Restore non-live continuation components from the validated saved artifact. Preserve live caches and honor the configured RL continuation device.
Closes #276
"endCharacter": 22,
"endLine": 1122,
"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]\"",
+ "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[Any, Any]\"\n \"VecEnv\" is not assignable to \"VecMonitor\"\n \"VecEnv\" is not assignable to \"SubprocVecEnv\"\n \"VecEnv\" is not assignable to \"Env[Any, Any]\"",
"rule": "reportAttributeAccessIssue",
"severity": "error",
"startCharacter": 13,
"endCharacter": 37,
"endLine": 1122,
"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]\"",
+ "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[Any, Any]\"\n Type \"VecEnv\" is not assignable to type \"VecMonitor | SubprocVecEnv | Env[Any, Any]\"\n \"VecEnv\" is not assignable to \"VecMonitor\"\n \"VecEnv\" is not assignable to \"SubprocVecEnv\"\n \"VecEnv\" is not assignable to \"Env[Any, Any]\"",
"rule": "reportAttributeAccessIssue",
"severity": "error",
"startCharacter": 29,
},
{
"endCharacter": 38,
- "endLine": 1617,
+ "endLine": 1620,
"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": 1617
+ "startLine": 1620
},
{
"endCharacter": 36,
- "endLine": 1621,
+ "endLine": 1624,
"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": 1621
+ "startLine": 1624
},
{
"endCharacter": 80,
- "endLine": 1624,
+ "endLine": 1627,
"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": 1624
+ "startLine": 1627
},
{
"endCharacter": 78,
- "endLine": 1625,
+ "endLine": 1628,
"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": 1625
+ "startLine": 1628
},
{
"endCharacter": 80,
- "endLine": 1626,
+ "endLine": 1629,
"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": 1626
+ "startLine": 1629
},
{
"endCharacter": 56,
- "endLine": 1710,
+ "endLine": 1713,
"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\"",
+ "message": "Argument of type \"VecMonitor | SubprocVecEnv | Env[Any, Any]\" cannot be assigned to parameter \"eval_env\" of type \"VecEnv | None\" in function \"get_callbacks\"\n Type \"VecMonitor | SubprocVecEnv | Env[Any, Any]\" is not assignable to type \"VecEnv | None\"\n Type \"Env[Any, Any]\" is not assignable to type \"VecEnv | None\"\n \"Env[Any, Any]\" is not assignable to \"VecEnv\"\n \"Env[Any, Any]\" is not assignable to \"None\"",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 43,
- "startLine": 1710
+ "startLine": 1713
},
{
"endCharacter": 84,
- "endLine": 1730,
+ "endLine": 1733,
"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": 1730
+ "startLine": 1733
},
{
"endCharacter": 84,
- "endLine": 1730,
+ "endLine": 1733,
"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": 1730
+ "startLine": 1733
},
{
"endCharacter": 44,
- "endLine": 2808,
+ "endLine": 2811,
"file": "ReforceXY/user_data/freqaimodels/ReforceXY.py",
"message": "\"best_trial_params\" is possibly unbound",
"rule": "reportPossiblyUnboundVariable",
"severity": "error",
"startCharacter": 27,
- "startLine": 2808
+ "startLine": 2811
},
{
"endCharacter": 12,
- "endLine": 2828,
+ "endLine": 2831,
"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": 2828
+ "startLine": 2831
},
{
"endCharacter": 16,
- "endLine": 2829,
+ "endLine": 2832,
"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": 2829
+ "startLine": 2832
},
{
"endCharacter": 51,
- "endLine": 2874,
+ "endLine": 2877,
"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",
+ "message": "Argument of type \"list[() -> BaseEnvironment]\" cannot be assigned to parameter \"env_fns\" of type \"list[() -> Env[Any, Any]]\" in function \"__init__\"\n \"list[() -> BaseEnvironment]\" is not assignable to \"list[() -> Env[Any, Any]]\"\n Type parameter \"_T@list\" is invariant, but \"() -> BaseEnvironment\" is not the same as \"() -> Env[Any, Any]\"\n Consider switching from \"list\" to \"Sequence\" which is covariant",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 42,
- "startLine": 2874
+ "startLine": 2877
},
{
"endCharacter": 53,
- "endLine": 2880,
+ "endLine": 2883,
"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",
+ "message": "Argument of type \"list[() -> BaseEnvironment]\" cannot be assigned to parameter \"env_fns\" of type \"list[() -> Env[Any, Any]]\" in function \"__init__\"\n \"list[() -> BaseEnvironment]\" is not assignable to \"list[() -> Env[Any, Any]]\"\n Type parameter \"_T@list\" is invariant, but \"() -> BaseEnvironment\" is not the same as \"() -> Env[Any, Any]\"\n Consider switching from \"list\" to \"Sequence\" which is covariant",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 45,
- "startLine": 2880
+ "startLine": 2883
},
{
"endCharacter": 22,
- "endLine": 2943,
+ "endLine": 2946,
"file": "ReforceXY/user_data/freqaimodels/ReforceXY.py",
"message": "Operator \"*\" not supported for \"None\"",
"rule": "reportOptionalOperand",
"severity": "error",
"startCharacter": 15,
- "startLine": 2943
+ "startLine": 2946
},
{
"endCharacter": 96,
- "endLine": 2945,
+ "endLine": 2948,
"file": "ReforceXY/user_data/freqaimodels/ReforceXY.py",
"message": "Operator \"*\" not supported for \"None\"",
"rule": "reportOptionalOperand",
"severity": "error",
"startCharacter": 89,
- "startLine": 2945
+ "startLine": 2948
},
{
"endCharacter": 23,
- "endLine": 2948,
+ "endLine": 2951,
"file": "ReforceXY/user_data/freqaimodels/ReforceXY.py",
"message": "Operator \"*\" not supported for \"None\"",
"rule": "reportOptionalOperand",
"severity": "error",
"startCharacter": 16,
- "startLine": 2948
+ "startLine": 2951
},
{
"endCharacter": 98,
- "endLine": 2950,
+ "endLine": 2953,
"file": "ReforceXY/user_data/freqaimodels/ReforceXY.py",
"message": "Operator \"*\" not supported for \"None\"",
"rule": "reportOptionalOperand",
"severity": "error",
"startCharacter": 91,
- "startLine": 2950
+ "startLine": 2953
},
{
"endCharacter": 44,
- "endLine": 2962,
+ "endLine": 2965,
"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": 2962
+ "startLine": 2965
},
{
"endCharacter": 133,
- "endLine": 2964,
+ "endLine": 2967,
"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": 2964
+ "startLine": 2967
},
{
"endCharacter": 30,
- "endLine": 2967,
+ "endLine": 2970,
"file": "ReforceXY/user_data/freqaimodels/ReforceXY.py",
"message": "Operator \">\" not supported for \"None\"",
"rule": "reportOptionalOperand",
"severity": "error",
"startCharacter": 15,
- "startLine": 2967
+ "startLine": 2970
},
{
"endCharacter": 54,
- "endLine": 3033,
+ "endLine": 3036,
"file": "ReforceXY/user_data/freqaimodels/ReforceXY.py",
"message": "\"is_pruned\" is not a known attribute of \"None\"",
"rule": "reportOptionalMemberAccess",
"severity": "error",
"startCharacter": 45,
- "startLine": 3033
+ "startLine": 3036
},
{
"endCharacter": 67,
- "endLine": 3036,
+ "endLine": 3039,
"file": "ReforceXY/user_data/freqaimodels/ReforceXY.py",
"message": "\"use_masking\" is not a known attribute of \"None\"",
"rule": "reportOptionalMemberAccess",
"severity": "error",
"startCharacter": 56,
- "startLine": 3036
+ "startLine": 3039
},
{
"endCharacter": 60,
- "endLine": 3044,
+ "endLine": 3047,
"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": 3044
+ "startLine": 3047
},
{
"endCharacter": 84,
- "endLine": 3044,
+ "endLine": 3047,
"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": 3044
+ "startLine": 3047
},
{
"endCharacter": 84,
- "endLine": 3044,
+ "endLine": 3047,
"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": 3044
+ "startLine": 3047
},
{
"endCharacter": 46,
- "endLine": 3098,
+ "endLine": 3101,
"file": "ReforceXY/user_data/freqaimodels/ReforceXY.py",
"message": "\"is_pruned\" is not a known attribute of \"None\"",
"rule": "reportOptionalMemberAccess",
"severity": "error",
"startCharacter": 37,
- "startLine": 3098
+ "startLine": 3101
},
{
"endCharacter": 57,
- "endLine": 3101,
+ "endLine": 3104,
"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": 3101
+ "startLine": 3104
},
{
"endCharacter": 37,
- "endLine": 3111,
+ "endLine": 3114,
"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]\"",
+ "message": "Cannot assign to attribute \"train_env\" for class \"ReforceXY*\"\n Type \"None\" is not assignable to type \"VecMonitor | SubprocVecEnv | Env[Any, Any]\"\n \"None\" is not assignable to \"VecMonitor\"\n \"None\" is not assignable to \"SubprocVecEnv\"\n \"None\" is not assignable to \"Env[Any, Any]\"",
"rule": "reportAttributeAccessIssue",
"severity": "error",
"startCharacter": 33,
- "startLine": 3111
+ "startLine": 3114
},
{
"endCharacter": 36,
- "endLine": 3116,
+ "endLine": 3119,
"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]\"",
+ "message": "Cannot assign to attribute \"eval_env\" for class \"ReforceXY*\"\n Type \"None\" is not assignable to type \"VecMonitor | SubprocVecEnv | Env[Any, Any]\"\n \"None\" is not assignable to \"VecMonitor\"\n \"None\" is not assignable to \"SubprocVecEnv\"\n \"None\" is not assignable to \"Env[Any, Any]\"",
"rule": "reportAttributeAccessIssue",
"severity": "error",
"startCharacter": 32,
- "startLine": 3116
+ "startLine": 3119
},
{
"endCharacter": 7,
- "endLine": 3161,
+ "endLine": 3164,
"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": 3161
+ "startLine": 3164
},
{
"endCharacter": 36,
- "endLine": 3173,
+ "endLine": 3176,
"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": 3173
+ "startLine": 3176
},
{
"endCharacter": 13,
- "endLine": 3765,
+ "endLine": 3768,
"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": 3765
+ "startLine": 3768
},
{
"endCharacter": 26,
- "endLine": 3786,
+ "endLine": 3789,
"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": 3786
+ "startLine": 3789
},
{
"endCharacter": 55,
- "endLine": 4091,
+ "endLine": 4094,
"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": 4091
+ "startLine": 4094
},
{
"endCharacter": 55,
- "endLine": 4091,
+ "endLine": 4094,
"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": 4091
+ "startLine": 4094
},
{
"endCharacter": 59,
- "endLine": 4115,
+ "endLine": 4118,
"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": 4115
+ "startLine": 4118
},
{
"endCharacter": 59,
- "endLine": 4115,
+ "endLine": 4118,
"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": 4115
+ "startLine": 4118
},
{
"endCharacter": 24,
- "endLine": 4144,
+ "endLine": 4147,
"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": 4144
+ "startLine": 4147
},
{
"endCharacter": 12,
- "endLine": 4237,
+ "endLine": 4240,
"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": 4237
+ "startLine": 4240
},
{
"endCharacter": 20,
- "endLine": 4432,
+ "endLine": 4435,
"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": 4432
+ "startLine": 4435
},
{
"endCharacter": 40,
- "endLine": 4581,
+ "endLine": 4584,
"file": "ReforceXY/user_data/freqaimodels/ReforceXY.py",
"message": "\"Figure\" is not exported from module \"matplotlib.pyplot\"",
"rule": "reportPrivateImportUsage",
"severity": "error",
"startCharacter": 34,
- "startLine": 4581
+ "startLine": 4584
},
{
"endCharacter": 54,
- "endLine": 5066,
+ "endLine": 5069,
"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": 5066
+ "startLine": 5069
},
{
"endCharacter": 54,
- "endLine": 5066,
+ "endLine": 5069,
"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": 5066
+ "startLine": 5069
},
{
"endCharacter": 50,
- "endLine": 5078,
+ "endLine": 5081,
"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": 5078
+ "startLine": 5081
},
{
"endCharacter": 72,
- "endLine": 5089,
+ "endLine": 5092,
"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": 5089
+ "startLine": 5092
},
{
"endCharacter": 72,
- "endLine": 5089,
+ "endLine": 5092,
"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": 5089
+ "startLine": 5092
},
{
"endCharacter": 73,
- "endLine": 5098,
+ "endLine": 5101,
"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": 5098
+ "startLine": 5101
},
{
"endCharacter": 73,
- "endLine": 5098,
+ "endLine": 5101,
"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": 5098
+ "startLine": 5101
},
{
"endCharacter": 58,
- "endLine": 5107,
+ "endLine": 5110,
"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": 5107
+ "startLine": 5110
},
{
"endCharacter": 58,
- "endLine": 5107,
+ "endLine": 5110,
"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": 5107
+ "startLine": 5110
},
{
"endCharacter": 50,
- "endLine": 5338,
+ "endLine": 5341,
"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": 5338
+ "startLine": 5341
},
{
"endCharacter": 20,
- "endLine": 5497,
+ "endLine": 5500,
"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": 5497
+ "startLine": 5500
},
{
"endCharacter": 20,
- "endLine": 5497,
+ "endLine": 5500,
"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": 5497
+ "startLine": 5500
},
{
"endCharacter": 59,
- "endLine": 5502,
+ "endLine": 5505,
"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": 5502
+ "startLine": 5505
},
{
"endCharacter": 59,
- "endLine": 5502,
+ "endLine": 5505,
"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": 5502
+ "startLine": 5505
},
{
"endCharacter": 65,
- "endLine": 5503,
+ "endLine": 5506,
"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": 5503
+ "startLine": 5506
},
{
"endCharacter": 65,
- "endLine": 5503,
+ "endLine": 5506,
"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": 5503
+ "startLine": 5506
},
{
"endCharacter": 63,
- "endLine": 5506,
+ "endLine": 5509,
"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": 5506
+ "startLine": 5509
},
{
"endCharacter": 63,
- "endLine": 5506,
+ "endLine": 5509,
"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": 5506
+ "startLine": 5509
},
{
"endCharacter": 61,
- "endLine": 5508,
+ "endLine": 5511,
"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": 5508
+ "startLine": 5511
},
{
"endCharacter": 61,
- "endLine": 5508,
+ "endLine": 5511,
"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": 5508
+ "startLine": 5511
},
{
"endCharacter": 67,
- "endLine": 5509,
+ "endLine": 5512,
"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": 5509
+ "startLine": 5512
},
{
"endCharacter": 67,
- "endLine": 5509,
+ "endLine": 5512,
"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": 5509
+ "startLine": 5512
},
{
"endCharacter": 73,
- "endLine": 5510,
+ "endLine": 5513,
"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": 5510
+ "startLine": 5513
},
{
"endCharacter": 73,
- "endLine": 5510,
+ "endLine": 5513,
"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": 5510
+ "startLine": 5513
},
{
"endCharacter": 61,
- "endLine": 5511,
+ "endLine": 5514,
"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": 5511
+ "startLine": 5514
},
{
"endCharacter": 61,
- "endLine": 5511,
+ "endLine": 5514,
"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": 5511
+ "startLine": 5514
},
{
"endCharacter": 89,
- "endLine": 5518,
+ "endLine": 5521,
"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": 5518
+ "startLine": 5521
},
{
"endCharacter": 89,
- "endLine": 5518,
+ "endLine": 5521,
"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": 5518
+ "startLine": 5521
},
{
"endCharacter": 83,
- "endLine": 5519,
+ "endLine": 5522,
"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": 5519
+ "startLine": 5522
},
{
"endCharacter": 83,
- "endLine": 5519,
+ "endLine": 5522,
"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": 5519
+ "startLine": 5522
},
{
"endCharacter": 65,
- "endLine": 5545,
+ "endLine": 5548,
"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": 5545
+ "startLine": 5548
},
{
"endCharacter": 65,
- "endLine": 5545,
+ "endLine": 5548,
"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": 5545
+ "startLine": 5548
},
{
"endCharacter": 67,
- "endLine": 5547,
+ "endLine": 5550,
"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": 5547
+ "startLine": 5550
},
{
"endCharacter": 67,
- "endLine": 5547,
+ "endLine": 5550,
"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": 5547
+ "startLine": 5550
},
{
"endCharacter": 87,
- "endLine": 5550,
+ "endLine": 5553,
"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": 5550
+ "startLine": 5553
},
{
"endCharacter": 87,
- "endLine": 5550,
+ "endLine": 5553,
"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": 5550
+ "startLine": 5553
},
{
"endCharacter": 93,
- "endLine": 5551,
+ "endLine": 5554,
"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": 5551
+ "startLine": 5554
},
{
"endCharacter": 93,
- "endLine": 5551,
+ "endLine": 5554,
"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": 5551
+ "startLine": 5554
},
{
"endCharacter": 89,
- "endLine": 5552,
+ "endLine": 5555,
"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": 5552
+ "startLine": 5555
},
{
"endCharacter": 89,
- "endLine": 5552,
+ "endLine": 5555,
"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": 5552
+ "startLine": 5555
},
{
"endCharacter": 89,
- "endLine": 5553,
+ "endLine": 5556,
"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": 5553
+ "startLine": 5556
},
{
"endCharacter": 89,
- "endLine": 5553,
+ "endLine": 5556,
"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": 5553
+ "startLine": 5556
},
{
"endCharacter": 75,
- "endLine": 5554,
+ "endLine": 5557,
"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": 5554
+ "startLine": 5557
},
{
"endCharacter": 75,
- "endLine": 5554,
+ "endLine": 5557,
"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": 5554
+ "startLine": 5557
},
{
"endCharacter": 33,
are reused only when their objective identity matches.
Backtests continue only from a saved policy whose training cutoff precedes
-the current window's end and its last available candle boundary. A later
-deployment under the same identifier is not reused for an earlier window,
-even when FreqAI has saved only metadata for intervening windows. Live and
-dry-run restarts still restore compatible deployed policies.
+the current window's end and its last available candle boundary. The policy,
+fitted feature pipeline and any required replay come from that saved artifact.
+A later deployment under the same identifier is not reused for an earlier
+window, even when FreqAI has saved only metadata for intervening windows.
+Live and dry-run restarts still restore compatible deployed policies.
## Live inference and backtesting
| freqai.model_training_parameters.learning_rate | SDK default unless lr_schedule=true; then initial 0.0003 if omitted | SDK numeric/schedule; app wraps numeric only | Omitted | Do not call 0.0003 an unconditional app default. |
| freqai.model_training_parameters.clip_range | SDK default unless PPO-family cr_schedule=true; then initial 0.2 if omitted | SDK numeric/schedule; app wraps numeric only | Omitted | Only PPO family schedule conversion. |
| freqai.model_training_parameters.gpu_memory_fraction | null/omitted disables | Numeric in (0,1] intended; ignored invalid bounds/no CUDA, not robust type validation | Omitted | App-only; applies torch CUDA per-process limit to device 0, removed before SDK constructor. |
-| freqai.model_training_parameters.device | No app fallback; SDK auto | PyTorch/SB3 device specification | auto | Forwarded; doc examples auto/cpu/cuda/cuda:0 are not an app-enforced exhaustive choice list. |
+| freqai.model_training_parameters.device | SDK auto when omitted | PyTorch/SB3 device specification | auto | Forwarded to new learners and continuation archive loads; live cached copies retain their deployed device. Native device syntax applies. |
| freqai.model_training_parameters.verbose | SDK constructor default; callback lookup fallback 0 | SDK verbosity integer | 1 | Forwarded to constructor, also read for callback verbosity. |
| freqai.model_training_parameters.policy_kwargs.net_arch | [128,128] per branch for PPO family; [128,128] for others | small\|medium\|large\|extra_large, list of layer widths; PPO family additionally {pi:[...],vf:[...]} | Omitted | Presets use two layers of 128/256/512/1024; PPO list expanded to both heads, invalid/missing head resets to [128,128]. Other families accept list or presets. Layer element validation remains SDK. |
| freqai.model_training_parameters.policy_kwargs.activation_fn | relu | relu\|tanh\|elu\|leaky_relu | Omitted | Converted to torch class; unknown name silently falls back to ReLU. |
"""Regression contracts for learning eligibility, replay and temporal observations."""
+import copy
import json
import tempfile
from pathlib import Path
from freqtrade.enums import RunMode
from freqtrade.exceptions import DependencyException
from freqtrade.exchange import timeframe_to_seconds
-from freqtrade.freqai.data_drawer import METADATA, FreqaiDataDrawer
+from freqtrade.freqai.data_drawer import FEATURE_PIPELINE, METADATA, FreqaiDataDrawer
from freqtrade.freqai.data_kitchen import FreqaiDataKitchen
from optuna import TrialPruned, create_study
-from qa_support import QaTestCase, RecordingPolicy, model_config
+from qa_support import PAIR, PROJECT_ROOT, QaTestCase, RecordingPolicy, model_config
from ReforceXY.user_data.freqaimodels.ReforceXY import ReforceXY
)
for column in ("open", "high", "low", "close"):
frame[f"%-raw_{column}"] = 100 + np.arange(64) * 0.1
- dk = FreqaiDataKitchen(config, live=True, pair="BTC/USDT")
+ dk = FreqaiDataKitchen(config, live=True, pair=PAIR)
dk.data_path = Path(temp) / "initial"
dk.model_filename = "cb_btc_initial"
dk.label_list = ["&-action"]
"device": "cpu",
"policy_kwargs": {"net_arch": [8]},
}
- pair = "BTC/USDT"
+ pair = PAIR
def frame(day, feature_offset):
values = np.arange(64)
backtest_config["runmode"] = RunMode.BACKTEST
backtest_config["timerange"] = "20260101-20260105"
backtest_config["config_files"] = [
- "/workspace/ReforceXY/user_data/config-template.json"
+ str(PROJECT_ROOT / "user_data" / "config-template.json")
]
backtest = ReforceXY(config=backtest_config)
backtest.live = False
transformed = boundary_dk.data_dictionary["train_features"]["%-feature"]
self.assertGreater(transformed.min(), 2.0)
+ def test_backtest_archive_continuation_preserves_explicit_cpu_placement(self):
+ for algorithm in ("DQN", "QRDQN"):
+ with self.subTest(algorithm=algorithm), tempfile.TemporaryDirectory() as temp:
+ config = model_config(temp)
+ info = config["freqai"]
+ info["continual_learning"] = True
+ info["data_split_parameters"]["test_size"] = 0
+ info["rl_config"]["model_type"] = algorithm
+ info["model_training_parameters"] = {
+ "learning_starts": 0,
+ "buffer_size": 256,
+ "batch_size": 8,
+ "train_freq": 4,
+ "gradient_steps": 1,
+ "device": "cpu",
+ "policy_kwargs": {"net_arch": [8]},
+ }
+ owner = ReforceXY(config=config)
+ owner.live = True
+ owner.can_short = False
+ self.addCleanup(owner.close_envs)
+ values = np.arange(64)
+ frame = pd.DataFrame(
+ {
+ "date": pd.date_range("2026-01-01", periods=64, freq="5min", tz="UTC"),
+ "%-feature": np.sin(values),
+ "&-action": np.zeros(64),
+ }
+ )
+ for column in ("open", "high", "low", "close"):
+ frame[f"%-raw_{column}"] = 100.0 + values * 0.1
+ dk = FreqaiDataKitchen(config, live=True, pair=PAIR)
+ timestamp = int((frame["date"].iloc[-1] + pd.Timedelta(minutes=5)).timestamp())
+ dk.set_paths(dk.pair, timestamp)
+ dk.set_new_model_names(dk.pair, timestamp)
+ dk.training_features_list = [column for column in frame if column.startswith("%")]
+ dk.label_list = ["&-action"]
+ trained = owner.train(frame, dk.pair, dk)
+ owner.dd.get_pair_dict_info(dk.pair)
+ owner.dd.pair_dict[dk.pair]["trained_timestamp"] = timestamp
+ owner.dd.save_data(trained, dk.pair, dk)
+
+ owner.live = False
+ current = copy.copy(dk)
+ current.live = False
+ current.data_path = Path(temp) / "continued"
+ current.data_path.mkdir()
+ restored, pipeline = owner._resolve_deployment_state(
+ current, dk.pair, as_of_ts=timestamp + 300
+ )
+ self.assertEqual(restored.device.type, "cpu")
+ self.assertTrue(
+ all(value.device.type == "cpu" for value in restored.policy.parameters())
+ )
+ self.assertEqual(restored.replay_buffer.device, restored.device)
+ sample = restored.replay_buffer.sample(1)
+ replay_tensors = (
+ sample.observations,
+ sample.actions,
+ sample.next_observations,
+ sample.dones,
+ sample.rewards,
+ )
+ self.assertTrue(all(value.device.type == "cpu" for value in replay_tensors))
+ action, _ = restored.predict(sample.observations.cpu().numpy(), deterministic=True)
+ self.assertTrue(restored.action_space.contains(action[0]))
+ previous_updates = restored._n_updates
+ previous_parameters = [
+ value.detach().cpu().numpy().copy() for value in restored.policy.parameters()
+ ]
+ owner.fit(
+ dk.data_dictionary,
+ current,
+ prices_train=dk.data_dictionary["train_prices"],
+ prices_test=dk.data_dictionary["test_prices"],
+ deployment_state=(restored, pipeline),
+ )
+ self.assertGreater(restored._n_updates, previous_updates)
+ self.assertEqual(restored.device.type, "cpu")
+ self.assertTrue(
+ any(
+ not np.array_equal(before, after.detach().cpu().numpy())
+ for before, after in zip(
+ previous_parameters, restored.policy.parameters(), strict=True
+ )
+ )
+ )
+
+ def test_backtest_continuation_binds_policy_pipeline_and_replay_to_the_artifact(self):
+ for algorithm in ("DQN", "QRDQN"):
+ with self.subTest(algorithm=algorithm), tempfile.TemporaryDirectory() as temp:
+
+ def deployment(algorithm, day, offset, seed, gamma, reward):
+ config = model_config(temp)
+ info = config["freqai"]
+ info["identifier"] = f"artifact-{algorithm}-{seed}"
+ info["continual_learning"] = True
+ info["rl_config"]["model_type"] = algorithm
+ info["model_training_parameters"] = {
+ "learning_starts": 0,
+ "buffer_size": 128,
+ "batch_size": 8,
+ "train_freq": 4,
+ "gradient_steps": 1,
+ "device": "cpu",
+ "seed": seed,
+ "gamma": gamma,
+ "policy_kwargs": {"net_arch": [8]},
+ }
+ owner = ReforceXY(config=config)
+ owner.live = True
+ owner.can_short = False
+ self.addCleanup(owner.close_envs)
+ values = np.arange(64)
+ frame = pd.DataFrame(
+ {
+ "date": pd.date_range(day, periods=64, freq="5min", tz="UTC"),
+ "%-feature": np.sin(values) + offset,
+ "&-action": np.zeros(64),
+ }
+ )
+ for column in ("open", "high", "low", "close"):
+ frame[f"%-raw_{column}"] = 100.0 + values * 0.1
+ dk = FreqaiDataKitchen(config, live=True, pair=PAIR)
+ timestamp = int((frame["date"].iloc[-1] + pd.Timedelta(minutes=5)).timestamp())
+ dk.set_paths(dk.pair, timestamp)
+ dk.set_new_model_names(dk.pair, timestamp)
+ dk.label_list = ["&-action"]
+ dk.training_features_list = [c for c in frame if c.startswith("%")]
+ model = owner.train(frame, dk.pair, dk)
+ observation = np.full(
+ (model.n_envs, *model.observation_space.shape),
+ 0.125,
+ dtype=np.float32,
+ )
+ model.replay_buffer.add(
+ observation,
+ observation + 0.125,
+ np.zeros((model.n_envs, 1), dtype=np.int64),
+ np.full(model.n_envs, reward),
+ np.zeros(model.n_envs, dtype=bool),
+ [{} for _ in range(model.n_envs)],
+ )
+ owner.dd.get_pair_dict_info(dk.pair)
+ owner.dd.pair_dict[dk.pair]["trained_timestamp"] = timestamp
+ owner.dd.save_data(model, dk.pair, dk)
+ return owner, dk, model, frame
+
+ owner, saved, model, frame = deployment(
+ algorithm, "2026-01-01", 0.0, 42, 0.95, 17.0
+ )
+ future, future_dk, future_model, _ = deployment(
+ algorithm, "2026-02-01", 1000.0, 43, 0.8, 29.0
+ )
+ pair = saved.pair
+ saved_cache = owner.dd.meta_data_dictionary[pair]
+ future_cache = future.dd.meta_data_dictionary[pair]
+ probe = frame[saved.training_features_list]
+ expected_features = saved.feature_pipeline.transform(probe)[0]
+ self.assertFalse(
+ np.allclose(
+ expected_features, future_cache[FEATURE_PIPELINE].transform(probe)[0]
+ )
+ )
+ expected_policy = {
+ name: value.detach().cpu().numpy().copy()
+ for name, value in model.policy.state_dict().items()
+ }
+ size = model.replay_buffer.size()
+ expected_replay = {
+ name: getattr(model.replay_buffer, name)[:size].copy()
+ for name in ("observations", "next_observations", "actions", "rewards", "dones")
+ }
+ cached_empty = owner.MODELCLASS.load(
+ future_dk.data_path / f"{future_dk.model_filename}_model"
+ )
+ self.assertEqual(cached_empty.replay_buffer.size(), 0)
+ cached_old = owner.MODELCLASS.load(
+ saved.data_path / f"{saved.model_filename}_model"
+ )
+ cached_old.replay_buffer = copy.deepcopy(future_model.replay_buffer)
+ owner.live = False
+ current_config = {
+ **owner.config,
+ "runmode": RunMode.BACKTEST,
+ "timerange": "20260101-20260105",
+ "config_files": [str(PROJECT_ROOT / "user_data" / "config-template.json")],
+ }
+ current = FreqaiDataKitchen(current_config, live=False, pair=pair)
+ current.training_features_list = saved.training_features_list.copy()
+ current.label_list = saved.label_list.copy()
+ cutoff = int(pd.Timestamp("2026-01-03", tz="UTC").timestamp())
+ owner.dd.pair_dict[pair]["trained_timestamp"] = future.dd.pair_dict[pair][
+ "trained_timestamp"
+ ]
+ previous = copy.deepcopy(owner.dd.pair_dict[pair])
+ for name, cached_model, cached in (
+ ("future", future_model, future_cache),
+ ("metadata_only", None, future_cache),
+ ("empty_replay", cached_empty, saved_cache),
+ ("future_replay", cached_old, saved_cache),
+ ):
+ with self.subTest(cache=name):
+ owner.dd.model_dictionary = (
+ {pair: cached_model} if cached_model is not None else {}
+ )
+ owner.dd.meta_data_dictionary = {pair: cached}
+ restored, pipeline = owner._resolve_deployment_state(
+ current, pair, as_of_ts=cutoff
+ )
+ self.assertEqual(restored.gamma, model.gamma)
+ for parameter, expected in expected_policy.items():
+ np.testing.assert_array_equal(
+ restored.policy.state_dict()[parameter].detach().cpu().numpy(),
+ expected,
+ )
+ np.testing.assert_allclose(pipeline.transform(probe)[0], expected_features)
+ self.assertEqual(restored.replay_buffer.size(), size)
+ self.assertEqual(restored.replay_buffer.pos, model.replay_buffer.pos)
+ self.assertEqual(restored.replay_buffer.device, restored.device)
+ for field, expected in expected_replay.items():
+ np.testing.assert_array_equal(
+ getattr(restored.replay_buffer, field)[:size], expected
+ )
+ self.assertEqual(owner.dd.pair_dict[pair], previous)
+ self.assertIs(owner.dd.meta_data_dictionary[pair], cached)
+ if cached_model is not None:
+ self.assertIs(owner.dd.model_dictionary[pair], cached_model)
+
+ owner.dd.model_dictionary = {pair: future_model}
+ owner.dd.meta_data_dictionary = {pair: future_cache}
+ (saved.data_path / saved.data["reforcexy_replay"]).unlink()
+ with self.assertRaises(DependencyException):
+ owner._resolve_deployment_state(current, pair, as_of_ts=cutoff)
+ self.assertIs(owner.dd.model_dictionary[pair], future_model)
+
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"
+ pair = PAIR
date = pd.Timestamp("2026-01-01", tz="UTC")
drawer.historic_predictions[pair] = pd.DataFrame(
{
)
def test_native_bootstrap_append_and_restart_provenance(self):
- pair = "BTC/USDT"
+ pair = PAIR
marker = "_freqai_strategies_produced"
with tempfile.TemporaryDirectory() as temp:
config = model_config(temp)
)
def test_native_schema_extension_and_restart_preserve_unknown_metadata(self):
- pair = "BTC/USDT"
+ pair = PAIR
marker = "_freqai_strategies_produced"
with tempfile.TemporaryDirectory() as temp:
config = model_config(temp)
self.assertEqual(dk.data["labels_mean"]["&-action"], 0.0)
def test_native_expiration_ignores_stale_production_and_resume_records_real_zero(self):
- pair = "BTC/USDT"
+ pair = PAIR
marker = "_freqai_strategies_produced"
with tempfile.TemporaryDirectory() as temp:
config = model_config(temp)
self.assertEqual(dk.data["labels_mean"]["&-action"], 2.0)
def test_partially_marked_history_restores_provable_observations(self):
- pair = "BTC/USDT"
+ pair = PAIR
marker = "_freqai_strategies_produced"
with tempfile.TemporaryDirectory() as temp:
config = model_config(temp)
self.assertNotIn(marker, dk.return_dataframe)
def test_duplicate_date_keeps_provable_observation_after_restart(self):
- pair = "BTC/USDT"
+ pair = PAIR
marker = "_freqai_strategies_produced"
date = pd.Timestamp("2026-01-01", tz="UTC")
for statuses, markers in (([1, 0], None), ([0, 0], [True, False])):
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"
+ pair = PAIR
history = pd.DataFrame(
{
"date_pred": pd.date_range("2026-01-01", periods=4, freq="5min", tz="UTC"),
self.assertEqual(dk.data["labels_mean"]["&-action"], 7.0)
def test_live_action_statistics_resume_persisted_observations(self):
- pair = "BTC/USDT"
+ pair = PAIR
dates = pd.date_range("2026-01-01", periods=4, freq="5min", tz="UTC")
history = pd.DataFrame(
{
model.frame_stacking = 2
model.get_state_info = lambda pair: (0.5, 0.0, 0)
policy = RecordingPolicy()
- dk = SimpleNamespace(pair="BTC/USDT", label_list=["&-action"], data_dictionary={})
+ dk = SimpleNamespace(pair=PAIR, label_list=["&-action"], data_dictionary={})
def predict(value, minute, valid=1):
dk.do_predict = np.array([valid])
"""Restore independent training copies of the deployed policy and feature pipeline."""
if not self.continual_learning:
return None
- model = self.dd.model_dictionary.get(pair)
+ model = self.dd.model_dictionary.get(pair) if self.live else None
cached_model = model
previous = self.dd.pair_dict.get(pair, {})
if model is None and not previous.get("model_filename"):
):
return None
try:
- cached = self.dd.meta_data_dictionary.get(pair, {})
+ cached = self.dd.meta_data_dictionary.get(pair, {}) if self.live else {}
metadata = cached.get(METADATA)
feature_pipeline = cached.get(FEATURE_PIPELINE)
prefix: Path | None = None
feature_pipeline = cloudpickle.load(fp)
if model is None:
assert prefix is not None
- model = self.MODELCLASS.load(Path(f"{prefix}_model"))
+ model = self.MODELCLASS.load(
+ Path(f"{prefix}_model"),
+ device=self.model_training_parameters.get("device", "auto"),
+ )
if not isinstance(model, self.MODELCLASS):
raise ValueError("persisted policy type differs from the configured model")
ReforceXY._resolve_discount_gamma({"gamma": getattr(model, "gamma", None)})
},
{
"endCharacter": 87,
- "endLine": 3242,
+ "endLine": 3257,
"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": 3242
+ "startLine": 3257
},
{
"endCharacter": 68,
- "endLine": 3243,
+ "endLine": 3258,
"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": 3243
+ "startLine": 3258
},
{
"endCharacter": 71,
- "endLine": 3252,
+ "endLine": 3267,
"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": 66,
- "startLine": 3252
+ "startLine": 3267
},
{
"endCharacter": 47,
- "endLine": 3255,
+ "endLine": 3270,
"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": 3255
+ "startLine": 3270
},
{
"endCharacter": 47,
- "endLine": 3255,
+ "endLine": 3270,
"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": 3255
+ "startLine": 3270
},
{
"endCharacter": 43,
- "endLine": 3256,
+ "endLine": 3271,
"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": 3256
+ "startLine": 3271
},
{
"endCharacter": 43,
- "endLine": 3256,
+ "endLine": 3271,
"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": 3256
+ "startLine": 3271
},
{
"endCharacter": 31,
- "endLine": 3277,
+ "endLine": 3292,
"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": 3277
+ "startLine": 3292
},
{
"endCharacter": 31,
- "endLine": 3277,
+ "endLine": 3292,
"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": 3277
+ "startLine": 3292
},
{
"endCharacter": 60,
- "endLine": 3277,
+ "endLine": 3292,
"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": 3277
+ "startLine": 3292
},
{
"endCharacter": 60,
- "endLine": 3277,
+ "endLine": 3292,
"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": 3277
+ "startLine": 3292
},
{
"endCharacter": 73,
- "endLine": 3289,
+ "endLine": 3304,
"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": 3289
+ "startLine": 3304
},
{
"endCharacter": 73,
- "endLine": 3289,
+ "endLine": 3304,
"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": 3289
+ "startLine": 3304
},
{
"endCharacter": 83,
- "endLine": 3290,
+ "endLine": 3305,
"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": 3290
+ "startLine": 3305
},
{
"endCharacter": 83,
- "endLine": 3290,
+ "endLine": 3305,
"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": 3290
+ "startLine": 3305
},
{
"endCharacter": 46,
- "endLine": 3525,
+ "endLine": 3540,
"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": 3525
+ "startLine": 3540
},
{
"endCharacter": 46,
- "endLine": 3525,
+ "endLine": 3540,
"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": 3525
+ "startLine": 3540
},
{
"endCharacter": 46,
- "endLine": 3525,
+ "endLine": 3540,
"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": 3525
+ "startLine": 3540
},
{
"endCharacter": 46,
- "endLine": 3525,
+ "endLine": 3540,
"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": 3525
+ "startLine": 3540
},
{
"endCharacter": 46,
- "endLine": 3525,
+ "endLine": 3540,
"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": 3525
+ "startLine": 3540
},
{
"endCharacter": 46,
- "endLine": 3525,
+ "endLine": 3540,
"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": 3525
+ "startLine": 3540
},
{
"endCharacter": 46,
- "endLine": 3525,
+ "endLine": 3540,
"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": 3525
+ "startLine": 3540
},
{
"endCharacter": 41,
- "endLine": 3532,
+ "endLine": 3547,
"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": 3532
+ "startLine": 3547
},
{
"endCharacter": 39,
- "endLine": 3581,
+ "endLine": 3596,
"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": 3581
+ "startLine": 3596
},
{
"endCharacter": 19,
- "endLine": 3691,
+ "endLine": 3706,
"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": 3691
+ "startLine": 3706
},
{
"endCharacter": 21,
- "endLine": 3802,
+ "endLine": 3817,
"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": 3802
+ "startLine": 3817
},
{
"endCharacter": 21,
- "endLine": 3803,
+ "endLine": 3818,
"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": 3803
+ "startLine": 3818
},
{
"endCharacter": 33,
- "endLine": 3804,
+ "endLine": 3819,
"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": 3804
+ "startLine": 3819
},
{
"endCharacter": 32,
- "endLine": 3805,
+ "endLine": 3820,
"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": 3805
+ "startLine": 3820
},
{
"endCharacter": 32,
- "endLine": 3806,
+ "endLine": 3821,
"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": 3806
+ "startLine": 3821
},
{
"endCharacter": 38,
- "endLine": 3807,
+ "endLine": 3822,
"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": 3807
+ "startLine": 3822
},
{
"endCharacter": 24,
- "endLine": 3828,
+ "endLine": 3843,
"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": 3828
+ "startLine": 3843
},
{
"endCharacter": 24,
- "endLine": 3829,
+ "endLine": 3844,
"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": 3829
+ "startLine": 3844
},
{
"endCharacter": 30,
- "endLine": 3830,
+ "endLine": 3845,
"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": 3830
+ "startLine": 3845
},
{
"endCharacter": 15,
- "endLine": 3836,
+ "endLine": 3851,
"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": 3836
+ "startLine": 3851
},
{
"endCharacter": 15,
- "endLine": 3837,
+ "endLine": 3852,
"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": 3837
+ "startLine": 3852
},
{
"endCharacter": 39,
- "endLine": 3838,
+ "endLine": 3853,
"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": 3838
+ "startLine": 3853
},
{
"endCharacter": 38,
- "endLine": 3848,
+ "endLine": 3863,
"file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
"message": "\"columns\" is not a known attribute of \"None\"",
"rule": "reportOptionalMemberAccess",
"severity": "error",
"startCharacter": 31,
- "startLine": 3848
+ "startLine": 3863
},
{
"endCharacter": 34,
- "endLine": 3849,
+ "endLine": 3864,
"file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
"message": "\"index\" is not a known attribute of \"None\"",
"rule": "reportOptionalMemberAccess",
"severity": "error",
"startCharacter": 29,
- "startLine": 3849
+ "startLine": 3864
},
{
"endCharacter": 82,
- "endLine": 3851,
+ "endLine": 3866,
"file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
"message": "\"copy\" is not a known attribute of \"None\"",
"rule": "reportOptionalMemberAccess",
"severity": "error",
"startCharacter": 78,
- "startLine": 3851
+ "startLine": 3866
},
{
"endCharacter": 62,
- "endLine": 4271,
+ "endLine": 4286,
"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": 4271
+ "startLine": 4286
},
{
"endCharacter": 68,
- "endLine": 4652,
+ "endLine": 4667,
"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": 4648
+ "startLine": 4663
},
{
"endCharacter": 13,
- "endLine": 4681,
+ "endLine": 4696,
"file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
"message": "No overloads for \"cdist\" match the provided arguments",
"rule": "reportCallIssue",
"severity": "error",
"startCharacter": 19,
- "startLine": 4676
+ "startLine": 4691
},
{
"endCharacter": 38,
- "endLine": 4679,
+ "endLine": 4694,
"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": 4679
+ "startLine": 4694
},
{
"endCharacter": 9,
- "endLine": 4784,
+ "endLine": 4799,
"file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
"message": "No overloads for \"pdist\" match the provided arguments",
"rule": "reportCallIssue",
"severity": "error",
"startCharacter": 36,
- "startLine": 4782
+ "startLine": 4797
},
{
"endCharacter": 42,
- "endLine": 4783,
+ "endLine": 4798,
"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": 4783
+ "startLine": 4798
},
{
"endCharacter": 9,
- "endLine": 4861,
+ "endLine": 4876,
"file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
"message": "No overloads for \"cdist\" match the provided arguments",
"rule": "reportCallIssue",
"severity": "error",
"startCharacter": 15,
- "startLine": 4856
+ "startLine": 4871
},
{
"endCharacter": 34,
- "endLine": 4859,
+ "endLine": 4874,
"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": 4859
+ "startLine": 4874
},
{
"endCharacter": 99,
- "endLine": 5050,
+ "endLine": 5065,
"file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
"message": "No overloads for \"pdist\" match the provided arguments",
"rule": "reportCallIssue",
"severity": "error",
"startCharacter": 12,
- "startLine": 5050
+ "startLine": 5065
},
{
"endCharacter": 79,
- "endLine": 5050,
+ "endLine": 5065,
"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": 5050
+ "startLine": 5065
},
{
"endCharacter": 55,
## Continual learning
In backtests, continual training uses only a saved model whose training cutoff
-precedes the current window's end and its last available candle boundary. A
-later model left under the same identifier is not reused when a backtest is
-extended into the past. Live and dry-run restarts still restore compatible
-deployed models.
+precedes the current window's end and its last available candle boundary. The
+model and both fitted pipelines are restored from that saved artifact; missing
+or incompatible required files prevent continuation. A later model left under
+the same identifier is not reused when a backtest is extended into the past.
+Live and dry-run restarts still restore compatible deployed models.
## Backtest cache reuse
"""Runtime contracts for FreqAI's native QuickAdapter prediction history.; requires the Freqtrade QA image."""
+import copy
import unittest
from types import SimpleNamespace
from unittest import mock
import numpy as np
import pandas as pd
from freqtrade.enums import RunMode
+from freqtrade.exceptions import DependencyException
from freqtrade.exchange import timeframe_to_seconds
+from freqtrade.freqai.data_drawer import FEATURE_PIPELINE, LABEL_PIPELINE, METADATA
from freqtrade.freqai.data_kitchen import FreqaiDataKitchen
from qa_support import CONFIG_TEMPLATE, PAIR, QaTestCase, model_config, temporary_directory
else:
backtest.dd.save_metadata(dk)
+ def test_backtest_continuation_loads_the_validated_artifact_despite_future_caches(self):
+ with temporary_directory() as temp:
+
+ def deployment(day, offset, amplitude, estimators):
+ config = model_config(
+ temp,
+ freqai={
+ "identifier": f"artifact-{estimators}",
+ "optuna_hyperopt": {"enabled": False},
+ "model_training_parameters": {"n_estimators": estimators},
+ },
+ )
+ values = np.arange(48)
+ frame = pd.DataFrame(
+ {
+ "date": pd.date_range(day, periods=48, freq="5min", tz="UTC"),
+ "%-feature": np.sin(values / 4) + offset,
+ "&s-extrema": amplitude * np.cos(values / 5),
+ }
+ )
+ owner = QuickAdapterRegressorV3(config=config)
+ owner.live = True
+ dk = FreqaiDataKitchen(config, live=True, pair=PAIR)
+ timestamp = int((frame["date"].iloc[-1] + pd.Timedelta(minutes=5)).timestamp())
+ dk.set_paths(PAIR, timestamp)
+ dk.set_new_model_names(PAIR, timestamp)
+ dk.training_features_list = ["%-feature"]
+ dk.label_list = ["&s-extrema"]
+ model = owner.train(frame, PAIR, dk)
+ owner.dd.get_pair_dict_info(PAIR)
+ owner.dd.pair_dict[PAIR]["trained_timestamp"] = timestamp
+ owner.dd.save_data(model, PAIR, dk)
+ return owner, dk, model, frame
+
+ owner, saved, model, frame = deployment("2026-01-01", 0.0, 1.0, 2)
+ future, _, future_model, _ = deployment("2026-02-01", 1000.0, 10.0, 5)
+ cached = future.dd.meta_data_dictionary[PAIR]
+ probe = frame[["%-feature"]]
+ labels = frame[["&s-extrema"]]
+ expected_features = saved.feature_pipeline.transform(probe)[0]
+ expected_labels = saved.label_pipeline.transform(labels)[0]
+ expected_predictions = model.predict(expected_features)
+ self.assertFalse(
+ np.allclose(expected_predictions, future_model.predict(expected_features))
+ )
+ self.assertFalse(
+ np.allclose(expected_features, cached[FEATURE_PIPELINE].transform(probe)[0])
+ )
+ self.assertFalse(
+ np.allclose(expected_labels, cached[LABEL_PIPELINE].transform(labels)[0])
+ )
+
+ owner.live = False
+ current_config = {
+ **owner.config,
+ "runmode": RunMode.BACKTEST,
+ "timerange": "20260101-20260105",
+ "config_files": [str(CONFIG_TEMPLATE)],
+ }
+ current = FreqaiDataKitchen(current_config, live=False, pair=PAIR)
+ current.training_features_list = ["%-feature"]
+ current.label_list = ["&s-extrema"]
+ cutoff = int(pd.Timestamp("2026-01-03", tz="UTC").timestamp())
+ # A metadata-only window may advance this timestamp, not the saved filename.
+ owner.dd.pair_dict[PAIR]["trained_timestamp"] = future.dd.pair_dict[PAIR][
+ "trained_timestamp"
+ ]
+ previous = copy.deepcopy(owner.dd.pair_dict[PAIR])
+ for model_cached, metadata_cached in ((True, True), (False, True), (True, False)):
+ with self.subTest(model_cached=model_cached, metadata_cached=metadata_cached):
+ owner.dd.model_dictionary = {PAIR: future_model} if model_cached else {}
+ owner.dd.meta_data_dictionary = {PAIR: cached} if metadata_cached else {}
+ restored, features, label_pipeline = owner._resolve_deployment_state(
+ current, PAIR, as_of_ts=cutoff
+ )
+ np.testing.assert_array_equal(
+ restored.predict(expected_features), expected_predictions
+ )
+ np.testing.assert_allclose(features.transform(probe)[0], expected_features)
+ np.testing.assert_allclose(label_pipeline.transform(labels)[0], expected_labels)
+ self.assertEqual(owner.dd.pair_dict[PAIR], previous)
+ if model_cached:
+ self.assertIs(owner.dd.model_dictionary[PAIR], future_model)
+ if metadata_cached:
+ self.assertIs(owner.dd.meta_data_dictionary[PAIR], cached)
+
+ owner.dd.model_dictionary = {PAIR: future_model}
+ owner.dd.meta_data_dictionary = {PAIR: cached}
+ (saved.data_path / f"{saved.model_filename}_model.joblib").unlink()
+ with self.assertRaises(DependencyException):
+ owner._resolve_deployment_state(current, PAIR, as_of_ts=cutoff)
+ self.assertIs(owner.dd.model_dictionary[PAIR], future_model)
+ self.assertIs(owner.dd.meta_data_dictionary[PAIR][METADATA], cached[METADATA])
+
if __name__ == "__main__":
unittest.main()
@wraps(load)
def loaded(drawer: FreqaiDataDrawer, coin: str, kitchen: FreqaiDataKitchen) -> Any:
- # A backtest window must not inherit another window's cached metadata.
- if not kitchen.live:
- drawer.meta_data_dictionary.pop(coin, None)
- drawer.model_dictionary.pop(coin, None)
- model = load(coin, kitchen)
+ model = (
+ load(coin, kitchen)
+ if kitchen.live
+ else self._load_deployment_artifact(drawer, coin, kitchen)
+ )
if model is not None and not kitchen.live:
drawer.model_dictionary[coin] = model
drawer.meta_data_dictionary[coin] = {
label_weighting_config=label_weighting_config,
)
+ @staticmethod
+ def _load_deployment_artifact(
+ drawer: FreqaiDataDrawer, pair: str, dk: FreqaiDataKitchen
+ ) -> Any:
+ """Load native artifact files without consulting or evicting shared caches."""
+ artifact_drawer = copy.copy(drawer)
+ artifact_drawer.model_dictionary = {}
+ artifact_drawer.meta_data_dictionary = {}
+ # Instance hooks can close over the original drawer and its mutable caches.
+ return FreqaiDataDrawer.load_data(artifact_drawer, pair, dk)
+
def _resolve_deployment_state(
self, dk: FreqaiDataKitchen, pair: str, *, as_of_ts: int | None = None
) -> tuple[Any, Pipeline, Pipeline] | None:
else:
return None
- model = self.dd.model_dictionary.get(pair)
+ model = self.dd.model_dictionary.get(pair) if self.live else None
previous = self.dd.pair_dict.get(pair, {})
if (
not self.live
):
return None
try:
- cached = self.dd.meta_data_dictionary.get(pair)
+ cached = self.dd.meta_data_dictionary.get(pair) if self.live else None
if model is not None and cached is not None:
metadata = cached[METADATA]
feature_pipeline = cached[FEATURE_PIPELINE]
previous_dk = copy.copy(dk)
previous_dk.data_path = Path(previous["data_path"])
previous_dk.model_filename = previous["model_filename"]
- model = self.dd.load_data(pair, previous_dk)
+ if self.live:
+ model = self.dd.load_data(pair, previous_dk)
+ else:
+ previous_dk.live = False
+ model = self._load_deployment_artifact(self.dd, pair, previous_dk)
metadata = previous_dk.data
feature_pipeline = previous_dk.feature_pipeline
label_pipeline = previous_dk.label_pipeline