Squash merge PR #274 after all quality and CodeQL checks passed.
wins.
In live and dry-run modes, each pair requires
-`freqai.fit_live_predictions_candles` model predictions after session startup
-before adaptive thresholds become available. Restarting requires a new warmup.
-Downtime and expired-model rows are excluded; genuine zero and outlier-rejected
-predictions count. Predictions align to candle dates; candles without
-predictions have `do_predict=0` and downtime zeros display but never calibrate.
+`freqai.fit_live_predictions_candles` real model predictions before adaptive
+thresholds become available. The Nth observation first affects the next
+prediction update, not the candle that produced it. FreqAI bootstrap
+predictions made from the initial training frame do not count. Warmup progress
+from persisted real predictions is restored after a restart. FreqAI saves
+prediction history after training attempts and on clean shutdown. After an
+abrupt stop or hard reboot, predictions since the last history save may be
+lost, so those observations must accumulate again. Legacy rows missing
+provenance, including rows in partly marked histories, count only when their
+nonzero, nonexpired prediction status distinguishes them from bootstrap;
+ambiguous rejected rows and explicit false markers do not count.
+
+A pair starts a new warmup when the time since its last observation, or a gap
+within its observations, is greater than
+`fit_live_predictions_candles × timeframe`. An observation exactly one horizon
+old remains eligible. Downtime and expired-model rows are excluded; genuine
+zero and outlier-rejected predictions count. Predictions align to candle dates;
+candles without predictions have `do_predict=0` and downtime zeros display but
+never calibrate.
### Backtest evaluation protocol
Continual learning trains an independent copy of the deployed policy with its
fitted feature pipeline. DQN/QRDQN deployments each persist their replay buffer;
-missing or incompatible replay data prevents continuation. Reset trained models
+it is loaded only when continual training starts. Missing or incompatible replay
+data prevents continuation but does not prevent inference. Reset trained models
or use a new `freqai.identifier` to migrate incompatible artifacts, including
deployments without the chronological training marker. Training disables
`shuffle_after_split`. HPO studies and saved best parameters are reused only
### Live inference
-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.
+Optional `fit_live_predictions_candles` statistics use the latest persisted real
+predictions per pair, excluding FreqAI bootstrap rows. Available observations
+are used before a full window accumulates and survive restarts. FreqAI returns
+the initial strategy frame before calculating live statistics; restored
+statistics appear on the next prediction update. Legacy rows missing provenance,
+including rows in partly marked histories, can count when their nonzero,
+nonexpired prediction status distinguishes them from bootstrap; zero-status rows
+remain excluded because bootstrap and rejected predictions cannot be
+distinguished. Explicit false markers remain excluded.
+On duplicate candle dates, a provable prediction takes precedence over an
+ambiguous close-bearing legacy row during history restoration.
+Rows with an invalid `date_pred` are discarded with a per-pair warning and the
+discarded-row count; valid duplicates retain the same precedence.
+See the model docstrings for continuation, HPO and statistics details.
With `hold_potential_enabled=true`, ReforceXY enables `add_state_info` before
constructing environments so training and inference use the same observations.
current evaluation run when available. DQN/QRDQN HPO rejects warmup budgets that
leave no gradient update and trials that finish without learning. A zero-sized
holdout remains supported when HPO is disabled, including with raw OHLC feature
-removal.
+removal. An interrupted ReforceXY fit is logged and still selects the best
+usable checkpoint when available, falling back to the final model otherwise.
### Reward and portfolio accounting
},
{
"endCharacter": 22,
- "endLine": 914,
+ "endLine": 1010,
"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": 914
+ "startLine": 1010
},
{
"endCharacter": 37,
- "endLine": 914,
+ "endLine": 1010,
"file": "ReforceXY/user_data/freqaimodels/ReforceXY.py",
"message": "Cannot assign to attribute \"eval_env\" for class \"ReforceXY*\"\n Expression of type \"VecEnv | None\" cannot be assigned to attribute \"eval_env\" of class \"ReforceXY\"\n Type \"VecEnv | None\" is not assignable to type \"VecMonitor | SubprocVecEnv | Env[Unknown, Unknown]\"\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": 914
+ "startLine": 1010
},
{
"endCharacter": 24,
- "endLine": 1173,
+ "endLine": 1269,
"file": "ReforceXY/user_data/freqaimodels/ReforceXY.py",
"message": "Argument of type \"VecEnv\" cannot be assigned to parameter \"eval_env\" of type \"BaseEnvironment\" in function \"__init__\"\n \"VecEnv\" is not assignable to \"BaseEnvironment\"",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 16,
- "startLine": 1173
+ "startLine": 1269
},
{
"endCharacter": 38,
- "endLine": 1378,
+ "endLine": 1477,
"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": 1378
+ "startLine": 1477
},
{
"endCharacter": 36,
- "endLine": 1382,
+ "endLine": 1481,
"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": 1382
+ "startLine": 1481
},
{
"endCharacter": 80,
- "endLine": 1385,
+ "endLine": 1484,
"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": 1385
+ "startLine": 1484
},
{
"endCharacter": 78,
- "endLine": 1386,
+ "endLine": 1485,
"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": 1386
+ "startLine": 1485
},
{
"endCharacter": 80,
- "endLine": 1387,
+ "endLine": 1486,
"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": 1387
+ "startLine": 1486
},
{
"endCharacter": 56,
- "endLine": 1472,
+ "endLine": 1571,
"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 \"VecEnv | None\" in function \"get_callbacks\"\n Type \"VecMonitor | SubprocVecEnv | Env[Unknown, Unknown]\" is not assignable to type \"VecEnv | None\"\n Type \"Env[Unknown, Unknown]\" is not assignable to type \"VecEnv | None\"\n \"Env[Unknown, Unknown]\" is not assignable to \"VecEnv\"\n \"Env[Unknown, Unknown]\" is not assignable to \"None\"",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 43,
- "startLine": 1472
+ "startLine": 1571
},
{
"endCharacter": 84,
- "endLine": 1492,
+ "endLine": 1591,
"file": "ReforceXY/user_data/freqaimodels/ReforceXY.py",
"message": "Argument of type \"float | list[float]\" cannot be assigned to parameter \"x\" of type \"ConvertibleToFloat\" in function \"__new__\"\n Type \"float | list[float]\" is not assignable to type \"ConvertibleToFloat\"\n Type \"list[float]\" is not assignable to type \"ConvertibleToFloat\"\n \"list[float]\" is not assignable to \"str\"\n \"list[float]\" is incompatible with protocol \"Buffer\"\n \"__buffer__\" is not present\n \"list[float]\" is incompatible with protocol \"SupportsFloat\"\n \"__float__\" is not present\n \"list[float]\" is incompatible with protocol \"SupportsIndex\"",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 67,
- "startLine": 1492
+ "startLine": 1591
},
{
"endCharacter": 84,
- "endLine": 1492,
+ "endLine": 1591,
"file": "ReforceXY/user_data/freqaimodels/ReforceXY.py",
"message": "Argument of type \"float | list[float]\" cannot be assigned to parameter \"x\" of type \"ConvertibleToFloat\" in function \"__new__\"\n Type \"float | list[float]\" is not assignable to type \"ConvertibleToFloat\"\n Type \"list[float]\" is not assignable to type \"ConvertibleToFloat\"\n \"list[float]\" is not assignable to \"str\"\n \"list[float]\" is incompatible with protocol \"Buffer\"\n \"__buffer__\" is not present\n \"list[float]\" is incompatible with protocol \"SupportsFloat\"\n \"__float__\" is not present\n \"list[float]\" is incompatible with protocol \"SupportsIndex\"\n ...",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 67,
- "startLine": 1492
+ "startLine": 1591
},
{
"endCharacter": 44,
- "endLine": 2586,
+ "endLine": 2665,
"file": "ReforceXY/user_data/freqaimodels/ReforceXY.py",
"message": "\"best_trial_params\" is possibly unbound",
"rule": "reportPossiblyUnboundVariable",
"severity": "error",
"startCharacter": 27,
- "startLine": 2586
+ "startLine": 2665
},
{
"endCharacter": 12,
- "endLine": 2606,
+ "endLine": 2685,
"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": 2606
+ "startLine": 2685
},
{
"endCharacter": 16,
- "endLine": 2607,
+ "endLine": 2686,
"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": 2607
+ "startLine": 2686
},
{
"endCharacter": 51,
- "endLine": 2650,
+ "endLine": 2729,
"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": 42,
- "startLine": 2650
+ "startLine": 2729
},
{
"endCharacter": 53,
- "endLine": 2656,
+ "endLine": 2735,
"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": 45,
- "startLine": 2656
+ "startLine": 2735
},
{
"endCharacter": 22,
- "endLine": 2719,
+ "endLine": 2798,
"file": "ReforceXY/user_data/freqaimodels/ReforceXY.py",
"message": "Operator \"*\" not supported for \"None\"",
"rule": "reportOptionalOperand",
"severity": "error",
"startCharacter": 15,
- "startLine": 2719
+ "startLine": 2798
},
{
"endCharacter": 96,
- "endLine": 2721,
+ "endLine": 2800,
"file": "ReforceXY/user_data/freqaimodels/ReforceXY.py",
"message": "Operator \"*\" not supported for \"None\"",
"rule": "reportOptionalOperand",
"severity": "error",
"startCharacter": 89,
- "startLine": 2721
+ "startLine": 2800
},
{
"endCharacter": 23,
- "endLine": 2724,
+ "endLine": 2803,
"file": "ReforceXY/user_data/freqaimodels/ReforceXY.py",
"message": "Operator \"*\" not supported for \"None\"",
"rule": "reportOptionalOperand",
"severity": "error",
"startCharacter": 16,
- "startLine": 2724
+ "startLine": 2803
},
{
"endCharacter": 98,
- "endLine": 2726,
+ "endLine": 2805,
"file": "ReforceXY/user_data/freqaimodels/ReforceXY.py",
"message": "Operator \"*\" not supported for \"None\"",
"rule": "reportOptionalOperand",
"severity": "error",
"startCharacter": 91,
- "startLine": 2726
+ "startLine": 2805
},
{
"endCharacter": 44,
- "endLine": 2738,
+ "endLine": 2817,
"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": 2738
+ "startLine": 2817
},
{
"endCharacter": 133,
- "endLine": 2740,
+ "endLine": 2819,
"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": 2740
+ "startLine": 2819
},
{
"endCharacter": 30,
- "endLine": 2743,
+ "endLine": 2822,
"file": "ReforceXY/user_data/freqaimodels/ReforceXY.py",
"message": "Operator \">\" not supported for \"None\"",
"rule": "reportOptionalOperand",
"severity": "error",
"startCharacter": 15,
- "startLine": 2743
+ "startLine": 2822
},
{
"endCharacter": 54,
- "endLine": 2808,
+ "endLine": 2887,
"file": "ReforceXY/user_data/freqaimodels/ReforceXY.py",
"message": "\"is_pruned\" is not a known attribute of \"None\"",
"rule": "reportOptionalMemberAccess",
"severity": "error",
"startCharacter": 45,
- "startLine": 2808
+ "startLine": 2887
},
{
"endCharacter": 67,
- "endLine": 2811,
+ "endLine": 2890,
"file": "ReforceXY/user_data/freqaimodels/ReforceXY.py",
"message": "\"use_masking\" is not a known attribute of \"None\"",
"rule": "reportOptionalMemberAccess",
"severity": "error",
"startCharacter": 56,
- "startLine": 2811
+ "startLine": 2890
},
{
"endCharacter": 60,
- "endLine": 2819,
+ "endLine": 2898,
"file": "ReforceXY/user_data/freqaimodels/ReforceXY.py",
"message": "\"update_best_reward\" is not a known attribute of \"None\"",
"rule": "reportOptionalMemberAccess",
"severity": "error",
"startCharacter": 42,
- "startLine": 2819
+ "startLine": 2898
},
{
"endCharacter": 84,
- "endLine": 2819,
+ "endLine": 2898,
"file": "ReforceXY/user_data/freqaimodels/ReforceXY.py",
"message": "Argument of type \"float | list[float]\" cannot be assigned to parameter \"x\" of type \"ConvertibleToFloat\" in function \"__new__\"\n Type \"float | list[float]\" is not assignable to type \"ConvertibleToFloat\"\n Type \"list[float]\" is not assignable to type \"ConvertibleToFloat\"\n \"list[float]\" is not assignable to \"str\"\n \"list[float]\" is incompatible with protocol \"Buffer\"\n \"__buffer__\" is not present\n \"list[float]\" is incompatible with protocol \"SupportsFloat\"\n \"__float__\" is not present\n \"list[float]\" is incompatible with protocol \"SupportsIndex\"",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 67,
- "startLine": 2819
+ "startLine": 2898
},
{
"endCharacter": 84,
- "endLine": 2819,
+ "endLine": 2898,
"file": "ReforceXY/user_data/freqaimodels/ReforceXY.py",
"message": "Argument of type \"float | list[float]\" cannot be assigned to parameter \"x\" of type \"ConvertibleToFloat\" in function \"__new__\"\n Type \"float | list[float]\" is not assignable to type \"ConvertibleToFloat\"\n Type \"list[float]\" is not assignable to type \"ConvertibleToFloat\"\n \"list[float]\" is not assignable to \"str\"\n \"list[float]\" is incompatible with protocol \"Buffer\"\n \"__buffer__\" is not present\n \"list[float]\" is incompatible with protocol \"SupportsFloat\"\n \"__float__\" is not present\n \"list[float]\" is incompatible with protocol \"SupportsIndex\"\n ...",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 67,
- "startLine": 2819
+ "startLine": 2898
},
{
"endCharacter": 46,
- "endLine": 2873,
+ "endLine": 2952,
"file": "ReforceXY/user_data/freqaimodels/ReforceXY.py",
"message": "\"is_pruned\" is not a known attribute of \"None\"",
"rule": "reportOptionalMemberAccess",
"severity": "error",
"startCharacter": 37,
- "startLine": 2873
+ "startLine": 2952
},
{
"endCharacter": 57,
- "endLine": 2876,
+ "endLine": 2955,
"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": 2876
+ "startLine": 2955
},
{
"endCharacter": 37,
- "endLine": 2886,
+ "endLine": 2965,
"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": 2886
+ "startLine": 2965
},
{
"endCharacter": 36,
- "endLine": 2891,
+ "endLine": 2970,
"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": 2891
+ "startLine": 2970
},
{
"endCharacter": 7,
- "endLine": 2936,
+ "endLine": 3015,
"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": 2936
+ "startLine": 3015
},
{
"endCharacter": 36,
- "endLine": 2948,
+ "endLine": 3027,
"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": 2948
+ "startLine": 3027
},
{
"endCharacter": 13,
- "endLine": 3540,
+ "endLine": 3619,
"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": 3540
+ "startLine": 3619
},
{
"endCharacter": 26,
- "endLine": 3561,
+ "endLine": 3640,
"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": 3561
+ "startLine": 3640
},
{
"endCharacter": 55,
- "endLine": 3869,
+ "endLine": 3948,
"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": 3869
+ "startLine": 3948
},
{
"endCharacter": 55,
- "endLine": 3869,
+ "endLine": 3948,
"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": 3869
+ "startLine": 3948
},
{
"endCharacter": 59,
- "endLine": 3893,
+ "endLine": 3972,
"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": 3893
+ "startLine": 3972
},
{
"endCharacter": 59,
- "endLine": 3893,
+ "endLine": 3972,
"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": 3893
+ "startLine": 3972
},
{
"endCharacter": 24,
- "endLine": 3922,
+ "endLine": 4001,
"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": 3922
+ "startLine": 4001
},
{
"endCharacter": 12,
- "endLine": 4024,
+ "endLine": 4103,
"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": 4024
+ "startLine": 4103
},
{
"endCharacter": 20,
- "endLine": 4207,
+ "endLine": 4290,
"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": 4207
+ "startLine": 4290
},
{
"endCharacter": 40,
- "endLine": 4356,
+ "endLine": 4439,
"file": "ReforceXY/user_data/freqaimodels/ReforceXY.py",
"message": "\"Figure\" is not exported from module \"matplotlib.pyplot\"",
"rule": "reportPrivateImportUsage",
"severity": "error",
"startCharacter": 34,
- "startLine": 4356
+ "startLine": 4439
},
{
"endCharacter": 54,
- "endLine": 4859,
+ "endLine": 4942,
"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": 4859
+ "startLine": 4942
},
{
"endCharacter": 54,
- "endLine": 4859,
+ "endLine": 4942,
"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": 4859
+ "startLine": 4942
},
{
"endCharacter": 50,
- "endLine": 4871,
+ "endLine": 4954,
"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": 4871
+ "startLine": 4954
},
{
"endCharacter": 72,
- "endLine": 4882,
+ "endLine": 4965,
"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": 4882
+ "startLine": 4965
},
{
"endCharacter": 72,
- "endLine": 4882,
+ "endLine": 4965,
"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": 4882
+ "startLine": 4965
},
{
"endCharacter": 73,
- "endLine": 4891,
+ "endLine": 4974,
"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": 4891
+ "startLine": 4974
},
{
"endCharacter": 73,
- "endLine": 4891,
+ "endLine": 4974,
"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": 4891
+ "startLine": 4974
},
{
"endCharacter": 58,
- "endLine": 4900,
+ "endLine": 4983,
"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": 4900
+ "startLine": 4983
},
{
"endCharacter": 58,
- "endLine": 4900,
+ "endLine": 4983,
"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": 4900
+ "startLine": 4983
},
{
"endCharacter": 50,
- "endLine": 5131,
+ "endLine": 5214,
"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": 5131
+ "startLine": 5214
},
{
"endCharacter": 20,
- "endLine": 5308,
+ "endLine": 5391,
"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": 5308
+ "startLine": 5391
},
{
"endCharacter": 20,
- "endLine": 5308,
+ "endLine": 5391,
"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": 5308
+ "startLine": 5391
},
{
"endCharacter": 59,
- "endLine": 5313,
+ "endLine": 5396,
"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": 5313
+ "startLine": 5396
},
{
"endCharacter": 59,
- "endLine": 5313,
+ "endLine": 5396,
"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": 5313
+ "startLine": 5396
},
{
"endCharacter": 65,
- "endLine": 5314,
+ "endLine": 5397,
"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": 5314
+ "startLine": 5397
},
{
"endCharacter": 65,
- "endLine": 5314,
+ "endLine": 5397,
"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": 5314
+ "startLine": 5397
},
{
"endCharacter": 57,
- "endLine": 5315,
+ "endLine": 5398,
"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": 5315
+ "startLine": 5398
},
{
"endCharacter": 57,
- "endLine": 5315,
+ "endLine": 5398,
"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": 5315
+ "startLine": 5398
},
{
"endCharacter": 63,
- "endLine": 5317,
+ "endLine": 5400,
"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": 5317
+ "startLine": 5400
},
{
"endCharacter": 63,
- "endLine": 5317,
+ "endLine": 5400,
"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": 5317
+ "startLine": 5400
},
{
"endCharacter": 61,
- "endLine": 5319,
+ "endLine": 5402,
"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": 5319
+ "startLine": 5402
},
{
"endCharacter": 61,
- "endLine": 5319,
+ "endLine": 5402,
"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": 5319
+ "startLine": 5402
},
{
"endCharacter": 67,
- "endLine": 5320,
+ "endLine": 5403,
"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": 5320
+ "startLine": 5403
},
{
"endCharacter": 67,
- "endLine": 5320,
+ "endLine": 5403,
"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": 5320
+ "startLine": 5403
},
{
"endCharacter": 73,
- "endLine": 5321,
+ "endLine": 5404,
"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": 5321
+ "startLine": 5404
},
{
"endCharacter": 73,
- "endLine": 5321,
+ "endLine": 5404,
"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": 5321
+ "startLine": 5404
},
{
"endCharacter": 61,
- "endLine": 5322,
+ "endLine": 5405,
"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": 5322
+ "startLine": 5405
},
{
"endCharacter": 61,
- "endLine": 5322,
+ "endLine": 5405,
"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": 5322
+ "startLine": 5405
},
{
"endCharacter": 89,
- "endLine": 5329,
+ "endLine": 5412,
"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": 5329
+ "startLine": 5412
},
{
"endCharacter": 89,
- "endLine": 5329,
+ "endLine": 5412,
"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": 5329
+ "startLine": 5412
},
{
"endCharacter": 83,
- "endLine": 5330,
+ "endLine": 5413,
"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": 5330
+ "startLine": 5413
},
{
"endCharacter": 83,
- "endLine": 5330,
+ "endLine": 5413,
"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": 5330
+ "startLine": 5413
},
{
"endCharacter": 57,
- "endLine": 5355,
+ "endLine": 5438,
"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": 5355
+ "startLine": 5438
},
{
"endCharacter": 57,
- "endLine": 5355,
+ "endLine": 5438,
"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": 5355
+ "startLine": 5438
},
{
"endCharacter": 65,
- "endLine": 5356,
+ "endLine": 5439,
"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": 5356
+ "startLine": 5439
},
{
"endCharacter": 65,
- "endLine": 5356,
+ "endLine": 5439,
"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": 5356
+ "startLine": 5439
},
{
"endCharacter": 67,
- "endLine": 5358,
+ "endLine": 5441,
"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": 5358
+ "startLine": 5441
},
{
"endCharacter": 67,
- "endLine": 5358,
+ "endLine": 5441,
"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": 5358
+ "startLine": 5441
},
{
"endCharacter": 87,
- "endLine": 5361,
+ "endLine": 5444,
"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": 5361
+ "startLine": 5444
},
{
"endCharacter": 87,
- "endLine": 5361,
+ "endLine": 5444,
"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": 5361
+ "startLine": 5444
},
{
"endCharacter": 93,
- "endLine": 5362,
+ "endLine": 5445,
"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": 5362
+ "startLine": 5445
},
{
"endCharacter": 93,
- "endLine": 5362,
+ "endLine": 5445,
"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": 5362
+ "startLine": 5445
},
{
"endCharacter": 89,
- "endLine": 5363,
+ "endLine": 5446,
"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": 5363
+ "startLine": 5446
},
{
"endCharacter": 89,
- "endLine": 5363,
+ "endLine": 5446,
"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": 5363
+ "startLine": 5446
},
{
"endCharacter": 89,
- "endLine": 5364,
+ "endLine": 5447,
"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": 5364
+ "startLine": 5447
},
{
"endCharacter": 89,
- "endLine": 5364,
+ "endLine": 5447,
"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": 5364
+ "startLine": 5447
},
{
"endCharacter": 75,
- "endLine": 5365,
+ "endLine": 5448,
"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": 5365
+ "startLine": 5448
},
{
"endCharacter": 75,
- "endLine": 5365,
+ "endLine": 5448,
"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": 5365
+ "startLine": 5448
},
{
"endCharacter": 33,
import numpy as np
import pandas as pd
+from freqtrade.exceptions import DependencyException
+from freqtrade.freqai.data_drawer import FreqaiDataDrawer
from freqtrade.freqai.data_kitchen import FreqaiDataKitchen
from optuna import TrialPruned, create_study
replay = trained.replay_buffer.observations.copy()
size = trained.replay_buffer.size()
self.assertGreater(size, 0)
- model.dd.model_dictionary.clear()
+ model.dd.model_dictionary[dk.pair] = trained
model.dd.meta_data_dictionary.clear()
+ direct_clone, _ = model._resolve_deployment_state(dk, dk.pair)
+ self.assertEqual(direct_clone.replay_buffer.size(), size)
+ np.testing.assert_array_equal(direct_clone.replay_buffer.observations, replay)
+ direct_clone.replay_buffer.observations.flat[0] += 42
+ np.testing.assert_array_equal(trained.replay_buffer.observations, replay)
+ model.dd.model_dictionary.clear()
restored = model.dd.load_data(dk.pair, dk)
- self.assertEqual(restored.replay_buffer.size(), size)
- np.testing.assert_array_equal(restored.replay_buffer.observations, replay)
+ self.assertEqual(restored.replay_buffer.size(), 0)
clone, _ = model._resolve_deployment_state(dk, dk.pair)
self.assertEqual(clone.replay_buffer.size(), size)
- self.assertIsNot(clone.replay_buffer, restored.replay_buffer)
- clone.replay_buffer.observations.flat[0] += 123.0
- self.assertNotEqual(
- clone.replay_buffer.observations.flat[0],
- restored.replay_buffer.observations.flat[0],
- )
- np.testing.assert_array_equal(restored.replay_buffer.observations, replay)
+ np.testing.assert_array_equal(clone.replay_buffer.observations, replay)
+ clone.replay_buffer.observations.flat[0] += 42
+ np.testing.assert_array_equal(trained.replay_buffer.observations, replay)
+ self.assertEqual(restored.replay_buffer.size(), 0)
self.assertIs(model.dd.load_data(dk.pair, dk), restored)
model.dd.model_dictionary.clear()
(dk.data_path / dk.data["reforcexy_replay"]).unlink()
- for _ in range(2):
- with self.assertRaises(FileNotFoundError):
- model.dd.load_data(dk.pair, dk)
- self.assertNotIn(dk.pair, model.dd.model_dictionary)
+ inference_model = model.dd.load_data(dk.pair, dk)
+ self.assertIsNotNone(inference_model)
+ model.continual_learning = False
+ self.assertIsNone(model._resolve_deployment_state(dk, dk.pair))
+ model.continual_learning = True
+ with self.assertRaises(DependencyException):
+ model._resolve_deployment_state(dk, dk.pair)
params = model.get_model_params()
trial = create_study(direction="maximize").ask()
for starts in (64, 50000):
)
self.assertTrue(np.isfinite(score))
+ def test_provenance_does_not_change_other_drawers(self):
+ with tempfile.TemporaryDirectory() as temp:
+ config = model_config(temp)
+ model = ReforceXY(config=config)
+ self.addCleanup(model.close_envs)
+ drawer = FreqaiDataDrawer(Path(temp), config)
+ pair = "BTC/USDT"
+ date = pd.Timestamp("2026-01-01", tz="UTC")
+ drawer.historic_predictions[pair] = pd.DataFrame(
+ {
+ "date_pred": [date],
+ "&-action": [1.0],
+ "do_predict": [1],
+ "close_price": [100.0],
+ }
+ )
+ candles = pd.DataFrame({"date": [date]})
+ drawer.set_initial_return_values(pair, pd.DataFrame({"&-action": [99.0]}), candles)
+ self.assertNotIn("_freqai_strategies_produced", drawer.historic_predictions[pair])
+ self.assertNotIn(
+ "_freqai_strategies_produced",
+ drawer.attach_return_values_to_return_dataframe(pair, candles),
+ )
+
+ def test_native_bootstrap_append_and_restart_provenance(self):
+ pair = "BTC/USDT"
+ marker = "_freqai_strategies_produced"
+ with tempfile.TemporaryDirectory() as temp:
+ config = model_config(temp)
+ config["freqai"]["fit_live_predictions_candles"] = 3
+ model = ReforceXY(config=config)
+ model.live = True
+ self.addCleanup(model.close_envs)
+ dates = pd.date_range("2026-01-01", periods=4, freq="5min", tz="UTC")
+ strat_df = pd.DataFrame(
+ {"date": dates, "high": [101.0] * 4, "low": [99.0] * 4, "close": [100.0] * 4}
+ )
+ dk = SimpleNamespace(
+ data={"extra_returns_per_train": {}}, label_list=["&-action"], unique_class_list=[]
+ )
+ bootstrap = pd.DataFrame({"&-action": [21.0, 22.0, 23.0, 24.0]})
+ model.set_initial_historic_predictions(bootstrap, dk, pair, strat_df)
+ model.dd.set_initial_return_values(pair, bootstrap, strat_df)
+ self.assertEqual(model.dd.historic_predictions[pair][marker].tolist(), [False] * 4)
+ model.fit_live_predictions(dk, pair)
+ self.assertEqual(dk.data["labels_mean"]["&-action"], 0.0)
+ returned = model.dd.attach_return_values_to_return_dataframe(pair, strat_df)
+ self.assertNotIn(marker, returned)
+
+ # Native same-candle append overwrites a bootstrap candle. A rejected
+ # prediction is nevertheless produced and must enter the statistics.
+ model.dd.append_model_predictions(
+ pair, pd.DataFrame({"&-action": [3.0]}), np.array([0]), dk, strat_df
+ )
+ model.fit_live_predictions(dk, pair)
+ self.assertEqual(dk.data["labels_mean"]["&-action"], 3.0)
+ self.assertNotIn(
+ marker, model.dd.attach_return_values_to_return_dataframe(pair, strat_df)
+ )
+
+ future = pd.date_range(dates[-1] + pd.Timedelta(minutes=5), periods=3, freq="5min")
+ resumed = pd.concat(
+ [
+ strat_df,
+ pd.DataFrame(
+ {
+ "date": future,
+ "high": [101.0] * 3,
+ "low": [99.0] * 3,
+ "close": [100.0] * 3,
+ }
+ ),
+ ],
+ ignore_index=True,
+ )
+ model.dd.append_model_predictions(
+ pair, pd.DataFrame({"&-action": [9.0]}), np.array([1]), dk, resumed
+ )
+ history = model.dd.historic_predictions[pair]
+ self.assertEqual(history[marker].tolist(), [False] * 3 + [True, False, False, True])
+ model.fit_live_predictions(dk, pair)
+ self.assertEqual(dk.data["labels_mean"]["&-action"], 6.0)
+ self.assertNotIn(
+ marker, model.dd.attach_return_values_to_return_dataframe(pair, resumed)
+ )
+ model.dd.append_model_predictions(
+ pair, pd.DataFrame({"&-action": [99.0]}), np.array([2]), dk, resumed
+ )
+ model.fit_live_predictions(dk, pair)
+ self.assertEqual(dk.data["labels_mean"]["&-action"], 3.0)
+ model.dd.append_model_predictions(
+ pair, pd.DataFrame({"&-action": [9.0]}), np.array([1]), dk, resumed
+ )
+ self.assertEqual(len(model.dd.historic_predictions[pair]), len(resumed))
+ model.fit_live_predictions(dk, pair)
+ self.assertEqual(dk.data["labels_mean"]["&-action"], 6.0)
+
+ model.dd.save_historic_predictions_to_disk()
+ restored = ReforceXY(config=config)
+ restored.live = True
+ self.addCleanup(restored.close_envs)
+ self.assertTrue(restored.dd.load_historic_predictions_from_disk())
+ self.assertEqual(
+ restored.dd.historic_predictions[pair][marker].tolist(), history[marker].tolist()
+ )
+ restored.fit_live_predictions(dk, pair)
+ self.assertEqual(dk.data["labels_mean"]["&-action"], 6.0)
+ self.assertNotIn(
+ marker, restored.dd.attach_return_values_to_return_dataframe(pair, resumed)
+ )
+
+ def test_partially_marked_history_restores_provable_observations(self):
+ pair = "BTC/USDT"
+ marker = "_freqai_strategies_produced"
+ with tempfile.TemporaryDirectory() as temp:
+ config = model_config(temp)
+ config["freqai"]["fit_live_predictions_candles"] = 4
+ source = ReforceXY(config=config)
+ self.addCleanup(source.close_envs)
+ dates = pd.date_range("2026-01-01", periods=4, freq="5min", tz="UTC")
+ source.dd.historic_predictions[pair] = pd.DataFrame(
+ {
+ "date_pred": dates,
+ "&-action": [7.0, 9.0, 99.0, 1000.0],
+ "&-action_mean": [0.0] * 4,
+ "&-action_std": [0.0] * 4,
+ "close_price": [100.0] * 4,
+ "high_price": [101.0] * 4,
+ "low_price": [99.0] * 4,
+ "do_predict": [1, 0, 2, 1],
+ marker: [np.nan, 1.0, np.nan, 0.0],
+ }
+ )
+ source.dd.save_historic_predictions_to_disk()
+
+ restarted = ReforceXY(config=config)
+ restarted.live = True
+ self.addCleanup(restarted.close_envs)
+ dk = SimpleNamespace(
+ data={"extra_returns_per_train": {}},
+ label_list=["&-action"],
+ unique_class_list=[],
+ return_dataframe=pd.DataFrame(),
+ )
+ restarted.predict = lambda frame, kitchen, **kwargs: (
+ pd.DataFrame({"&-action": np.ones(len(frame))}),
+ np.ones(len(frame), dtype=int),
+ )
+ restarted.fit_live_predictions(dk, pair)
+ self.assertEqual(dk.data["labels_mean"]["&-action"], 8.0)
+
+ candles = pd.DataFrame(
+ {"date": dates, "high": [101.0] * 4, "low": [99.0] * 4, "close": [100.0] * 4}
+ )
+ restarted.build_strategy_return_arrays(candles, dk, pair, 0)
+ self.assertEqual(
+ restarted.dd.historic_predictions[pair][marker].tolist(), [True, True, False, False]
+ )
+
+ next_candle = pd.DataFrame(
+ {
+ "date": [dates[-1] + pd.Timedelta(minutes=5)],
+ "high": [101.0],
+ "low": [99.0],
+ "close": [100.0],
+ }
+ )
+ restarted.dk = SimpleNamespace(check_if_model_expired=lambda timestamp: False)
+ restarted.build_strategy_return_arrays(
+ pd.concat([candles, next_candle], ignore_index=True), dk, pair, 0
+ )
+ self.assertEqual(dk.return_dataframe["&-action_mean"].iloc[-1], 8.0)
+ self.assertEqual(dk.return_dataframe["&-action_std"].iloc[-1], 1.0)
+ self.assertNotIn(marker, dk.return_dataframe)
+
+ def test_duplicate_date_keeps_provable_observation_after_restart(self):
+ pair = "BTC/USDT"
+ marker = "_freqai_strategies_produced"
+ date = pd.Timestamp("2026-01-01", tz="UTC")
+ for statuses, markers in (([1, 0], None), ([0, 0], [True, False])):
+ with self.subTest(markers=markers), tempfile.TemporaryDirectory() as temp:
+ config = model_config(temp)
+ config["freqai"]["fit_live_predictions_candles"] = 3
+ source = ReforceXY(config=config)
+ self.addCleanup(source.close_envs)
+ history = pd.DataFrame(
+ {
+ "date_pred": [date, date],
+ "&-action": [7.0, 99.0],
+ "close_price": [100.0, 100.0],
+ "do_predict": statuses,
+ }
+ )
+ if markers is not None:
+ history[marker] = markers
+ source.dd.historic_predictions[pair] = history
+ source.dd.save_historic_predictions_to_disk()
+
+ restarted = ReforceXY(config=config)
+ restarted.live = True
+ self.addCleanup(restarted.close_envs)
+ restored = restarted.dd.historic_predictions[pair]
+ self.assertEqual(restored["&-action"].tolist(), [7.0])
+ self.assertEqual(restored[marker].tolist(), [True])
+ dk = SimpleNamespace(data={}, label_list=["&-action"], unique_class_list=[])
+ restarted.fit_live_predictions(dk, pair)
+ self.assertEqual(dk.data["labels_mean"]["&-action"], 7.0)
+
+ def test_legacy_zero_status_is_ambiguous_but_expired_status_is_excluded(self):
+ pair = "BTC/USDT"
+ history = pd.DataFrame(
+ {
+ "date_pred": pd.date_range("2026-01-01", periods=4, freq="5min", tz="UTC"),
+ "&-action": [99.0, 7.0, 88.0, 77.0],
+ "close_price": [100.0] * 4,
+ "do_predict": [0, 1, 2, np.nan],
+ }
+ )
+ model = ReforceXY.__new__(ReforceXY)
+ model.live = True
+ model.freqai_info = {"fit_live_predictions_candles": 4}
+ model.dd = SimpleNamespace(historic_predictions={pair: history})
+ dk = SimpleNamespace(data={}, label_list=["&-action"], unique_class_list=[])
+ model.fit_live_predictions(dk, pair)
+ self.assertEqual(dk.data["labels_mean"]["&-action"], 7.0)
+
+ def test_live_action_statistics_resume_persisted_observations(self):
+ pair = "BTC/USDT"
+ dates = pd.date_range("2026-01-01", periods=4, freq="5min", tz="UTC")
+ history = pd.DataFrame(
+ {
+ "date_pred": dates,
+ "&-action": [1.0, 2.0, 3.0, 99.0],
+ "do_predict": [1, 1, 1, 2],
+ "close_price": [100.0, 101.0, 102.0, 103.0],
+ }
+ )
+ model = ReforceXY.__new__(ReforceXY)
+ model.live = True
+ model.freqai_info = {"fit_live_predictions_candles": 4}
+ model.dd = SimpleNamespace(
+ historic_predictions={pair: history},
+ model_return_values={pair: history.tail(1)},
+ )
+ dk = SimpleNamespace(data={}, label_list=["&-action"], unique_class_list=[])
+
+ model.fit_live_predictions(dk, pair)
+
+ self.assertEqual(dk.data["labels_mean"]["&-action"], 2.0)
+ self.assertAlmostEqual(dk.data["labels_std"]["&-action"], np.std([1.0, 2.0, 3.0]))
+
def test_frame_validity_and_gap_reset(self):
with tempfile.TemporaryDirectory() as temp:
model = ReforceXY(config=model_config(temp))
import os
import stat
import time
-import warnings
from collections import defaultdict, deque
from collections.abc import Callable, Iterator, Mapping
from contextlib import contextmanager, suppress
from matplotlib.lines import Line2D
from numpy.typing import NDArray
from optuna import Trial, TrialPruned, create_study, delete_study
-from optuna.exceptions import ExperimentalWarning
from optuna.pruners import BasePruner, HyperbandPruner
from optuna.samplers import BaseSampler, TPESampler
from optuna.storages import (
_DATE_PRED_DEDUP_SENTINEL = "_freqai_strategies_date_pred_repair_patched"
+_PRODUCED_COLUMN = "_freqai_strategies_produced"
-def _recorded_prediction_mask(frame: pd.DataFrame) -> NDArray[np.bool_]:
- """Identify recorded rows from metadata, never from prediction magnitudes."""
+def _legacy_produced_prediction_mask(frame: pd.DataFrame) -> NDArray[np.bool_]:
+ """Bootstrap has status 0; only nonzero, nonexpired statuses prove legacy production."""
+ if "do_predict" not in frame:
+ return np.zeros(len(frame), dtype=bool)
+ status = pd.to_numeric(frame["do_predict"], errors="coerce")
+ return (status.notna() & np.isfinite(status) & status.ne(0) & status.ne(2)).to_numpy(dtype=bool)
+
+
+def _recorded_prediction_rank(frame: pd.DataFrame) -> NDArray[np.int8]:
+ """Prefer provable predictions to ambiguous legacy rows and placeholders."""
recorded = np.zeros(len(frame), dtype=bool)
+ status = None
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)
.fillna(False)
.to_numpy(dtype=bool)
)
- return recorded
+ recorded &= status.ne(2).fillna(True).to_numpy(dtype=bool)
+ rank = recorded.astype(np.int8)
+ rank[_legacy_produced_prediction_mask(frame)] = 2
+ if _PRODUCED_COLUMN in frame:
+ marker = frame[_PRODUCED_COLUMN]
+ proven = marker.eq(True).fillna(False).to_numpy(dtype=bool)
+ if status is not None:
+ proven = proven & status.ne(2).fillna(True).to_numpy(dtype=bool)
+ rank[marker.notna().to_numpy(dtype=bool)] = 0
+ rank[proven] = 2
+ return rank
def _produced_prediction_mask(frame: pd.DataFrame) -> NDArray[np.bool_]:
- """Exclude expired-model placeholders from recorded model observations."""
- produced = _recorded_prediction_mask(frame)
+ """Select real model outputs, excluding bootstrap and expired-model placeholders."""
+ produced = _legacy_produced_prediction_mask(frame)
+ if _PRODUCED_COLUMN in frame:
+ marker = frame[_PRODUCED_COLUMN]
+ produced = np.where(
+ marker.notna(), marker.eq(True).fillna(False).to_numpy(dtype=bool), produced
+ )
if "do_predict" in frame:
status = pd.to_numeric(frame["do_predict"], errors="coerce")
- produced &= status.ne(2).fillna(True).to_numpy(dtype=bool)
+ produced = 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.
+def _ensure_prediction_provenance(frame: pd.DataFrame) -> pd.DataFrame:
+ """Preserve explicit markers and infer only distinguishable legacy predictions."""
+ if _PRODUCED_COLUMN not in frame:
+ result = frame.copy()
+ result[_PRODUCED_COLUMN] = _legacy_produced_prediction_mask(frame)
+ return result
+ missing = frame[_PRODUCED_COLUMN].isna()
+ if not missing.any():
+ return frame
+ result = frame.copy()
+ result[_PRODUCED_COLUMN] = frame[_PRODUCED_COLUMN].where(
+ ~missing, _legacy_produced_prediction_mask(frame)
+ )
+ return result
+
- Freqtrade fills downtime rows with zeros/NaNs, without a candle close or a
- prediction status. Those rows must not replace recorded predictions, including
- zero predictions and rejected predictions (do_predict == 0 with a candle close).
- Indistinguishable rows use last-write-wins; label magnitudes never rank rows.
- Invalid dates cannot match a candle and are discarded.
+def _dedupe_historic_predictions_on_date_pred(frame: pd.DataFrame, pair: str) -> pd.DataFrame:
+ """Retain the most provable prediction per candle, in date order.
+
+ Proven outputs (legacy nonzero statuses or explicit markers) outrank
+ ambiguous close-bearing rows, which outrank downtime and expired placeholders.
+ Equally ranked rows use last-write-wins; invalid dates are discarded.
"""
date_pred = pd.to_datetime(frame["date_pred"], utc=True, errors="coerce", format="mixed")
valid = date_pred.notna()
- if valid.all() and date_pred.is_monotonic_increasing and date_pred.is_unique:
+ if not valid.all():
+ logger.warning(
+ "FreqAI prediction history [%s]: discarded invalid date_pred entries (count=%d)",
+ pair,
+ len(frame) - int(valid.sum()),
+ )
+ elif date_pred.is_monotonic_increasing and date_pred.is_unique:
if date_pred.dtype == frame["date_pred"].dtype:
return frame
result = frame.copy()
result["date_pred"] = date_pred
return result
- recorded = _recorded_prediction_mask(frame)
+ rank = _recorded_prediction_rank(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))}
+ {"date_pred": date_pred.array, "rank": rank, "position": np.arange(len(frame))}
)
kept = (
order.loc[valid.to_numpy()]
- .sort_values(["date_pred", "recorded", "position"])
+ .sort_values(["date_pred", "rank", "position"])
.drop_duplicates("date_pred", keep="last")
)
result = frame.iloc[kept.index].copy()
def _install_date_pred_dedup_patch() -> None:
- """Normalize persisted history and duplicate predictions before upstream writes.
+ """Repair persisted prediction dates before Freqtrade's positional writes.
- Normalize before upstream positional writes and before disk repair can discard
- a recorded duplicate. Already-clean upstream results are preserved. Recheck
- these synchronous method contracts on Freqtrade upgrades.
+ Normalize before upstream disk repair discards a provable duplicate, and
+ align the returned candles after writes. Both model copies of this global
+ patch must have identical behavior regardless of import order.
"""
names = (
"set_initial_return_values",
)
pending.append(not getattr(current, _DATE_PRED_DEDUP_SENTINEL, False))
if iscoroutinefunction(original) or iscoroutinefunction(current):
- raise RuntimeError("Repair [global]: requires synchronous drawer methods")
+ raise RuntimeError("FreqAI prediction repair requires synchronous drawer methods")
if not any(pending):
return
original_set_initial, original_append, original_attach = originals[:3]
self, pair: str, pred_df: pd.DataFrame, dataframe: pd.DataFrame
) -> None:
self.historic_predictions[pair] = _dedupe_historic_predictions_on_date_pred(
- self.historic_predictions[pair]
+ self.historic_predictions[pair], pair
)
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])
+ repaired = _dedupe_historic_predictions_on_date_pred(self.historic_predictions[pair], pair)
self.historic_predictions[pair] = repaired
self.model_return_values[pair] = _align_historic_predictions(repaired, dataframe)
strat_df: pd.DataFrame,
) -> None:
self.historic_predictions[pair] = _dedupe_historic_predictions_on_date_pred(
- self.historic_predictions[pair]
+ self.historic_predictions[pair], pair
)
if self.historic_predictions[pair].empty and not strat_df.empty:
# Append requires an initialized row; let upstream construct it.
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])
+ repaired = _dedupe_historic_predictions_on_date_pred(self.historic_predictions[pair], pair)
self.historic_predictions[pair] = repaired
self.model_return_values[pair] = _align_historic_predictions(repaired, strat_df)
def attach_return_values_to_return_dataframe(
self, pair: str, dataframe: pd.DataFrame
) -> pd.DataFrame:
- repaired = _dedupe_historic_predictions_on_date_pred(self.historic_predictions[pair])
+ repaired = _dedupe_historic_predictions_on_date_pred(self.historic_predictions[pair], pair)
self.historic_predictions[pair] = repaired
self.model_return_values[pair] = _align_historic_predictions(repaired, dataframe)
return original_attach(self, pair, dataframe)
@wraps(original_repair)
def repair_historic_predictions(self, pair: str, pair_df: pd.DataFrame) -> pd.DataFrame:
if "date_pred" in pair_df:
- pair_df = _dedupe_historic_predictions_on_date_pred(pair_df)
+ pair_df = _dedupe_historic_predictions_on_date_pred(pair_df, pair)
return original_repair(self, pair, pair_df)
replacements += (repair_historic_predictions,)
matplotlib.use("Agg")
-warnings.filterwarnings("ignore", category=UserWarning)
-warnings.filterwarnings("ignore", category=FutureWarning)
-warnings.filterwarnings("ignore", category=ExperimentalWarning)
logger = logging.getLogger(__name__)
"freqai": {
...
"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.
+ // Live/dry-run: latest N persisted produced observations per pair.
+ // Initial full-frame predictions are bootstrap samples, not observations.
+ // Available observations are used after the next actual prediction append
+ // and survive restarts. Downtime and expired status 2 do not count;
+ // neutral/exit actions and recorded rejected predictions do. Legacy history
+ // without provenance cannot distinguish bootstrap from rejected status 0:
+ // those ambiguous rows are excluded. Backtests use the previous N rows.
// 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.
raise ValueError(
f"Config [global]: fit_live_predictions_candles="
f"{fit_live_predictions_candles!r} invalid; "
- "must be a non-negative integer (0 disables label statistics)"
+ "must be a non-negative integer (0 disables action statistics)"
)
self.freqai_info["fit_live_predictions_candles"] = fit_live_predictions_candles
self.unset_unsupported()
self._configure_gpu_memory()
self._install_replay_persistence()
+ self._install_prediction_provenance()
+
+ def _install_prediction_provenance(self) -> None:
+ """Keep live observation metadata local to this model's drawer instance."""
+ drawer = self.dd
+ set_initial = drawer.set_initial_return_values
+ append = drawer.append_model_predictions
+ attach = drawer.attach_return_values_to_return_dataframe
+ load = drawer.load_historic_predictions_from_disk
+
+ def migrate() -> None:
+ for pair, history in drawer.historic_predictions.items():
+ if "date_pred" in history:
+ drawer.historic_predictions[pair] = _ensure_prediction_provenance(history)
+
+ @wraps(load)
+ def load_with_provenance() -> bool:
+ loaded = load()
+ migrate()
+ return loaded
+
+ @wraps(set_initial)
+ def set_initial_with_provenance(
+ pair: str, pred_df: pd.DataFrame, dataframe: pd.DataFrame
+ ) -> None:
+ drawer.historic_predictions[pair] = _ensure_prediction_provenance(
+ drawer.historic_predictions[pair]
+ )
+ set_initial(pair, pred_df, dataframe)
+ drawer.historic_predictions[pair] = _ensure_prediction_provenance(
+ drawer.historic_predictions[pair]
+ )
+ drawer.model_return_values[pair] = _align_historic_predictions(
+ drawer.historic_predictions[pair], dataframe
+ )
+
+ @wraps(append)
+ def append_with_provenance(
+ pair: str,
+ predictions: pd.DataFrame,
+ do_preds: NDArray[np.int_],
+ dk: FreqaiDataKitchen,
+ strat_df: pd.DataFrame,
+ ) -> None:
+ drawer.historic_predictions[pair] = _ensure_prediction_provenance(
+ drawer.historic_predictions[pair]
+ )
+ append(pair, predictions, do_preds, dk, strat_df)
+ history = drawer.historic_predictions[pair]
+ # The native writer may return without writing an older candle.
+ if (
+ not history.empty
+ and not strat_df.empty
+ and pd.to_datetime(history["date_pred"].iloc[-1], utc=True)
+ == pd.to_datetime(strat_df["date"].iloc[-1], utc=True)
+ ):
+ history.loc[history.index[-1], _PRODUCED_COLUMN] = True
+ drawer.model_return_values[pair] = _align_historic_predictions(history, strat_df)
+
+ @wraps(attach)
+ def attach_without_provenance(pair: str, dataframe: pd.DataFrame) -> pd.DataFrame:
+ return attach(pair, dataframe).drop(columns=_PRODUCED_COLUMN, errors="ignore")
+
+ migrate()
+ drawer.load_historic_predictions_from_disk = load_with_provenance
+ drawer.set_initial_return_values = set_initial_with_provenance
+ drawer.append_model_predictions = append_with_provenance
+ drawer.attach_return_values_to_return_dataframe = attach_without_provenance
def _install_replay_persistence(self) -> None:
save_data = self.dd.save_data
- load_data = self.dd.load_data
@wraps(save_data)
def save_with_replay(model, coin, dk):
dk.data["reforcexy_replay"] = filename
return save_data(model, coin, dk)
- @wraps(load_data)
- def load_with_replay(coin, dk):
- cached = self.dd.model_dictionary.get(coin) if dk.live else None
- model = load_data(coin, dk)
- if model is not None and model is not cached:
- try:
- self._restore_replay(model, dk.data, dk.data_path, coin)
- except Exception:
- if self.dd.model_dictionary.get(coin) is model:
- self.dd.model_dictionary.pop(coin, None)
- raise
- return model
-
self.dd.save_data = save_with_replay
- self.dd.load_data = load_with_replay
@staticmethod
def _restore_replay(model: Any, metadata: dict[str, Any], directory: Path, pair: str) -> None:
archive.seek(0)
model = self.MODELCLASS.load(archive, device=cached_model.device)
# Off-policy experience is excluded from SB3 model archives.
- if getattr(cached_model, "replay_buffer", None) is not None:
- model.replay_buffer = copy.deepcopy(cached_model.replay_buffer)
+ replay_buffer = getattr(cached_model, "replay_buffer", None)
+ if replay_buffer is not None and replay_buffer.size() > 0:
+ model.replay_buffer = copy.deepcopy(replay_buffer)
+ elif hasattr(model, "load_replay_buffer"):
+ self._restore_replay(model, metadata, Path(previous["data_path"]), pair)
state = model, copy.deepcopy(feature_pipeline)
except Exception as exc:
raise DependencyException(
)
if model is not None:
dk.data[self._DEPLOYMENT_COORDINATE_MARKER_KEY] = self._DEPLOYMENT_COORDINATE_GENERATION
- logger.info("Training [%s]: completed", pair)
+ logger.info("Training [%s]: model selection finished", pair)
return model
def fit(
)
_update_eval_best_reward(self.eval_callback, float(final_mean_reward), model)
except KeyboardInterrupt:
- pass
+ logger.warning("Training [%s]: model fitting interrupted by user", dk.pair)
finally:
if self.progressbar_callback:
self.progressbar_callback.on_training_end()
return model
+ def set_initial_historic_predictions(
+ self, pred_df: pd.DataFrame, dk: FreqaiDataKitchen, pair: str, strat_df: pd.DataFrame
+ ) -> None:
+ """Keep Freqtrade's full-frame bootstrap out of live prediction statistics."""
+ super().set_initial_historic_predictions(pred_df, dk, pair, strat_df)
+ self.dd.historic_predictions[pair][_PRODUCED_COLUMN] = False
+
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(
- "Predict [%s]: fit live predictions not warmed up; "
- "%d more produced observations required for warmup completion",
- pair,
- remaining,
- )
+ history = _dedupe_historic_predictions_on_date_pred(history, pair)
+ history = history.loc[_produced_prediction_mask(history)]
pred_df = history.tail(fit_live_predictions_candles).reset_index(drop=True)
dk.data["labels_mean"], dk.data["labels_std"] = {}, {}
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]
+ 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:
- 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,
- )
+ 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],
if self._position == Positions.Neutral:
exit_pnl = pre_pnl
elif action != Actions.Neutral.value:
+ try:
+ action_name = Actions(action).name
+ except ValueError:
+ action_name = "unknown"
logger.warning(
"Env [%s]: invalid action=%s (%d) in position=%s at tick=%d",
self.id,
- Actions(action).name,
+ action_name,
action,
self._position.name,
self._current_tick,
"diagnostics": [
{
"endCharacter": 46,
- "endLine": 1357,
+ "endLine": 1400,
"file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
"message": "Argument of type \"str | None\" cannot be assigned to parameter \"default\" of type \"str\" in function \"_validate_label_selection_metric\"\n Type \"str | None\" is not assignable to type \"str\"\n \"None\" is not assignable to \"str\"",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 24,
- "startLine": 1357
+ "startLine": 1400
},
{
"endCharacter": 79,
- "endLine": 2139,
+ "endLine": 2183,
"file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
"message": "Cannot access attribute \"index\" for class \"NDArray[Unknown]\"\n Attribute \"index\" is unknown",
"rule": "reportAttributeAccessIssue",
"severity": "error",
"startCharacter": 74,
- "startLine": 2139
+ "startLine": 2183
},
{
"endCharacter": 72,
- "endLine": 2141,
+ "endLine": 2185,
"file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
"message": "Cannot access attribute \"index\" for class \"NDArray[Unknown]\"\n Attribute \"index\" is unknown",
"rule": "reportAttributeAccessIssue",
"severity": "error",
"startCharacter": 67,
- "startLine": 2141
+ "startLine": 2185
},
{
"endCharacter": 90,
- "endLine": 2150,
+ "endLine": 2194,
"file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
"message": "Cannot access attribute \"index\" for class \"NDArray[Unknown]\"\n Attribute \"index\" is unknown",
"rule": "reportAttributeAccessIssue",
"severity": "error",
"startCharacter": 85,
- "startLine": 2150
+ "startLine": 2194
},
{
"endCharacter": 34,
- "endLine": 2163,
+ "endLine": 2207,
"file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
"message": "Argument of type \"Unknown | NDArray[Unknown] | Any | list[Unknown]\" cannot be assigned to parameter \"train_features\" of type \"DataFrame\" in function \"_filter_train_by_mask\"\n Type \"Unknown | NDArray[Unknown] | Any | list[Unknown]\" is not assignable to type \"DataFrame\"\n \"list[Unknown]\" is not assignable to \"DataFrame\"",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 20,
- "startLine": 2163
+ "startLine": 2207
},
{
"endCharacter": 32,
- "endLine": 2164,
+ "endLine": 2208,
"file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
"message": "Argument of type \"Unknown | NDArray[Unknown] | Any | list[Unknown]\" cannot be assigned to parameter \"train_labels\" of type \"DataFrame\" in function \"_filter_train_by_mask\"\n Type \"Unknown | NDArray[Unknown] | Any | list[Unknown]\" is not assignable to type \"DataFrame\"\n \"list[Unknown]\" is not assignable to \"DataFrame\"",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 20,
- "startLine": 2164
+ "startLine": 2208
},
{
"endCharacter": 38,
- "endLine": 2165,
+ "endLine": 2209,
"file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
"message": "Argument of type \"Unknown | NDArray[Unknown] | Any | list[Unknown]\" cannot be assigned to parameter \"train_weights\" of type \"NDArray[floating[Any]]\" in function \"_filter_train_by_mask\"\n Type \"Unknown | NDArray[Unknown] | Any | list[Unknown]\" is not assignable to type \"NDArray[floating[Any]]\"\n \"list[Unknown]\" is not assignable to \"ndarray[_AnyShape, dtype[floating[Any]]]\"",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 20,
- "startLine": 2165
+ "startLine": 2209
},
{
"endCharacter": 59,
- "endLine": 2168,
+ "endLine": 2212,
"file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
"message": "Argument of type \"Unknown | NDArray[Unknown] | Any | list[Unknown] | None\" cannot be assigned to parameter \"train_label_weights\" of type \"NDArray[floating[Any]] | None\" in function \"_filter_train_by_mask\"\n Type \"Unknown | NDArray[Unknown] | Any | list[Unknown] | None\" is not assignable to type \"NDArray[floating[Any]] | None\"\n Type \"list[Unknown]\" is not assignable to type \"NDArray[floating[Any]] | None\"\n \"list[Unknown]\" is not assignable to \"ndarray[_AnyShape, dtype[floating[Any]]]\"\n \"list[Unknown]\" is not assignable to \"None\"",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 40,
- "startLine": 2168
+ "startLine": 2212
},
{
"endCharacter": 34,
- "endLine": 2202,
+ "endLine": 2246,
"file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
"message": "Argument of type \"DataFrame | Unknown | NDArray[Unknown] | Any | list[Unknown]\" cannot be assigned to parameter \"features\" of type \"DataFrame\" in function \"_shuffle_split_rows\"\n Type \"DataFrame | Unknown | NDArray[Unknown] | Any | list[Unknown]\" is not assignable to type \"DataFrame\"\n \"list[Unknown]\" is not assignable to \"DataFrame\"",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 20,
- "startLine": 2202
+ "startLine": 2246
},
{
"endCharacter": 32,
- "endLine": 2203,
+ "endLine": 2247,
"file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
"message": "Argument of type \"DataFrame | Unknown | NDArray[Unknown] | Any | list[Unknown]\" cannot be assigned to parameter \"labels\" of type \"DataFrame\" in function \"_shuffle_split_rows\"\n Type \"DataFrame | Unknown | NDArray[Unknown] | Any | list[Unknown]\" is not assignable to type \"DataFrame\"\n \"list[Unknown]\" is not assignable to \"DataFrame\"",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 20,
- "startLine": 2203
+ "startLine": 2247
},
{
"endCharacter": 38,
- "endLine": 2204,
+ "endLine": 2248,
"file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
"message": "Argument of type \"NDArray[floating[Any]] | Unknown | NDArray[Unknown] | Any | list[Unknown]\" cannot be assigned to parameter \"base_weights\" of type \"NDArray[floating[Any]]\" in function \"_shuffle_split_rows\"\n Type \"NDArray[floating[Any]] | Unknown | NDArray[Unknown] | Any | list[Unknown]\" is not assignable to type \"NDArray[floating[Any]]\"\n \"list[Unknown]\" is not assignable to \"ndarray[_AnyShape, dtype[floating[Any]]]\"",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 20,
- "startLine": 2204
+ "startLine": 2248
},
{
"endCharacter": 39,
- "endLine": 2205,
+ "endLine": 2249,
"file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
"message": "Argument of type \"NDArray[floating[Any]] | Unknown | NDArray[Unknown] | Any | list[Unknown] | None\" cannot be assigned to parameter \"label_weights\" of type \"NDArray[floating[Any]] | None\" in function \"_shuffle_split_rows\"\n Type \"NDArray[floating[Any]] | Unknown | NDArray[Unknown] | Any | list[Unknown] | None\" is not assignable to type \"NDArray[floating[Any]] | None\"\n Type \"list[Unknown]\" is not assignable to type \"NDArray[floating[Any]] | None\"\n \"list[Unknown]\" is not assignable to \"ndarray[_AnyShape, dtype[floating[Any]]]\"\n \"list[Unknown]\" is not assignable to \"None\"",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 20,
- "startLine": 2205
+ "startLine": 2249
},
{
"endCharacter": 37,
- "endLine": 2212,
+ "endLine": 2256,
"file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
"message": "Argument of type \"Unknown | NDArray[Unknown] | Any | list[Unknown] | DataFrame\" cannot be assigned to parameter \"features\" of type \"DataFrame\" in function \"_shuffle_split_rows\"\n Type \"Unknown | NDArray[Unknown] | Any | list[Unknown] | DataFrame\" is not assignable to type \"DataFrame\"\n \"list[Unknown]\" is not assignable to \"DataFrame\"",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 24,
- "startLine": 2212
+ "startLine": 2256
},
{
"endCharacter": 35,
- "endLine": 2213,
+ "endLine": 2257,
"file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
"message": "Argument of type \"Unknown | NDArray[Unknown] | Any | list[Unknown] | DataFrame\" cannot be assigned to parameter \"labels\" of type \"DataFrame\" in function \"_shuffle_split_rows\"\n Type \"Unknown | NDArray[Unknown] | Any | list[Unknown] | DataFrame\" is not assignable to type \"DataFrame\"\n \"list[Unknown]\" is not assignable to \"DataFrame\"",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 24,
- "startLine": 2213
+ "startLine": 2257
},
{
"endCharacter": 41,
- "endLine": 2214,
+ "endLine": 2258,
"file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
"message": "Argument of type \"Unknown | NDArray[Unknown] | Any | list[Unknown] | ndarray[_AnyShape, dtype[floating[Any]]]\" cannot be assigned to parameter \"base_weights\" of type \"NDArray[floating[Any]]\" in function \"_shuffle_split_rows\"\n Type \"Unknown | NDArray[Unknown] | Any | list[Unknown] | ndarray[_AnyShape, dtype[floating[Any]]]\" is not assignable to type \"NDArray[floating[Any]]\"\n \"list[Unknown]\" is not assignable to \"ndarray[_AnyShape, dtype[floating[Any]]]\"",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 24,
- "startLine": 2214
+ "startLine": 2258
},
{
"endCharacter": 42,
- "endLine": 2215,
+ "endLine": 2259,
"file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
"message": "Argument of type \"Unknown | NDArray[Unknown] | Any | list[Unknown] | ndarray[_AnyShape, dtype[floating[Any]]] | None\" cannot be assigned to parameter \"label_weights\" of type \"NDArray[floating[Any]] | None\" in function \"_shuffle_split_rows\"\n Type \"Unknown | NDArray[Unknown] | Any | list[Unknown] | ndarray[_AnyShape, dtype[floating[Any]]] | None\" is not assignable to type \"NDArray[floating[Any]] | None\"\n Type \"list[Unknown]\" is not assignable to type \"NDArray[floating[Any]] | None\"\n \"list[Unknown]\" is not assignable to \"ndarray[_AnyShape, dtype[floating[Any]]]\"\n \"list[Unknown]\" is not assignable to \"None\"",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 24,
- "startLine": 2215
+ "startLine": 2259
},
{
"endCharacter": 30,
- "endLine": 2233,
+ "endLine": 2277,
"file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
"message": "Argument of type \"NDArray[floating[Any]] | Unknown | NDArray[Unknown] | Any | list[Unknown]\" cannot be assigned to parameter \"base_weights\" of type \"NDArray[floating[Any]]\" in function \"_compose_train_weights_with_support\"\n Type \"NDArray[floating[Any]] | Unknown | NDArray[Unknown] | Any | list[Unknown]\" is not assignable to type \"NDArray[floating[Any]]\"\n \"list[Unknown]\" is not assignable to \"ndarray[_AnyShape, dtype[floating[Any]]]\"",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 12,
- "startLine": 2233
+ "startLine": 2277
},
{
"endCharacter": 31,
- "endLine": 2234,
+ "endLine": 2278,
"file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
"message": "Argument of type \"NDArray[floating[Any]] | Unknown | NDArray[Unknown] | Any | list[Unknown] | None\" cannot be assigned to parameter \"label_weights\" of type \"NDArray[floating[Any]] | None\" in function \"_compose_train_weights_with_support\"\n Type \"NDArray[floating[Any]] | Unknown | NDArray[Unknown] | Any | list[Unknown] | None\" is not assignable to type \"NDArray[floating[Any]] | None\"\n Type \"list[Unknown]\" is not assignable to type \"NDArray[floating[Any]] | None\"\n \"list[Unknown]\" is not assignable to \"ndarray[_AnyShape, dtype[floating[Any]]]\"\n \"list[Unknown]\" is not assignable to \"None\"",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 12,
- "startLine": 2234
+ "startLine": 2278
},
{
"endCharacter": 33,
- "endLine": 2240,
+ "endLine": 2284,
"file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
"message": "Argument of type \"NDArray[floating[Any]] | Unknown | NDArray[Unknown] | Any | list[Unknown]\" cannot be assigned to parameter \"base_weights\" of type \"NDArray[floating[Any]]\" in function \"_compose_eval_weights\"\n Type \"NDArray[floating[Any]] | Unknown | NDArray[Unknown] | Any | list[Unknown]\" is not assignable to type \"NDArray[floating[Any]]\"\n \"list[Unknown]\" is not assignable to \"ndarray[_AnyShape, dtype[floating[Any]]]\"",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 16,
- "startLine": 2240
+ "startLine": 2284
},
{
"endCharacter": 34,
- "endLine": 2241,
+ "endLine": 2285,
"file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
"message": "Argument of type \"NDArray[floating[Any]] | Unknown | NDArray[Unknown] | Any | list[Unknown] | None\" cannot be assigned to parameter \"label_weights\" of type \"NDArray[floating[Any]] | None\" in function \"_compose_eval_weights\"\n Type \"NDArray[floating[Any]] | Unknown | NDArray[Unknown] | Any | list[Unknown] | None\" is not assignable to type \"NDArray[floating[Any]] | None\"\n Type \"list[Unknown]\" is not assignable to type \"NDArray[floating[Any]] | None\"\n \"list[Unknown]\" is not assignable to \"ndarray[_AnyShape, dtype[floating[Any]]]\"\n \"list[Unknown]\" is not assignable to \"None\"",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 16,
- "startLine": 2241
+ "startLine": 2285
},
{
"endCharacter": 26,
- "endLine": 2248,
+ "endLine": 2292,
"file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
"message": "Argument of type \"DataFrame | Unknown | NDArray[Unknown] | Any | list[Unknown]\" cannot be assigned to parameter \"train_df\" of type \"DataFrame\" in function \"build_data_dictionary\"\n Type \"DataFrame | Unknown | NDArray[Unknown] | Any | list[Unknown]\" is not assignable to type \"DataFrame\"\n \"list[Unknown]\" is not assignable to \"DataFrame\"",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 12,
- "startLine": 2248
+ "startLine": 2292
},
{
"endCharacter": 25,
- "endLine": 2249,
+ "endLine": 2293,
"file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
"message": "Argument of type \"DataFrame | Unknown | NDArray[Unknown] | Any | list[Unknown]\" cannot be assigned to parameter \"test_df\" of type \"DataFrame\" in function \"build_data_dictionary\"\n Type \"DataFrame | Unknown | NDArray[Unknown] | Any | list[Unknown]\" is not assignable to type \"DataFrame\"\n \"list[Unknown]\" is not assignable to \"DataFrame\"",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 12,
- "startLine": 2249
+ "startLine": 2293
},
{
"endCharacter": 24,
- "endLine": 2250,
+ "endLine": 2294,
"file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
"message": "Argument of type \"DataFrame | Unknown | NDArray[Unknown] | Any | list[Unknown]\" cannot be assigned to parameter \"train_labels\" of type \"DataFrame\" in function \"build_data_dictionary\"\n Type \"DataFrame | Unknown | NDArray[Unknown] | Any | list[Unknown]\" is not assignable to type \"DataFrame\"\n \"list[Unknown]\" is not assignable to \"DataFrame\"",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 12,
- "startLine": 2250
+ "startLine": 2294
},
{
"endCharacter": 23,
- "endLine": 2251,
+ "endLine": 2295,
"file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
"message": "Argument of type \"DataFrame | Unknown | NDArray[Unknown] | Any | list[Unknown]\" cannot be assigned to parameter \"test_labels\" of type \"DataFrame\" in function \"build_data_dictionary\"\n Type \"DataFrame | Unknown | NDArray[Unknown] | Any | list[Unknown]\" is not assignable to type \"DataFrame\"\n \"list[Unknown]\" is not assignable to \"DataFrame\"",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 12,
- "startLine": 2251
+ "startLine": 2295
},
{
"endCharacter": 87,
- "endLine": 2558,
+ "endLine": 2602,
"file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
"message": "Cannot access attribute \"index\" for class \"NDArray[Unknown]\"\n Attribute \"index\" is unknown",
"rule": "reportAttributeAccessIssue",
"severity": "error",
"startCharacter": 82,
- "startLine": 2558
+ "startLine": 2602
},
{
"endCharacter": 68,
- "endLine": 2559,
+ "endLine": 2603,
"file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
"message": "Cannot access attribute \"index\" for class \"NDArray[Unknown]\"\n Attribute \"index\" is unknown",
"rule": "reportAttributeAccessIssue",
"severity": "error",
"startCharacter": 63,
- "startLine": 2559
+ "startLine": 2603
},
{
"endCharacter": 63,
- "endLine": 2570,
+ "endLine": 2614,
"file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
"message": "Cannot access attribute \"index\" for class \"NDArray[Unknown]\"\n Attribute \"index\" is unknown",
"rule": "reportAttributeAccessIssue",
"severity": "error",
"startCharacter": 58,
- "startLine": 2570
+ "startLine": 2614
},
{
"endCharacter": 47,
- "endLine": 2572,
+ "endLine": 2616,
"file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
"message": "Cannot access attribute \"loc\" for class \"NDArray[Unknown]\"\n Attribute \"loc\" is unknown",
"rule": "reportAttributeAccessIssue",
"severity": "error",
"startCharacter": 44,
- "startLine": 2572
+ "startLine": 2616
},
{
"endCharacter": 47,
- "endLine": 2572,
+ "endLine": 2616,
"file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
"message": "Cannot access attribute \"loc\" for class \"list[Unknown]\"\n Attribute \"loc\" is unknown",
"rule": "reportAttributeAccessIssue",
"severity": "error",
"startCharacter": 44,
- "startLine": 2572
+ "startLine": 2616
},
{
"endCharacter": 43,
- "endLine": 2573,
+ "endLine": 2617,
"file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
"message": "Cannot access attribute \"loc\" for class \"NDArray[Unknown]\"\n Attribute \"loc\" is unknown",
"rule": "reportAttributeAccessIssue",
"severity": "error",
"startCharacter": 40,
- "startLine": 2573
+ "startLine": 2617
},
{
"endCharacter": 43,
- "endLine": 2573,
+ "endLine": 2617,
"file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
"message": "Cannot access attribute \"loc\" for class \"list[Unknown]\"\n Attribute \"loc\" is unknown",
"rule": "reportAttributeAccessIssue",
"severity": "error",
"startCharacter": 40,
- "startLine": 2573
+ "startLine": 2617
},
{
"endCharacter": 31,
- "endLine": 2594,
+ "endLine": 2638,
"file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
"message": "Cannot access attribute \"empty\" for class \"NDArray[Unknown]\"\n Attribute \"empty\" is unknown",
"rule": "reportAttributeAccessIssue",
"severity": "error",
"startCharacter": 26,
- "startLine": 2594
+ "startLine": 2638
},
{
"endCharacter": 31,
- "endLine": 2594,
+ "endLine": 2638,
"file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
"message": "Cannot access attribute \"empty\" for class \"list[Unknown]\"\n Attribute \"empty\" is unknown",
"rule": "reportAttributeAccessIssue",
"severity": "error",
"startCharacter": 26,
- "startLine": 2594
+ "startLine": 2638
},
{
"endCharacter": 60,
- "endLine": 2594,
+ "endLine": 2638,
"file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
"message": "Cannot access attribute \"empty\" for class \"NDArray[Unknown]\"\n Attribute \"empty\" is unknown",
"rule": "reportAttributeAccessIssue",
"severity": "error",
"startCharacter": 55,
- "startLine": 2594
+ "startLine": 2638
},
{
"endCharacter": 60,
- "endLine": 2594,
+ "endLine": 2638,
"file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
"message": "Cannot access attribute \"empty\" for class \"list[Unknown]\"\n Attribute \"empty\" is unknown",
"rule": "reportAttributeAccessIssue",
"severity": "error",
"startCharacter": 55,
- "startLine": 2594
+ "startLine": 2638
},
{
"endCharacter": 73,
- "endLine": 2606,
+ "endLine": 2650,
"file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
"message": "Argument of type \"Unknown | Any | ((value: Unknown, start: SupportsIndex = 0, stop: SupportsIndex = sys.maxsize, /) -> int)\" cannot be assigned to parameter \"target\" of type \"Index[Any]\" in function \"get_indexer\"\n Type \"Unknown | Any | ((value: Unknown, start: SupportsIndex = 0, stop: SupportsIndex = sys.maxsize, /) -> int)\" is not assignable to type \"Index[Any]\"\n \"MethodType\" is not assignable to \"Index[Any]\"",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 53,
- "startLine": 2606
+ "startLine": 2650
},
{
"endCharacter": 73,
- "endLine": 2606,
+ "endLine": 2650,
"file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
"message": "Cannot access attribute \"index\" for class \"NDArray[Unknown]\"\n Attribute \"index\" is unknown",
"rule": "reportAttributeAccessIssue",
"severity": "error",
"startCharacter": 68,
- "startLine": 2606
+ "startLine": 2650
},
{
"endCharacter": 83,
- "endLine": 2607,
+ "endLine": 2651,
"file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
"message": "Argument of type \"Unknown | Any | ((value: Unknown, start: SupportsIndex = 0, stop: SupportsIndex = sys.maxsize, /) -> int)\" cannot be assigned to parameter \"target\" of type \"Index[Any]\" in function \"get_indexer\"\n Type \"Unknown | Any | ((value: Unknown, start: SupportsIndex = 0, stop: SupportsIndex = sys.maxsize, /) -> int)\" is not assignable to type \"Index[Any]\"\n \"MethodType\" is not assignable to \"Index[Any]\"",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 58,
- "startLine": 2607
+ "startLine": 2651
},
{
"endCharacter": 83,
- "endLine": 2607,
+ "endLine": 2651,
"file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
"message": "Cannot access attribute \"index\" for class \"NDArray[Unknown]\"\n Attribute \"index\" is unknown",
"rule": "reportAttributeAccessIssue",
"severity": "error",
"startCharacter": 78,
- "startLine": 2607
+ "startLine": 2651
},
{
"endCharacter": 46,
- "endLine": 2842,
+ "endLine": 2886,
"file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
"message": "Cannot access attribute \"empty\" for class \"Buffer\"\n Attribute \"empty\" is unknown",
"rule": "reportAttributeAccessIssue",
"severity": "error",
"startCharacter": 41,
- "startLine": 2842
+ "startLine": 2886
},
{
"endCharacter": 46,
- "endLine": 2842,
+ "endLine": 2886,
"file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
"message": "Cannot access attribute \"empty\" for class \"_NestedSequence[_SupportsArray[dtype[Any]]]\"\n Attribute \"empty\" is unknown",
"rule": "reportAttributeAccessIssue",
"severity": "error",
"startCharacter": 41,
- "startLine": 2842
+ "startLine": 2886
},
{
"endCharacter": 46,
- "endLine": 2842,
+ "endLine": 2886,
"file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
"message": "Cannot access attribute \"empty\" for class \"_NestedSequence[complex | bytes | str]\"\n Attribute \"empty\" is unknown",
"rule": "reportAttributeAccessIssue",
"severity": "error",
"startCharacter": 41,
- "startLine": 2842
+ "startLine": 2886
},
{
"endCharacter": 46,
- "endLine": 2842,
+ "endLine": 2886,
"file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
"message": "Cannot access attribute \"empty\" for class \"_SupportsArray[dtype[Any]]\"\n Attribute \"empty\" is unknown",
"rule": "reportAttributeAccessIssue",
"severity": "error",
"startCharacter": 41,
- "startLine": 2842
+ "startLine": 2886
},
{
"endCharacter": 46,
- "endLine": 2842,
+ "endLine": 2886,
"file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
"message": "Cannot access attribute \"empty\" for class \"bytes\"\n Attribute \"empty\" is unknown",
"rule": "reportAttributeAccessIssue",
"severity": "error",
"startCharacter": 41,
- "startLine": 2842
+ "startLine": 2886
},
{
"endCharacter": 46,
- "endLine": 2842,
+ "endLine": 2886,
"file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
"message": "Cannot access attribute \"empty\" for class \"complex\"\n Attribute \"empty\" is unknown",
"rule": "reportAttributeAccessIssue",
"severity": "error",
"startCharacter": 41,
- "startLine": 2842
+ "startLine": 2886
},
{
"endCharacter": 46,
- "endLine": 2842,
+ "endLine": 2886,
"file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
"message": "Cannot access attribute \"empty\" for class \"str\"\n Attribute \"empty\" is unknown",
"rule": "reportAttributeAccessIssue",
"severity": "error",
"startCharacter": 41,
- "startLine": 2842
+ "startLine": 2886
},
{
"endCharacter": 41,
- "endLine": 2849,
+ "endLine": 2893,
"file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
"message": "Argument of type \"ArrayLike\" cannot be assigned to parameter \"features\" of type \"DataFrame\" in function \"_sanitize_pipeline_weights\"\n Type \"ArrayLike\" is not assignable to type \"DataFrame\"\n \"Buffer\" is not assignable to \"DataFrame\"",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 16,
- "startLine": 2849
+ "startLine": 2893
},
{
"endCharacter": 39,
- "endLine": 2898,
+ "endLine": 2942,
"file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
"message": "Argument of type \"ArrayLike\" cannot be assigned to parameter \"features\" of type \"DataFrame\" in function \"_sanitize_pipeline_weights\"\n Type \"ArrayLike\" is not assignable to type \"DataFrame\"\n \"Buffer\" is not assignable to \"DataFrame\"",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 20,
- "startLine": 2898
+ "startLine": 2942
},
{
"endCharacter": 19,
- "endLine": 3008,
+ "endLine": 3052,
"file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
"message": "Argument of type \"int | Any | None\" cannot be assigned to parameter \"gap\" of type \"int\" in function \"__init__\"\n Type \"int | Any | None\" is not assignable to type \"int\"\n \"None\" is not assignable to \"int\"",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 16,
- "startLine": 3008
+ "startLine": 3052
},
{
"endCharacter": 21,
- "endLine": 3120,
+ "endLine": 3164,
"file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
"message": "Argument of type \"Any | None\" cannot be assigned to parameter \"X\" of type \"DataFrame\" in function \"hp_objective\"\n Type \"Any | None\" is not assignable to type \"DataFrame\"\n \"None\" is not assignable to \"DataFrame\"",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 20,
- "startLine": 3120
+ "startLine": 3164
},
{
"endCharacter": 21,
- "endLine": 3121,
+ "endLine": 3165,
"file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
"message": "Argument of type \"Any | None\" cannot be assigned to parameter \"y\" of type \"DataFrame\" in function \"hp_objective\"\n Type \"Any | None\" is not assignable to type \"DataFrame\"\n \"None\" is not assignable to \"DataFrame\"",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 20,
- "startLine": 3121
+ "startLine": 3165
},
{
"endCharacter": 33,
- "endLine": 3122,
+ "endLine": 3166,
"file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
"message": "Argument of type \"Any | None\" cannot be assigned to parameter \"train_weights\" of type \"NDArray[floating[Any]]\" in function \"hp_objective\"\n Type \"Any | None\" is not assignable to type \"NDArray[floating[Any]]\"\n \"None\" is not assignable to \"ndarray[_AnyShape, dtype[floating[Any]]]\"",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 20,
- "startLine": 3122
+ "startLine": 3166
},
{
"endCharacter": 32,
- "endLine": 3123,
+ "endLine": 3167,
"file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
"message": "Argument of type \"Any | None\" cannot be assigned to parameter \"X_validation\" of type \"DataFrame\" in function \"hp_objective\"\n Type \"Any | None\" is not assignable to type \"DataFrame\"\n \"None\" is not assignable to \"DataFrame\"",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 20,
- "startLine": 3123
+ "startLine": 3167
},
{
"endCharacter": 32,
- "endLine": 3124,
+ "endLine": 3168,
"file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
"message": "Argument of type \"Any | None\" cannot be assigned to parameter \"y_validation\" of type \"DataFrame\" in function \"hp_objective\"\n Type \"Any | None\" is not assignable to type \"DataFrame\"\n \"None\" is not assignable to \"DataFrame\"",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 20,
- "startLine": 3124
+ "startLine": 3168
},
{
"endCharacter": 38,
- "endLine": 3125,
+ "endLine": 3169,
"file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
"message": "Argument of type \"Any | None\" cannot be assigned to parameter \"validation_weights\" of type \"NDArray[floating[Any]]\" in function \"hp_objective\"\n Type \"Any | None\" is not assignable to type \"NDArray[floating[Any]]\"\n \"None\" is not assignable to \"ndarray[_AnyShape, dtype[floating[Any]]]\"",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 20,
- "startLine": 3125
+ "startLine": 3169
},
{
"endCharacter": 24,
- "endLine": 3146,
+ "endLine": 3190,
"file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
"message": "Argument of type \"Any | None\" cannot be assigned to parameter \"X_test\" of type \"DataFrame\" in function \"make_test_set_and_weights\"\n Type \"Any | None\" is not assignable to type \"DataFrame\"\n \"None\" is not assignable to \"DataFrame\"",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 12,
- "startLine": 3146
+ "startLine": 3190
},
{
"endCharacter": 24,
- "endLine": 3147,
+ "endLine": 3191,
"file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
"message": "Argument of type \"Any | None\" cannot be assigned to parameter \"y_test\" of type \"DataFrame\" in function \"make_test_set_and_weights\"\n Type \"Any | None\" is not assignable to type \"DataFrame\"\n \"None\" is not assignable to \"DataFrame\"",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 12,
- "startLine": 3147
+ "startLine": 3191
},
{
"endCharacter": 30,
- "endLine": 3148,
+ "endLine": 3192,
"file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
"message": "Argument of type \"Any | None\" cannot be assigned to parameter \"test_weights\" of type \"NDArray[floating[Any]]\" in function \"make_test_set_and_weights\"\n Type \"Any | None\" is not assignable to type \"NDArray[floating[Any]]\"\n \"None\" is not assignable to \"ndarray[_AnyShape, dtype[floating[Any]]]\"",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 12,
- "startLine": 3148
+ "startLine": 3192
},
{
"endCharacter": 15,
- "endLine": 3154,
+ "endLine": 3198,
"file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
"message": "Argument of type \"Any | None\" cannot be assigned to parameter \"X\" of type \"DataFrame\" in function \"fit_regressor\"\n Type \"Any | None\" is not assignable to type \"DataFrame\"\n \"None\" is not assignable to \"DataFrame\"",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 14,
- "startLine": 3154
+ "startLine": 3198
},
{
"endCharacter": 15,
- "endLine": 3155,
+ "endLine": 3199,
"file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
"message": "Argument of type \"Any | None\" cannot be assigned to parameter \"y\" of type \"DataFrame\" in function \"fit_regressor\"\n Type \"Any | None\" is not assignable to type \"DataFrame\"\n \"None\" is not assignable to \"DataFrame\"",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 14,
- "startLine": 3155
+ "startLine": 3199
},
{
"endCharacter": 39,
- "endLine": 3156,
+ "endLine": 3200,
"file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
"message": "Argument of type \"Any | None\" cannot be assigned to parameter \"train_weights\" of type \"NDArray[floating[Any]]\" in function \"fit_regressor\"\n Type \"Any | None\" is not assignable to type \"NDArray[floating[Any]]\"\n \"None\" is not assignable to \"ndarray[_AnyShape, dtype[floating[Any]]]\"",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 26,
- "startLine": 3156
+ "startLine": 3200
},
{
"endCharacter": 38,
- "endLine": 3166,
+ "endLine": 3210,
"file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
"message": "\"columns\" is not a known attribute of \"None\"",
"rule": "reportOptionalMemberAccess",
"severity": "error",
"startCharacter": 31,
- "startLine": 3166
+ "startLine": 3210
},
{
"endCharacter": 34,
- "endLine": 3167,
+ "endLine": 3211,
"file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
"message": "\"index\" is not a known attribute of \"None\"",
"rule": "reportOptionalMemberAccess",
"severity": "error",
"startCharacter": 29,
- "startLine": 3167
+ "startLine": 3211
},
{
"endCharacter": 82,
- "endLine": 3169,
+ "endLine": 3213,
"file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
"message": "\"copy\" is not a known attribute of \"None\"",
"rule": "reportOptionalMemberAccess",
"severity": "error",
"startCharacter": 78,
- "startLine": 3169
+ "startLine": 3213
},
{
"endCharacter": 62,
- "endLine": 3468,
+ "endLine": 3647,
"file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
"message": "\"get_pair_dataframe\" is not a known attribute of \"None\"",
"rule": "reportOptionalMemberAccess",
"severity": "error",
"startCharacter": 44,
- "startLine": 3468
+ "startLine": 3647
},
{
"endCharacter": 68,
- "endLine": 3848,
+ "endLine": 4027,
"file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
"message": "Type \"floating[Any] | NDArray[float64]\" is not assignable to return type \"NDArray[floating[Any]]\"\n Type \"floating[Any] | NDArray[float64]\" is not assignable to type \"NDArray[floating[Any]]\"\n \"floating[Any]\" is not assignable to \"ndarray[_AnyShape, dtype[floating[Any]]]\"",
"rule": "reportReturnType",
"severity": "error",
"startCharacter": 15,
- "startLine": 3844
+ "startLine": 4023
},
{
"endCharacter": 13,
- "endLine": 3877,
+ "endLine": 4056,
"file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
"message": "No overloads for \"cdist\" match the provided arguments",
"rule": "reportCallIssue",
"severity": "error",
"startCharacter": 19,
- "startLine": 3872
+ "startLine": 4051
},
{
"endCharacter": 38,
- "endLine": 3875,
+ "endLine": 4054,
"file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
"message": "Argument of type \"str\" cannot be assigned to parameter \"metric\" of type \"_MetricFunc\" in function \"cdist\"\n Type \"str\" is not assignable to type \"_MetricFunc\"",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 23,
- "startLine": 3875
+ "startLine": 4054
},
{
"endCharacter": 9,
- "endLine": 3980,
+ "endLine": 4159,
"file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
"message": "No overloads for \"pdist\" match the provided arguments",
"rule": "reportCallIssue",
"severity": "error",
"startCharacter": 36,
- "startLine": 3978
+ "startLine": 4157
},
{
"endCharacter": 42,
- "endLine": 3979,
+ "endLine": 4158,
"file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
"message": "Argument of type \"str\" cannot be assigned to parameter \"metric\" of type \"_MetricFunc\" in function \"pdist\"\n Type \"str\" is not assignable to type \"_MetricFunc\"",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 27,
- "startLine": 3979
+ "startLine": 4158
},
{
"endCharacter": 9,
- "endLine": 4057,
+ "endLine": 4236,
"file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
"message": "No overloads for \"cdist\" match the provided arguments",
"rule": "reportCallIssue",
"severity": "error",
"startCharacter": 15,
- "startLine": 4052
+ "startLine": 4231
},
{
"endCharacter": 34,
- "endLine": 4055,
+ "endLine": 4234,
"file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
"message": "Argument of type \"str\" cannot be assigned to parameter \"metric\" of type \"_MetricFunc\" in function \"cdist\"\n Type \"str\" is not assignable to type \"_MetricFunc\"",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 19,
- "startLine": 4055
+ "startLine": 4234
},
{
"endCharacter": 99,
- "endLine": 4246,
+ "endLine": 4425,
"file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
"message": "No overloads for \"pdist\" match the provided arguments",
"rule": "reportCallIssue",
"severity": "error",
"startCharacter": 12,
- "startLine": 4246
+ "startLine": 4425
},
{
"endCharacter": 79,
- "endLine": 4246,
+ "endLine": 4425,
"file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
"message": "Argument of type \"str\" cannot be assigned to parameter \"metric\" of type \"_MetricFunc\" in function \"pdist\"\n Type \"str\" is not assignable to type \"_MetricFunc\"",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 64,
- "startLine": 4246
+ "startLine": 4425
},
{
"endCharacter": 55,
import logging
import random
import time
-import warnings
from collections.abc import Callable
from collections.abc import Set as AbstractSet
from dataclasses import dataclass
from datasieve.transforms import SKLearnWrapper
from freqtrade.enums import TRADE_MODES
from freqtrade.exceptions import DependencyException
+from freqtrade.exchange import timeframe_to_seconds
from freqtrade.freqai.base_models.BaseRegressionModel import BaseRegressionModel
from freqtrade.freqai.data_drawer import (
FEATURE_PIPELINE,
)
_DATE_PRED_DEDUP_SENTINEL = "_freqai_strategies_date_pred_repair_patched"
+_PRODUCED_PREDICTION_COLUMN = "_freqai_strategies_produced"
-def _recorded_prediction_mask(frame: pd.DataFrame) -> NDArray[np.bool_]:
- """Identify recorded rows from metadata, never from prediction magnitudes."""
+def _legacy_produced_prediction_mask(frame: pd.DataFrame) -> NDArray[np.bool_]:
+ """Bootstrap has status 0; only nonzero, nonexpired statuses prove legacy production."""
+ if "do_predict" not in frame:
+ return np.zeros(len(frame), dtype=bool)
+ status = pd.to_numeric(frame["do_predict"], errors="coerce")
+ return (status.notna() & np.isfinite(status) & status.ne(0) & status.ne(2)).to_numpy(dtype=bool)
+
+
+def _recorded_prediction_rank(frame: pd.DataFrame) -> NDArray[np.int8]:
+ """Prefer provable predictions to ambiguous legacy rows and placeholders."""
recorded = np.zeros(len(frame), dtype=bool)
+ status = None
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)
.fillna(False)
.to_numpy(dtype=bool)
)
- return recorded
+ recorded &= status.ne(2).fillna(True).to_numpy(dtype=bool)
+ rank = recorded.astype(np.int8)
+ rank[_legacy_produced_prediction_mask(frame)] = 2
+ if _PRODUCED_PREDICTION_COLUMN in frame:
+ marker = frame[_PRODUCED_PREDICTION_COLUMN]
+ proven = marker.eq(True).fillna(False).to_numpy(dtype=bool)
+ if status is not None:
+ proven = proven & status.ne(2).fillna(True).to_numpy(dtype=bool)
+ rank[marker.notna().to_numpy(dtype=bool)] = 0
+ rank[proven] = 2
+ return rank
def _produced_prediction_mask(frame: pd.DataFrame) -> NDArray[np.bool_]:
- """Exclude expired-model placeholders from recorded model observations."""
- produced = _recorded_prediction_mask(frame)
+ """Select real model outputs, excluding bootstrap and expired-model placeholders."""
+ produced = _legacy_produced_prediction_mask(frame)
+ if _PRODUCED_PREDICTION_COLUMN in frame:
+ marker = frame[_PRODUCED_PREDICTION_COLUMN]
+ produced = np.where(
+ marker.notna(), marker.eq(True).fillna(False).to_numpy(dtype=bool), produced
+ )
if "do_predict" in frame:
status = pd.to_numeric(frame["do_predict"], errors="coerce")
- produced &= status.ne(2).fillna(True).to_numpy(dtype=bool)
+ produced = 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.
+def _ensure_produced_prediction_column(frame: pd.DataFrame) -> pd.DataFrame:
+ if _PRODUCED_PREDICTION_COLUMN not in frame:
+ result = frame.copy()
+ result[_PRODUCED_PREDICTION_COLUMN] = _legacy_produced_prediction_mask(frame)
+ return result
+ missing = frame[_PRODUCED_PREDICTION_COLUMN].isna()
+ if not missing.any():
+ return frame
+ result = frame.copy()
+ result[_PRODUCED_PREDICTION_COLUMN] = frame[_PRODUCED_PREDICTION_COLUMN].where(
+ ~missing, _legacy_produced_prediction_mask(frame)
+ )
+ return result
+
+
+def _dedupe_historic_predictions_on_date_pred(frame: pd.DataFrame, pair: str) -> pd.DataFrame:
+ """Retain the most provable prediction per candle, in date order.
- Freqtrade fills downtime rows with zeros/NaNs, without a candle close or a
- prediction status. Those rows must not replace recorded predictions, including
- zero predictions and rejected predictions (do_predict == 0 with a candle close).
- Indistinguishable legacy rows use last-write-wins; label magnitudes never rank rows.
- Invalid dates cannot match a candle and are discarded.
+ Proven outputs (legacy nonzero statuses or explicit markers) outrank
+ ambiguous close-bearing rows, which outrank downtime and expired placeholders.
+ Equally ranked rows use last-write-wins; invalid dates are discarded.
"""
date_pred = pd.to_datetime(frame["date_pred"], utc=True, errors="coerce", format="mixed")
valid = date_pred.notna()
- if valid.all() and date_pred.is_monotonic_increasing and date_pred.is_unique:
+ if not valid.all():
+ logger.warning(
+ "FreqAI prediction history [%s]: discarded invalid date_pred entries (count=%d)",
+ pair,
+ len(frame) - int(valid.sum()),
+ )
+ elif date_pred.is_monotonic_increasing and date_pred.is_unique:
if date_pred.dtype == frame["date_pred"].dtype:
return frame
result = frame.copy()
result["date_pred"] = date_pred
return result
- recorded = _recorded_prediction_mask(frame)
+ rank = _recorded_prediction_rank(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))}
+ {"date_pred": date_pred.array, "rank": rank, "position": np.arange(len(frame))}
)
kept = (
order.loc[valid.to_numpy()]
- .sort_values(["date_pred", "recorded", "position"])
+ .sort_values(["date_pred", "rank", "position"])
.drop_duplicates("date_pred", keep="last")
)
result = frame.iloc[kept.index].copy()
def _install_date_pred_dedup_patch() -> None:
- """Repair persisted history and duplicates produced by older Freqtrade writers.
+ """Repair persisted prediction dates before Freqtrade's positional writes.
- Normalize before upstream positional writes and after legacy duplicate writes.
- Normalize before upstream disk repair can discard a recorded duplicate.
- Already-clean upstream results are preserved. Recheck these synchronous
- method contracts on Freqtrade upgrades.
+ Normalize before upstream disk repair discards a provable duplicate, and
+ align the returned candles after writes. Both model copies of this global
+ patch must have identical behavior regardless of import order.
"""
names = (
"set_initial_return_values",
self, pair: str, pred_df: pd.DataFrame, dataframe: pd.DataFrame
) -> None:
self.historic_predictions[pair] = _dedupe_historic_predictions_on_date_pred(
- self.historic_predictions[pair]
+ self.historic_predictions[pair], pair
)
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])
+ repaired = _dedupe_historic_predictions_on_date_pred(self.historic_predictions[pair], pair)
self.historic_predictions[pair] = repaired
self.model_return_values[pair] = _align_historic_predictions(repaired, dataframe)
strat_df: pd.DataFrame,
) -> None:
self.historic_predictions[pair] = _dedupe_historic_predictions_on_date_pred(
- self.historic_predictions[pair]
+ self.historic_predictions[pair], pair
)
if self.historic_predictions[pair].empty and not strat_df.empty:
- # Legacy append requires an initialized row; let upstream construct it.
+ # Append requires an initialized row; let upstream construct it.
original_set_initial(
self,
pair,
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])
+ repaired = _dedupe_historic_predictions_on_date_pred(self.historic_predictions[pair], pair)
self.historic_predictions[pair] = repaired
self.model_return_values[pair] = _align_historic_predictions(repaired, strat_df)
def attach_return_values_to_return_dataframe(
self, pair: str, dataframe: pd.DataFrame
) -> pd.DataFrame:
- repaired = _dedupe_historic_predictions_on_date_pred(self.historic_predictions[pair])
+ repaired = _dedupe_historic_predictions_on_date_pred(self.historic_predictions[pair], pair)
self.historic_predictions[pair] = repaired
self.model_return_values[pair] = _align_historic_predictions(repaired, dataframe)
return original_attach(self, pair, dataframe)
@wraps(original_repair)
def repair_historic_predictions(self, pair: str, pair_df: pd.DataFrame) -> pd.DataFrame:
if "date_pred" in pair_df:
- pair_df = _dedupe_historic_predictions_on_date_pred(pair_df)
+ pair_df = _dedupe_historic_predictions_on_date_pred(pair_df, pair)
return original_repair(self, pair, pair_df)
replacements += (repair_historic_predictions,)
ValidationMode = Literal["warn", "raise", "none"]
_VALIDATION_MODES: Final[tuple[ValidationMode, ...]] = get_args(ValidationMode)
SplitFn = Callable[[pd.DataFrame, pd.DataFrame, "SampleWeightInputs", pd.DataFrame], dict[str, Any]]
-warnings.simplefilter(action="ignore", category=FutureWarning)
+
logger = logging.getLogger(__name__)
return
_KNOWN_AT_NONE_LOGGED.add(key)
logger.info(
- f"[{pair}] {context}: No <label>_known_at_lookahead column present; "
+ f"[{pair}] {context}: No usable label/weight known-at-lookahead data; "
"causal guards use position-based purge only (label-aware filtering disabled)"
)
https://github.com/sponsors/robcaulk
"""
- version = "3.13.0-rc.10"
+ version = "3.13.0-rc.11"
+ _CALIBRATION_START_KEY: Final[str] = "quickadapter_calibration_start"
_DEPLOYMENT_COORDINATE_MARKER_KEY: Final[str] = "quickadapter_deployment_coordinates"
_DEPLOYMENT_COORDINATE_GENERATION: Final[str] = "frozen-pipelines-v1"
logger.info(f"{context}: Removed {removed} causal-unsafe train rows")
if not keep_mask.any():
raise ValueError(
- f"{context}: causal guard removed all train rows "
- f"(pivot-sparse training window; widen fit_live_predictions_candles "
- f"or lower label_natr_multiplier)"
+ f"{context}: causal guard removed all train rows; "
+ "no train rows satisfy the causal availability cutoff"
)
return (
train_features.loc[keep_mask],
self._optuna_hp_value: dict[str, float] = {}
self._holdout_rmse: dict[str, float] = {}
self._session_fitted_pairs: set[str] = set()
+ self._calibration_current_candles: dict[str, pd.Timestamp] = {}
self._optuna_label_values: dict[str, list[float | int]] = {}
self._optuna_hp_params: dict[str, dict[str, Any]] = {}
self._optuna_label_params: dict[str, dict[str, Any]] = {}
data_dictionary["test_weights"] = data_dictionary["test_weights"][holdout_mask]
if data_dictionary["test_features"].empty:
logger.warning(
- f"[{pair}] Causal purge emptied the holdout (label horizon "
- f">= holdout span); skipping holdout evaluation "
- f"(holdout_rmse=inf)"
+ f"[{pair}] No holdout rows passed the causal availability "
+ "cutoff at the end of the data window; skipping holdout "
+ "evaluation (holdout_rmse=inf)"
)
data_dictionary["holdout_purged_empty"] = True
if len(self._optuna_label_incremented_pairs) >= len(self.pairs):
self._optuna_label_incremented_pairs = []
+ def set_initial_historic_predictions(
+ self, pred_df: pd.DataFrame, dk: FreqaiDataKitchen, pair: str, strat_df: pd.DataFrame
+ ) -> None:
+ super().set_initial_historic_predictions(pred_df, dk, pair, strat_df)
+ if self.live:
+ self.dd.historic_predictions[pair] = _ensure_produced_prediction_column(
+ self.dd.historic_predictions[pair]
+ )
+
+ def build_strategy_return_arrays(
+ self, dataframe: pd.DataFrame, dk: FreqaiDataKitchen, pair: str, trained_timestamp: int
+ ) -> None:
+ """Record real appends and use Freqtrade's current candle for calibration."""
+ had_returns = pair in self.dd.model_return_values
+ if self.live and pair in self.dd.historic_predictions:
+ self.dd.historic_predictions[pair] = _ensure_produced_prediction_column(
+ self.dd.historic_predictions[pair]
+ )
+ if not dataframe.empty:
+ self._calibration_current_candles[pair] = pd.to_datetime(
+ dataframe["date"].iloc[-1], utc=True, errors="coerce"
+ )
+ try:
+ super().build_strategy_return_arrays(dataframe, dk, pair, trained_timestamp)
+ if self.live and had_returns:
+ history = self.dd.historic_predictions[pair]
+ current = self._calibration_current_candles.get(pair)
+ # Native append overwrites the last row on the same date, but
+ # returns early if the strategy candle predates the saved one.
+ if (
+ current is not None
+ and pd.notna(current)
+ and not history.empty
+ and pd.to_datetime(history["date_pred"].iloc[-1], utc=True) == current
+ ):
+ history.at[history.index[-1], _PRODUCED_PREDICTION_COLUMN] = True
+ returned = self.dd.model_return_values[pair]
+ if not returned.empty and _PRODUCED_PREDICTION_COLUMN in returned:
+ returned.at[returned.index[-1], _PRODUCED_PREDICTION_COLUMN] = True
+ if _PRODUCED_PREDICTION_COLUMN in dk.return_dataframe:
+ dk.return_dataframe = dk.return_dataframe.drop(columns=_PRODUCED_PREDICTION_COLUMN)
+ finally:
+ self._calibration_current_candles.pop(pair, None)
+
+ def _persist_calibration_start(self, pair: str, start: pd.Timestamp) -> None:
+ """Persist a UTC boundary without mutating Freqtrade's shared empty extras."""
+ self.dd.get_pair_dict_info(pair)
+ pair_info = self.dd.pair_dict[pair]
+ extras = pair_info.get("extras", {})
+ value = start.isoformat()
+ if extras.get(self._CALIBRATION_START_KEY) == value:
+ return
+ self.dd.pair_dict[pair] = {
+ **pair_info,
+ "extras": {**extras, self._CALIBRATION_START_KEY: value},
+ }
+ self.dd.save_drawer_to_disk()
+
+ def _calibration_decision_time(
+ self, dk: FreqaiDataKitchen, pair: str, history: pd.DataFrame
+ ) -> pd.Timestamp | None:
+ """Use the live strategy candle; retain historical fallback for direct callers."""
+ if pair in self._calibration_current_candles:
+ current = self._calibration_current_candles[pair]
+ return current if pd.notna(current) else None
+ full_df = getattr(dk, "full_df", None)
+ if isinstance(full_df, pd.DataFrame) and "date" in full_df:
+ dates = pd.to_datetime(full_df["date"], utc=True, errors="coerce", format="mixed")
+ if not dates.empty and pd.notna(dates.max()):
+ return dates.max()
+ if not history.empty:
+ latest = pd.to_datetime(
+ history["date_pred"], utc=True, errors="coerce", format="mixed"
+ ).max()
+ if pd.notna(latest):
+ return latest
+ return None
+
+ def _migrate_calibration_start(
+ self, pair: str, history: pd.DataFrame, decision_time: pd.Timestamp
+ ) -> pd.Timestamp:
+ """Resume only provable legacy outputs; an ambiguous bootstrap starts cold."""
+ produced = (
+ _produced_prediction_mask(history) & history["date_pred"].le(decision_time).to_numpy()
+ )
+ if produced.any():
+ start = history.loc[produced, "date_pred"].min()
+ logger.info("[%s] Resuming calibration from prediction history", pair)
+ else:
+ start = decision_time
+ logger.info("[%s] Starting calibration after FreqAI bootstrap history", pair)
+ self._persist_calibration_start(pair, start)
+ return start
+
+ def _calibration_history(
+ self,
+ dk: FreqaiDataKitchen,
+ pair: str,
+ history: pd.DataFrame,
+ sample_size: int,
+ ) -> pd.DataFrame:
+ """Select persisted observations for the current calibration period."""
+ decision_time = self._calibration_decision_time(dk, pair, history)
+ if decision_time is None:
+ return history.iloc[:0]
+ self.dd.get_pair_dict_info(pair)
+ raw_start = self.dd.pair_dict[pair].get("extras", {}).get(self._CALIBRATION_START_KEY)
+ start = (
+ pd.to_datetime(raw_start, utc=True, errors="coerce")
+ if isinstance(raw_start, str)
+ else pd.NaT
+ )
+ if pd.isna(start) or start > decision_time:
+ start = self._migrate_calibration_start(pair, history, decision_time)
+ elif raw_start != start.isoformat():
+ self._persist_calibration_start(pair, start)
+
+ produced = (
+ _produced_prediction_mask(history) & history["date_pred"].le(decision_time).to_numpy()
+ )
+ eligible = history.loc[produced & history["date_pred"].ge(start).to_numpy()]
+ max_gap = pd.Timedelta(seconds=sample_size * timeframe_to_seconds(self.config["timeframe"]))
+ # Include the persisted boundary itself: history may have been rebuilt
+ # after a restart, leaving no rows from the preceding warmup segment.
+ gap_starts = eligible.loc[eligible["date_pred"].diff().gt(max_gap), "date_pred"]
+ if not eligible.empty and eligible["date_pred"].iloc[0] - start > max_gap:
+ gap_starts = pd.concat([eligible["date_pred"].iloc[:1], gap_starts])
+ if not gap_starts.empty:
+ start = gap_starts.iloc[-1]
+ logger.warning(
+ "[%s] Calibration history contains a gap longer than %s; resuming warmup after the gap",
+ pair,
+ max_gap,
+ )
+ self._persist_calibration_start(pair, start)
+ eligible = history.loc[produced & history["date_pred"].ge(start).to_numpy()]
+
+ last_observation = eligible["date_pred"].max() if not eligible.empty else start
+ if decision_time - last_observation > max_gap:
+ logger.warning(
+ "[%s] Calibration observations are older than %s; starting a new warmup",
+ pair,
+ max_gap,
+ )
+ start = decision_time
+ self._persist_calibration_start(pair, start)
+ eligible = history.loc[produced & history["date_pred"].ge(start).to_numpy()]
+ return eligible
+
def fit_live_predictions(self, dk: FreqaiDataKitchen, pair: str) -> None:
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]
+ history = _dedupe_historic_predictions_on_date_pred(history, pair)
+ history = self._calibration_history(dk, pair, history, fit_live_predictions_candles)
remaining = fit_live_predictions_candles - len(history)
warmed_up = remaining <= 0
if not warmed_up:
specificity = float(sum(1 for c in pattern if c not in "*?[]"))
matches.append((specificity, pattern, col_config))
- if columns_config and not matches:
- logger.warning(
- f"Column '{column_name}' did not match any pattern in columns config. "
- f"Available patterns: {list(columns_config.keys())}"
- )
-
matches.sort(key=lambda x: x[0])
for _, _, col_config in matches:
_ANNOTATION_LINE_OFFSET_CANDLES: Final[int] = 10
def version(self) -> str:
- return "3.13.0-rc.10"
+ return "3.13.0-rc.11"
timeframe = "5m"
timeframe_minutes = timeframe_to_minutes(timeframe)