Resolve RL environment fees for the trained pair without RPC pairlists and invalidate incompatible HPO objective state. Bind native result reuse to model, helper and runtime identity using synchronized standalone helpers. Preserve native startup and archived replay boundaries; document and verify the contracts.
docker run --rm \
--mount "type=bind,src=${GITHUB_WORKSPACE},dst=/workspace,readonly" \
--workdir /workspace \
+ --env PYTHONPATH=/workspace/ReforceXY/user_data/strategies \
--env FREQAI_QA_SHUFFLE_SEED=1 \
--entrypoint python \
"${{ matrix.image }}" \
read from the template, not duplicated in the tests.
Both coverage commands need the same explicit configuration and data path; the
-runner propagates test and coverage-report failures. QuickAdapter needs the
-strategy path for bare-name imports; it is optional for ReforceXY.
+runner propagates test and coverage-report failures. Include each strategy's
+`user_data/strategies` on `PYTHONPATH` for its standalone helper imports.
For a focused debug run without coverage, use `python -m unittest discover` with
the same suite path and an exact `module.Class.method` pattern, for example
Import guards require one registration per resolved production file. QuickAdapter
strategy modules use bare names and its model uses a dotted name; ReforceXY uses
-dotted production names. Test modules use bare stems in both suites. QA config
-builders preserve explicit run modes, user directories and nested overrides;
+dotted model/strategy names and the shared standalone `BacktestIdentity` bare name.
+Test modules use bare stems in both suites. QA config builders preserve explicit
+run modes, user directories and nested overrides;
fixtures exercising futures behavior must request futures explicitly.
## Quality checks
},
{
"endCharacter": 22,
- "endLine": 1160,
+ "endLine": 1180,
"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[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,
- "startLine": 1160
+ "startLine": 1180
},
{
"endCharacter": 37,
- "endLine": 1160,
+ "endLine": 1180,
"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[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,
- "startLine": 1160
+ "startLine": 1180
},
{
"endCharacter": 24,
- "endLine": 1422,
+ "endLine": 1442,
"file": "ReforceXY/user_data/freqaimodels/ReforceXY.py",
"message": "Argument of type \"VecEnv\" cannot be assigned to parameter \"eval_env\" of type \"BaseEnvironment\" in function \"__init__\"\n \"VecEnv\" is not assignable to \"BaseEnvironment\"",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 16,
- "startLine": 1422
+ "startLine": 1442
},
{
"endCharacter": 38,
- "endLine": 1658,
+ "endLine": 1678,
"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": 1658
+ "startLine": 1678
},
{
"endCharacter": 36,
- "endLine": 1662,
+ "endLine": 1682,
"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": 1662
+ "startLine": 1682
},
{
"endCharacter": 80,
- "endLine": 1665,
+ "endLine": 1685,
"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": 1665
+ "startLine": 1685
},
{
"endCharacter": 78,
- "endLine": 1666,
+ "endLine": 1686,
"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": 1666
+ "startLine": 1686
},
{
"endCharacter": 80,
- "endLine": 1667,
+ "endLine": 1687,
"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": 1667
+ "startLine": 1687
},
{
"endCharacter": 56,
- "endLine": 1751,
+ "endLine": 1771,
"file": "ReforceXY/user_data/freqaimodels/ReforceXY.py",
"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": 1751
+ "startLine": 1771
},
{
"endCharacter": 84,
- "endLine": 1771,
+ "endLine": 1791,
"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": 1771
+ "startLine": 1791
},
{
"endCharacter": 84,
- "endLine": 1771,
+ "endLine": 1791,
"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": 1771
+ "startLine": 1791
},
{
"endCharacter": 44,
- "endLine": 2849,
+ "endLine": 2869,
"file": "ReforceXY/user_data/freqaimodels/ReforceXY.py",
"message": "\"best_trial_params\" is possibly unbound",
"rule": "reportPossiblyUnboundVariable",
"severity": "error",
"startCharacter": 27,
- "startLine": 2849
+ "startLine": 2869
},
{
"endCharacter": 12,
- "endLine": 2869,
+ "endLine": 2889,
"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": 2869
+ "startLine": 2889
},
{
"endCharacter": 16,
- "endLine": 2870,
+ "endLine": 2890,
"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": 2870
+ "startLine": 2890
},
{
"endCharacter": 51,
- "endLine": 2915,
+ "endLine": 2935,
"file": "ReforceXY/user_data/freqaimodels/ReforceXY.py",
"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": 2915
+ "startLine": 2935
},
{
"endCharacter": 53,
- "endLine": 2921,
+ "endLine": 2941,
"file": "ReforceXY/user_data/freqaimodels/ReforceXY.py",
"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": 2921
+ "startLine": 2941
},
{
"endCharacter": 22,
- "endLine": 2984,
+ "endLine": 3004,
"file": "ReforceXY/user_data/freqaimodels/ReforceXY.py",
"message": "Operator \"*\" not supported for \"None\"",
"rule": "reportOptionalOperand",
"severity": "error",
"startCharacter": 15,
- "startLine": 2984
+ "startLine": 3004
},
{
"endCharacter": 96,
- "endLine": 2986,
+ "endLine": 3006,
"file": "ReforceXY/user_data/freqaimodels/ReforceXY.py",
"message": "Operator \"*\" not supported for \"None\"",
"rule": "reportOptionalOperand",
"severity": "error",
"startCharacter": 89,
- "startLine": 2986
+ "startLine": 3006
},
{
"endCharacter": 23,
- "endLine": 2989,
+ "endLine": 3009,
"file": "ReforceXY/user_data/freqaimodels/ReforceXY.py",
"message": "Operator \"*\" not supported for \"None\"",
"rule": "reportOptionalOperand",
"severity": "error",
"startCharacter": 16,
- "startLine": 2989
+ "startLine": 3009
},
{
"endCharacter": 98,
- "endLine": 2991,
+ "endLine": 3011,
"file": "ReforceXY/user_data/freqaimodels/ReforceXY.py",
"message": "Operator \"*\" not supported for \"None\"",
"rule": "reportOptionalOperand",
"severity": "error",
"startCharacter": 91,
- "startLine": 2991
+ "startLine": 3011
},
{
"endCharacter": 44,
- "endLine": 3003,
+ "endLine": 3023,
"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": 3003
+ "startLine": 3023
},
{
"endCharacter": 133,
- "endLine": 3005,
+ "endLine": 3025,
"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": 3005
+ "startLine": 3025
},
{
"endCharacter": 30,
- "endLine": 3008,
+ "endLine": 3028,
"file": "ReforceXY/user_data/freqaimodels/ReforceXY.py",
"message": "Operator \">\" not supported for \"None\"",
"rule": "reportOptionalOperand",
"severity": "error",
"startCharacter": 15,
- "startLine": 3008
+ "startLine": 3028
},
{
"endCharacter": 54,
- "endLine": 3074,
+ "endLine": 3094,
"file": "ReforceXY/user_data/freqaimodels/ReforceXY.py",
"message": "\"is_pruned\" is not a known attribute of \"None\"",
"rule": "reportOptionalMemberAccess",
"severity": "error",
"startCharacter": 45,
- "startLine": 3074
+ "startLine": 3094
},
{
"endCharacter": 67,
- "endLine": 3077,
+ "endLine": 3097,
"file": "ReforceXY/user_data/freqaimodels/ReforceXY.py",
"message": "\"use_masking\" is not a known attribute of \"None\"",
"rule": "reportOptionalMemberAccess",
"severity": "error",
"startCharacter": 56,
- "startLine": 3077
+ "startLine": 3097
},
{
"endCharacter": 60,
- "endLine": 3085,
+ "endLine": 3105,
"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": 3085
+ "startLine": 3105
},
{
"endCharacter": 84,
- "endLine": 3085,
+ "endLine": 3105,
"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": 3085
+ "startLine": 3105
},
{
"endCharacter": 84,
- "endLine": 3085,
+ "endLine": 3105,
"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": 3085
+ "startLine": 3105
},
{
"endCharacter": 46,
- "endLine": 3139,
+ "endLine": 3159,
"file": "ReforceXY/user_data/freqaimodels/ReforceXY.py",
"message": "\"is_pruned\" is not a known attribute of \"None\"",
"rule": "reportOptionalMemberAccess",
"severity": "error",
"startCharacter": 37,
- "startLine": 3139
+ "startLine": 3159
},
{
"endCharacter": 57,
- "endLine": 3142,
+ "endLine": 3162,
"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": 3142
+ "startLine": 3162
},
{
"endCharacter": 37,
- "endLine": 3152,
+ "endLine": 3172,
"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[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": 3152
+ "startLine": 3172
},
{
"endCharacter": 36,
- "endLine": 3157,
+ "endLine": 3177,
"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[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": 3157
+ "startLine": 3177
},
{
"endCharacter": 7,
- "endLine": 3202,
+ "endLine": 3222,
"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": 3202
+ "startLine": 3222
},
{
"endCharacter": 36,
- "endLine": 3214,
+ "endLine": 3234,
"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": 3214
+ "startLine": 3234
},
{
"endCharacter": 13,
- "endLine": 3806,
+ "endLine": 3826,
"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": 3806
+ "startLine": 3826
},
{
"endCharacter": 26,
- "endLine": 3827,
+ "endLine": 3847,
"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": 3827
+ "startLine": 3847
},
{
"endCharacter": 55,
- "endLine": 4132,
+ "endLine": 4152,
"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": 4132
+ "startLine": 4152
},
{
"endCharacter": 55,
- "endLine": 4132,
+ "endLine": 4152,
"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": 4132
+ "startLine": 4152
},
{
"endCharacter": 59,
- "endLine": 4156,
+ "endLine": 4176,
"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": 4156
+ "startLine": 4176
},
{
"endCharacter": 59,
- "endLine": 4156,
+ "endLine": 4176,
"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": 4156
+ "startLine": 4176
},
{
"endCharacter": 24,
- "endLine": 4185,
+ "endLine": 4205,
"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": 4185
+ "startLine": 4205
},
{
"endCharacter": 12,
- "endLine": 4278,
+ "endLine": 4298,
"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": 4278
+ "startLine": 4298
},
{
"endCharacter": 20,
- "endLine": 4473,
+ "endLine": 4493,
"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": 4473
+ "startLine": 4493
},
{
"endCharacter": 40,
- "endLine": 4622,
+ "endLine": 4642,
"file": "ReforceXY/user_data/freqaimodels/ReforceXY.py",
"message": "\"Figure\" is not exported from module \"matplotlib.pyplot\"",
"rule": "reportPrivateImportUsage",
"severity": "error",
"startCharacter": 34,
- "startLine": 4622
+ "startLine": 4642
},
{
"endCharacter": 54,
- "endLine": 5107,
+ "endLine": 5127,
"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": 5107
+ "startLine": 5127
},
{
"endCharacter": 54,
- "endLine": 5107,
+ "endLine": 5127,
"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": 5107
+ "startLine": 5127
},
{
"endCharacter": 50,
- "endLine": 5119,
+ "endLine": 5139,
"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": 5119
+ "startLine": 5139
},
{
"endCharacter": 72,
- "endLine": 5130,
+ "endLine": 5150,
"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": 5130
+ "startLine": 5150
},
{
"endCharacter": 72,
- "endLine": 5130,
+ "endLine": 5150,
"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": 5130
+ "startLine": 5150
},
{
"endCharacter": 73,
- "endLine": 5139,
+ "endLine": 5159,
"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": 5139
+ "startLine": 5159
},
{
"endCharacter": 73,
- "endLine": 5139,
+ "endLine": 5159,
"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": 5139
+ "startLine": 5159
},
{
"endCharacter": 58,
- "endLine": 5148,
+ "endLine": 5168,
"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": 5148
+ "startLine": 5168
},
{
"endCharacter": 58,
- "endLine": 5148,
+ "endLine": 5168,
"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": 5148
+ "startLine": 5168
},
{
"endCharacter": 50,
- "endLine": 5379,
+ "endLine": 5399,
"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": 5379
+ "startLine": 5399
},
{
"endCharacter": 20,
- "endLine": 5538,
+ "endLine": 5558,
"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": 5538
+ "startLine": 5558
},
{
"endCharacter": 20,
- "endLine": 5538,
+ "endLine": 5558,
"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": 5538
+ "startLine": 5558
},
{
"endCharacter": 59,
- "endLine": 5543,
+ "endLine": 5563,
"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": 5543
+ "startLine": 5563
},
{
"endCharacter": 59,
- "endLine": 5543,
+ "endLine": 5563,
"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": 5543
+ "startLine": 5563
},
{
"endCharacter": 65,
- "endLine": 5544,
+ "endLine": 5564,
"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": 5544
+ "startLine": 5564
},
{
"endCharacter": 65,
- "endLine": 5544,
+ "endLine": 5564,
"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": 5544
+ "startLine": 5564
},
{
"endCharacter": 63,
- "endLine": 5547,
+ "endLine": 5567,
"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": 5547
+ "startLine": 5567
},
{
"endCharacter": 63,
- "endLine": 5547,
+ "endLine": 5567,
"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": 5547
+ "startLine": 5567
},
{
"endCharacter": 61,
- "endLine": 5549,
+ "endLine": 5569,
"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": 5549
+ "startLine": 5569
},
{
"endCharacter": 61,
- "endLine": 5549,
+ "endLine": 5569,
"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": 5549
+ "startLine": 5569
},
{
"endCharacter": 67,
- "endLine": 5550,
+ "endLine": 5570,
"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": 5550
+ "startLine": 5570
},
{
"endCharacter": 67,
- "endLine": 5550,
+ "endLine": 5570,
"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": 5550
+ "startLine": 5570
},
{
"endCharacter": 73,
- "endLine": 5551,
+ "endLine": 5571,
"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": 5551
+ "startLine": 5571
},
{
"endCharacter": 73,
- "endLine": 5551,
+ "endLine": 5571,
"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": 5551
+ "startLine": 5571
},
{
"endCharacter": 61,
- "endLine": 5552,
+ "endLine": 5572,
"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": 5552
+ "startLine": 5572
},
{
"endCharacter": 61,
- "endLine": 5552,
+ "endLine": 5572,
"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": 5552
+ "startLine": 5572
},
{
"endCharacter": 89,
- "endLine": 5559,
+ "endLine": 5579,
"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": 5559
+ "startLine": 5579
},
{
"endCharacter": 89,
- "endLine": 5559,
+ "endLine": 5579,
"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": 5559
+ "startLine": 5579
},
{
"endCharacter": 83,
- "endLine": 5560,
+ "endLine": 5580,
"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": 5560
+ "startLine": 5580
},
{
"endCharacter": 83,
- "endLine": 5560,
+ "endLine": 5580,
"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": 5560
+ "startLine": 5580
},
{
"endCharacter": 65,
- "endLine": 5586,
+ "endLine": 5606,
"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": 5586
+ "startLine": 5606
},
{
"endCharacter": 65,
- "endLine": 5586,
+ "endLine": 5606,
"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": 5586
+ "startLine": 5606
},
{
"endCharacter": 67,
- "endLine": 5588,
+ "endLine": 5608,
"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": 5588
+ "startLine": 5608
},
{
"endCharacter": 67,
- "endLine": 5588,
+ "endLine": 5608,
"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": 5588
+ "startLine": 5608
},
{
"endCharacter": 87,
- "endLine": 5591,
+ "endLine": 5611,
"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": 5591
+ "startLine": 5611
},
{
"endCharacter": 87,
- "endLine": 5591,
+ "endLine": 5611,
"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": 5591
+ "startLine": 5611
},
{
"endCharacter": 93,
- "endLine": 5592,
+ "endLine": 5612,
"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": 5592
+ "startLine": 5612
},
{
"endCharacter": 93,
- "endLine": 5592,
+ "endLine": 5612,
"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": 5592
+ "startLine": 5612
},
{
"endCharacter": 89,
- "endLine": 5593,
+ "endLine": 5613,
"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": 5593
+ "startLine": 5613
},
{
"endCharacter": 89,
- "endLine": 5593,
+ "endLine": 5613,
"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": 5593
+ "startLine": 5613
},
{
"endCharacter": 89,
- "endLine": 5594,
+ "endLine": 5614,
"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": 5594
+ "startLine": 5614
},
{
"endCharacter": 89,
- "endLine": 5594,
+ "endLine": 5614,
"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": 5594
+ "startLine": 5614
},
{
"endCharacter": 75,
- "endLine": 5595,
+ "endLine": 5615,
"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": 5595
+ "startLine": 5615
},
{
"endCharacter": 75,
- "endLine": 5595,
+ "endLine": 5615,
"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": 5595
+ "startLine": 5615
},
{
"endCharacter": 33,
- "endLine": 37,
+ "endLine": 40,
"file": "ReforceXY/user_data/strategies/RLAgentStrategy.py",
"message": "Argument of type \"Scalar\" cannot be assigned to parameter \"x\" of type \"ConvertibleToInt\" in function \"__new__\"\n Type \"Scalar\" is not assignable to type \"ConvertibleToInt\"\n Type \"complex\" is not assignable to type \"ConvertibleToInt\"\n \"complex\" is not assignable to \"str\"\n \"complex\" is incompatible with protocol \"Buffer\"\n \"__buffer__\" is not present\n \"complex\" is incompatible with protocol \"SupportsInt\"\n \"__int__\" is not present\n \"complex\" is incompatible with protocol \"SupportsIndex\"",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 20,
- "startLine": 37
+ "startLine": 40
},
{
"endCharacter": 33,
- "endLine": 37,
+ "endLine": 40,
"file": "ReforceXY/user_data/strategies/RLAgentStrategy.py",
"message": "Argument of type \"Scalar\" cannot be assigned to parameter \"x\" of type \"ConvertibleToInt\" in function \"__new__\"\n Type \"Scalar\" is not assignable to type \"ConvertibleToInt\"\n Type \"complex\" is not assignable to type \"ConvertibleToInt\"\n \"complex\" is not assignable to \"str\"\n \"complex\" is incompatible with protocol \"Buffer\"\n \"__buffer__\" is not present\n \"complex\" is incompatible with protocol \"SupportsInt\"\n \"__int__\" is not present\n \"complex\" is incompatible with protocol \"SupportsIndex\"\n ...",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 20,
- "startLine": 37
+ "startLine": 40
},
{
"endCharacter": 17,
- "endLine": 64,
+ "endLine": 76,
"file": "ReforceXY/user_data/strategies/RLAgentStrategy.py",
"message": "\"can_short\" overrides symbol of same name in class \"IStrategy\"\n \"property\" is not assignable to \"bool\"",
"rule": "reportIncompatibleVariableOverride",
"severity": "error",
"startCharacter": 8,
- "startLine": 64
+ "startLine": 76
},
{
"endCharacter": 19,
- "endLine": 68,
+ "endLine": 80,
"file": "ReforceXY/user_data/strategies/RLAgentStrategy.py",
"message": "\"protections\" overrides symbol of same name in class \"IStrategy\"\n \"property\" is not assignable to \"list[Unknown]\"",
"rule": "reportIncompatibleVariableOverride",
"severity": "error",
"startCharacter": 8,
- "startLine": 68
+ "startLine": 80
}
],
- "filesAnalyzed": 3,
+ "filesAnalyzed": 4,
"schemaVersion": 4,
"sourceFiles": [
"ReforceXY/reward_space_analysis/reward_space_analysis.py",
"ReforceXY/user_data/freqaimodels/ReforceXY.py",
+ "ReforceXY/user_data/strategies/BacktestIdentity.py",
"ReforceXY/user_data/strategies/RLAgentStrategy.py"
]
}
and remains supported for plain training, including with raw OHLC feature
removal.
+Training uses the top-level `fee` when configured, including `0`. Otherwise it
+uses the exchange's maker-fee estimate for the pair being trained, not the
+whitelist's first pair. This also works with chart-history providers without a
+pairlist. A provider without an exchange requires an explicit `fee`; exchange
+errors are not replaced with a synthetic fee.
+
`train_cycles` requests approximately training rows × cycles per HPO trial
and final fit; environment and algorithm update boundaries round the actual
budget. It is not an exact episode count. Trials are serialized (one Optuna
and the resumed learner's gamma, so a valid higher-priority value can supersede
an invalid base value. A persisted learner with missing or invalid gamma cannot
continue training. Learner and environment use the same effective discount.
-Incompatible reward-objective identities reset persisted HPO studies and cause
-stale best-parameter payloads to be ignored rather than warm-started.
+The per-pair fee correction changes the HPO objective identity. Existing studies
+reset, and saved best parameters from earlier objective identities are ignored
+rather than warm-started. Deployed policies are not deleted.
## Continual learning
splits; training disables `shuffle_after_split`, and the native RL base
disables row-removing SVM/DBSCAN/DI outlier removal to preserve trajectories.
+Native result-cache reuse checks implementation and runtime versions; see
+[backtest result caching](../docs/evaluation.md#backtest-result-caching).
+This does not reset saved policies or native FreqAI prediction caches. Keep
+separate identifiers when comparing configurations or training environments.
+
Archived strategy charts require the extracted `RLAgentStrategy` source, not a
fallback to the current strategy. They still use the current server's FreqAI
model and configuration; see [archived strategy charts](../docs/evaluation.md#archived-strategy-charts).
"""Native archived replay must not train against a substituted current strategy."""
+import builtins
import re
import unittest
from pathlib import Path
+from unittest import mock
import pandas as pd
from freqtrade.data.dataprovider import DataProvider
-from freqtrade.enums import TradingMode
+from freqtrade.enums import SignalDirection, TradingMode
from freqtrade.resolvers import StrategyResolver
from qa_support import QaTestCase, model_config, temporary_directory
-from ReforceXY.user_data.freqaimodels.ReforceXY import ReforceXY
+from ReforceXY.user_data.freqaimodels.ReforceXY import Actions, ReforceXY
from scripts.archive_replay_contract import HAS_ARCHIVED_STRATEGY_REPLAY, archived_strategy
STRATEGY_SOURCE = Path(__file__).resolve().parents[1] / "user_data/strategies/RLAgentStrategy.py"
@unittest.skipUnless(HAS_ARCHIVED_STRATEGY_REPLAY, "Native archived replay is unavailable")
class ArchiveReplayTest(QaTestCase):
+ def test_archived_strategy_remains_usable_without_cache_helper(self):
+ with temporary_directory() as directory:
+ config = model_config(
+ directory, strategy="RLAgentStrategy", trading_mode=TradingMode.SPOT
+ )
+ original_import = builtins.__import__
+
+ def without_cache_helper(name, *args, **kwargs):
+ if name == "BacktestIdentity":
+ raise ImportError("The standalone cache helper is not archived")
+ return original_import(name, *args, **kwargs)
+
+ with (
+ archived_strategy(config, STRATEGY_SOURCE) as (replay, source),
+ mock.patch("builtins.__import__", side_effect=without_cache_helper),
+ ):
+ strategy = StrategyResolver.load_strategy(replay)
+ self.assertEqual(Path(strategy.__file__).resolve(), source.resolve())
+ frame = pd.DataFrame(
+ {
+ "date": pd.date_range(
+ end=pd.Timestamp.now(tz="UTC"), periods=3, freq="5min"
+ ),
+ "close": 100.0,
+ "volume": 1.0,
+ "do_predict": 1,
+ "&-action": [0, 0, Actions.Long_enter.value],
+ }
+ )
+ signals = strategy.populate_entry_trend(frame, {"pair": "BTC/USDT"})
+ self.assertEqual(
+ strategy.get_entry_signal("BTC/USDT", "5m", signals),
+ (SignalDirection.LONG, "long"),
+ )
+
def test_current_strategy_fallback_cannot_start_training(self):
with temporary_directory() as directory:
current = directory / "strategies"
None,
"terminal-liquidation-risk-normalized-trained-policy-v3",
"terminal-liquidation-risk-normalized-trained-policy-v5",
+ "unshaped-evaluation-temporal-costs-trained-policy-v6",
):
with self.subTest(identity=identity):
model = self.model()
"objective_identity": "terminal-liquidation-risk-normalized-trained-policy-v5",
"params": {"gamma": 0.1},
},
+ {
+ "objective_identity": "unshaped-evaluation-temporal-costs-trained-policy-v6",
+ "params": {"gamma": 0.1},
+ },
{"objective_identity": ReforceXY._OPTUNA_OBJECTIVE_IDENTITY, "params": []},
):
with self.subTest(payload=payload):
import numpy as np
import pandas as pd
+from freqtrade.data.dataprovider import DataProvider
from freqtrade.enums import RunMode
-from freqtrade.exceptions import DependencyException
+from freqtrade.exceptions import DependencyException, OperationalException
from freqtrade.exchange import timeframe_to_seconds
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 PAIR, PROJECT_ROOT, QaTestCase, RecordingPolicy, model_config
-from ReforceXY.user_data.freqaimodels.ReforceXY import ReforceXY
+from ReforceXY.user_data.freqaimodels.ReforceXY import Actions, MyRLEnv, ReforceXY
class TrainingObservationsTest(QaTestCase):
+ def test_pairlist_free_training_costs_follow_each_pair_and_explicit_fee(self):
+ with tempfile.TemporaryDirectory() as temp:
+ config = model_config(temp)
+ model = ReforceXY(config=config)
+ model.live = True
+ model.can_short = True
+ self.addCleanup(model.close_envs)
+ rates = {"BTC/USDT": 0.001, "ETH/USDT:USDT": 0.003}
+
+ def get_fee(*, symbol):
+ if config.get("fee") is not None:
+ raise AssertionError("Explicit costs must not query the exchange")
+ return rates[symbol]
+
+ provider = DataProvider(
+ config, exchange=SimpleNamespace(get_fee=get_fee), pairlists=None
+ )
+ prices = pd.DataFrame({"open": [100.0] * 16})
+ for has_provider, explicit in (
+ (True, None),
+ (True, 0.0),
+ (True, 0.002),
+ (False, 0.0),
+ (False, 0.002),
+ ):
+ model.data_provider = provider if has_provider else None
+ config["fee"] = explicit
+ for pair, pair_fee in rates.items():
+ with self.subTest(provider=has_provider, explicit=explicit, pair=pair):
+ env = MyRLEnv(df=prices.copy(), prices=prices, **model.pack_env_dict(pair))
+ self.addCleanup(env.close)
+ env.reset()
+ env.step(Actions.Long_enter.value)
+ fee = pair_fee if explicit is None else explicit
+ expected = 1.0 / (1.0 + fee) ** 2 - 1.0
+ self.assertAlmostEqual(env.get_unrealized_profit(), expected)
+
+ def test_missing_exchange_requires_costs_and_preserves_exchange_errors(self):
+ with tempfile.TemporaryDirectory() as temp:
+ config = model_config(temp)
+ model = ReforceXY(config=config)
+ model.live = True
+ model.can_short = False
+ self.addCleanup(model.close_envs)
+ model.data_provider = DataProvider(config, exchange=None, pairlists=None)
+ with self.assertRaises(OperationalException) as raised:
+ model.pack_env_dict(PAIR)
+ self.assertIn(PAIR, str(raised.exception))
+ config["fee"] = 0.0
+ prices = pd.DataFrame({"open": [100.0] * 16})
+ env = MyRLEnv(df=prices.copy(), prices=prices, **model.pack_env_dict(PAIR))
+ self.addCleanup(env.close)
+ env.reset()
+ env.step(Actions.Long_enter.value)
+ self.assertEqual(env.get_unrealized_profit(), 0.0)
+ config["fee"] = None
+ error = OperationalException("exchange cost unavailable")
+
+ def fail_fee(**kwargs):
+ raise error
+
+ model.data_provider = DataProvider(
+ config, exchange=SimpleNamespace(get_fee=fail_fee), pairlists=None
+ )
+ with self.assertRaises(OperationalException) as raised:
+ model.pack_env_dict(PAIR)
+ self.assertIs(raised.exception, error)
+
def test_dqn_eligibility_restart_and_chronology(self):
for algorithm in ("DQN", "QRDQN"):
with self.subTest(algorithm=algorithm), tempfile.TemporaryDirectory() as temp:
--- /dev/null
+"""Native result-cache behavior across implementation and SDK changes."""
+
+from qa_support import REPO_ROOT, QaTestCase, model_config, temporary_directory
+
+from scripts.backtest_cache_contract import (
+ assert_native_implementation_cache,
+ assert_native_startup_predictions,
+)
+
+
+class NativeResultCacheTest(QaTestCase):
+ def test_native_startup_and_predictions_do_not_require_test_pythonpath(self):
+ with temporary_directory() as directory:
+ assert_native_startup_predictions(
+ self, directory, model_config, REPO_ROOT / "ReforceXY"
+ )
+
+ def test_implementation_changes_reject_results_but_unchanged_inputs_reuse_them(self):
+ with temporary_directory() as directory:
+ assert_native_implementation_cache(
+ self,
+ directory,
+ model_config,
+ "RLAgentStrategy",
+ REPO_ROOT / "ReforceXY",
+ "from ReforceXY.user_data.freqaimodels.ReforceXY import ReforceXY as CacheBase",
+ )
reseed,
)
-PRODUCTION_NAMES = (PRODUCTION_MODULE, STRATEGY_MODULE)
+PRODUCTION_NAMES = (PRODUCTION_MODULE, STRATEGY_MODULE, "BacktestIdentity")
# `ReforceXY/user_data` holds no `__init__.py`, so `ReforceXY`, `ReforceXY.user_data` and
# `ReforceXY.user_data.freqaimodels` are PEP 420 namespace packages carrying no `__file__`
# at all; `Path(None)` would raise instead of asserting, so every walk below filters on the
# left behind, not the state setUp already put back. It is the ONLY exemption from the
# inheritance rule below — not its module, which is why the guard names this class.
-# Imported here, at module scope, so the parity contract holds on its own: unittest discovery
-# imports every test module before running any test, so a lazy import inside a method would
-# make the assertion unconditionally true. Dotted paths only — CI puts `user_data/strategies`
-# on PYTHONPATH, so a bare-stem name would register a second module object for the very file
-# this contract pins.
+# Imported at module scope so the parity contract holds on its own: unittest
+# discovery imports every test module before running any test. Model and strategy
+# keep dotted identities; BacktestIdentity uses the bare native-resolution import.
for _name in PRODUCTION_NAMES:
importlib.import_module(_name)
"shadow copy carrying its own module state",
)
- def test_no_measured_file_is_registered_under_a_bare_stem(self):
+ def test_each_measured_file_uses_its_canonical_import_name(self):
expected = {
Path(importlib.import_module(name).__file__).resolve(): name
for name in PRODUCTION_NAMES
import torch as th
from datasieve.pipeline import Pipeline
from freqtrade.enums import RunMode
-from freqtrade.exceptions import DependencyException
+from freqtrade.exceptions import DependencyException, OperationalException
from freqtrade.exchange import timeframe_to_seconds
from freqtrade.freqai.data_drawer import (
FEATURE_PIPELINE,
_QUARANTINE_TIE_BREAK_LIMIT: Final[int] = 99
_BEST_PARAMS_LOCK_FILENAME: Final[str] = ".hyperopt-best-params.lock"
# Bump on objective changes that make persisted trials or best params incompatible.
- _OPTUNA_OBJECTIVE_IDENTITY: Final[str] = "unshaped-evaluation-temporal-costs-trained-policy-v6"
+ _OPTUNA_OBJECTIVE_IDENTITY: Final[str] = "unshaped-evaluation-temporal-costs-pair-fees-v7"
_PPO_N_STEPS: Final[tuple[int, ...]] = (512, 1024, 2048, 4096)
_PPO_N_STEPS_MIN: Final[int] = min(_PPO_N_STEPS)
_PPO_N_STEPS_MAX: Final[int] = max(_PPO_N_STEPS)
)
effective_params = self.get_model_params() if model_params is None else model_params
gamma = ReforceXY._resolve_discount_gamma(effective_params)
- env_info = super().pack_env_dict(pair)
+ # Native packing uses the whitelist's first pair, unavailable in RPC history.
+ # Keep the SDK environment contract but resolve costs for the training pair.
+ env_info: dict[str, Any] = {
+ "window_size": self.CONV_WIDTH,
+ "reward_kwargs": self.reward_params,
+ "config": self.config,
+ "live": self.live,
+ "can_short": self.can_short,
+ "pair": pair,
+ "df_raw": self.df_raw,
+ }
+ if self.config.get("fee") is not None:
+ env_info["fee"] = self.config["fee"]
+ elif self.data_provider is not None:
+ exchange = self.data_provider._exchange
+ if exchange is None:
+ raise OperationalException(
+ f"Env [{pair}]: resolving training fees requires an exchange "
+ "or an explicit configured fee"
+ )
+ env_info["fee"] = exchange.get_fee(symbol=pair)
# Each environment owns its effective parameters; do not mutate global config.
config = copy.deepcopy(env_info["config"])
env_info["config"] = config
--- /dev/null
+"""Implementation identity for native result and FreqAI prediction caches.
+
+Keep both standalone strategy copies identical. Native resolver search and class
+source metadata are private SDK contracts; recheck them on Freqtrade upgrades.
+"""
+
+import ast
+import json
+import platform
+import sys
+from collections.abc import Iterator, Mapping
+from hashlib import sha256
+from importlib.metadata import PackageNotFoundError, version
+from importlib.util import resolve_name
+from inspect import getfile, isfunction, unwrap
+from pathlib import Path
+from types import ModuleType
+from typing import Any, Final
+
+import freqtrade
+from freqtrade.exceptions import OperationalException
+from freqtrade.resolvers.freqaimodel_resolver import FreqaiModelResolver
+
+_IMPLEMENTATION_KEY: Final = "_freqai_strategies_implementation"
+_COMMON_DEPENDENCIES: Final = (
+ "freqtrade",
+ "datasieve",
+ "numpy",
+ "pandas",
+ "scipy",
+ "scikit-learn",
+ "optuna",
+ "optuna-integration",
+ "optunahub",
+ "cmaes",
+ "torch",
+ "botorch",
+ "gpytorch",
+ "filelock",
+ "joblib",
+ "cloudpickle",
+ "TA-Lib",
+ "technical",
+ "pandas-ta",
+)
+_REGRESSION_DEPENDENCIES: Final = ("xgboost", "lightgbm", "catboost", "ngboost", "scikit-image")
+_RL_DEPENDENCIES: Final = ("gymnasium", "stable-baselines3", "sb3-contrib")
+
+
+def _import_namespaces(source: bytes, package: str) -> Iterator[dict[str, Any]]:
+ """Find loaded imports even when a native-resolved leaf owns no methods."""
+ for node in ast.walk(ast.parse(source)):
+ if isinstance(node, ast.Import):
+ names = [alias.name for alias in node.names]
+ elif isinstance(node, ast.ImportFrom):
+ name = node.module or ""
+ if node.level:
+ if not package:
+ continue
+ try:
+ name = resolve_name("." * node.level + name, package)
+ except ImportError:
+ continue
+ names = [name, *(f"{name}.{alias.name}" for alias in node.names)]
+ else:
+ continue
+ for name in names:
+ module = sys.modules.get(name)
+ if module is not None:
+ yield vars(module)
+
+
+def _class_namespaces(cls: type) -> Iterator[dict[str, Any]]:
+ """Use actual function globals: native-resolved modules may be unregistered."""
+ for member in vars(cls).values():
+ if isinstance(member, (staticmethod, classmethod)):
+ member = member.__func__
+ elif isinstance(member, property):
+ member = member.fget
+ if callable(member):
+ member = unwrap(member)
+ if isfunction(member):
+ yield member.__globals__
+ module = sys.modules.get(cls.__module__)
+ # Data-only imported classes have no function globals. Reject name collisions.
+ if module is not None and vars(module).get(cls.__name__) is cls:
+ yield vars(module)
+
+
+def implementation_fingerprint(implementations: Mapping[str, type]) -> str:
+ """Hash selected classes, reachable local helpers and release dependencies.
+
+ Paths locate sources but are not part of identity. Resolver snapshots take
+ precedence over disk source. Local helper traversal stays inside directories
+ containing selected non-SDK MRO implementations; it never scans user data or
+ installed packages. Version metadata does not detect same-version SDK/binary
+ modifications. File hashes are not memoized across strategy constructions.
+ """
+ classes = {role: list(leaf.__mro__[:-1]) for role, leaf in implementations.items()}
+ local_classes = [
+ cls
+ for lineage in classes.values()
+ for cls in lineage
+ if cls.__module__ != "abc" and not cls.__module__.startswith("freqtrade.")
+ ]
+ sources: dict[tuple[str, bytes], None] = {}
+ source_cache: dict[tuple[str, str | Path], bytes] = {}
+ snapshots: dict[Path, str] = {}
+ imports: dict[tuple[bytes, str], tuple[dict[str, Any], ...]] = {}
+ directories: set[Path] = set()
+ namespaces: list[dict[str, Any]] = []
+
+ def add_source(path: str | Path, snapshot: str | None = None) -> bytes:
+ key = ("snapshot", snapshot) if snapshot is not None else ("file", Path(path).resolve())
+ if key not in source_cache:
+ source_cache[key] = (
+ snapshot.encode() if snapshot is not None else Path(path).read_bytes()
+ )
+ sources[(Path(path).name, source_cache[key])] = None
+ return source_cache[key]
+
+ def imported_namespaces(payload: bytes, package: str) -> tuple[dict[str, Any], ...]:
+ key = (payload, package)
+ if key not in imports:
+ imports[key] = tuple(_import_namespaces(payload, package))
+ return imports[key]
+
+ for lineage in classes.values():
+ leaf = lineage[0]
+ for cls in lineage:
+ if cls not in local_classes:
+ continue
+ snapshot = cls.__dict__.get("__source__")
+ path = cls.__dict__.get("__file__")
+ if snapshot is None and path is None and cls.__module__ == leaf.__module__:
+ snapshot = leaf.__dict__.get("__source__")
+ path = leaf.__dict__.get("__file__")
+ if snapshot is None and path is None:
+ path = getfile(cls)
+ payload = add_source(path or cls.__module__, snapshot)
+ if path is not None:
+ resolved = Path(path).resolve()
+ directories.add(resolved.parent)
+ if snapshot is not None:
+ snapshots[resolved] = snapshot
+ namespaces.extend(_class_namespaces(cls))
+ namespaces.extend(imported_namespaces(payload, cls.__module__.rpartition(".")[0]))
+
+ visited: set[int] = set()
+ while namespaces:
+ namespace = namespaces.pop()
+ if id(namespace) in visited:
+ continue
+ visited.add(id(namespace))
+ filename = namespace.get("__file__")
+ if filename is None:
+ continue
+ path = Path(filename).resolve()
+ if not any(path.is_relative_to(directory) for directory in directories):
+ continue
+ payload = add_source(path, snapshots.get(path))
+ namespaces.extend(imported_namespaces(payload, namespace.get("__package__") or ""))
+ for value in tuple(namespace.values()):
+ if callable(value):
+ value = unwrap(value)
+ if isfunction(value):
+ namespaces.append(value.__globals__)
+ elif isinstance(value, ModuleType):
+ namespaces.append(vars(value))
+ elif isinstance(value, type):
+ namespaces.extend(_class_namespaces(value))
+
+ add_source(__file__)
+ rl = any(
+ cls.__module__.startswith("freqtrade.freqai.RL.")
+ for lineage in classes.values()
+ for cls in lineage
+ )
+ dependencies = _COMMON_DEPENDENCIES + (_RL_DEPENDENCIES if rl else _REGRESSION_DEPENDENCIES)
+ versions: dict[str, str | None] = {}
+ for name in dependencies:
+ try:
+ versions[name] = version(name)
+ except PackageNotFoundError:
+ versions[name] = None
+ configuration = {
+ "python": platform.python_version(),
+ "sdk": freqtrade.__version__,
+ "versions": versions,
+ "implementations": {
+ role: [(cls.__module__, cls.__qualname__) for cls in lineage]
+ for role, lineage in classes.items()
+ },
+ }
+ digest = sha256(json.dumps(configuration, sort_keys=True).encode())
+ for label, payload in sorted(sources):
+ digest.update(json.dumps((label, len(payload))).encode())
+ digest.update(payload)
+ return digest.hexdigest()
+
+
+def bind_backtest_implementation(strategy: Any) -> None:
+ """Extend native result identity without model construction or storage changes."""
+ config = strategy.config
+ model_name = config.get("freqaimodel")
+ if not config.get("freqai", {}).get("enabled", False) or not model_name:
+ config.pop(_IMPLEMENTATION_KEY, None)
+ return
+ if model_name == "BaseRegressionModel":
+ raise OperationalException(
+ "BaseRegressionModel is a baseclass and cannot be used directly. "
+ "Please choose an existing child class or inherit from this baseclass."
+ )
+ paths = FreqaiModelResolver.build_search_paths(config, FreqaiModelResolver.user_subdir)
+ for path in paths:
+ try:
+ model, _ = FreqaiModelResolver._search_object(
+ directory=path, object_name=model_name, add_source=True
+ )
+ except FileNotFoundError:
+ continue
+ if model is not None:
+ config[_IMPLEMENTATION_KEY] = implementation_fingerprint(
+ {
+ "strategy": type(strategy),
+ "model": model,
+ }
+ )
+ return
+ raise OperationalException(
+ f"Impossible to load FreqaiModel '{model_name}'. "
+ "This class does not exist or contains Python code errors."
+ )
import datetime
import logging
from functools import reduce
+from pathlib import Path
from typing import Any, Final, Literal
import numpy as np
import pandas as pd
from freqtrade.constants import LongShort
+from freqtrade.enums import RunMode
from freqtrade.freqai.RL.Base5ActionRLEnv import Actions
# import talib.abstract as ta
from freqtrade.persistence import Trade
+from freqtrade.resolvers.iresolver import PathModifier
from freqtrade.strategy import IStrategy
from pandas import DataFrame
_ACTION_EXIT_SHORT: Final[int] = Actions.Short_exit.value
_leverage_warning_state: tuple[str, str] | None = None
+ def __init__(self, config: dict[str, Any], *args, **kwargs) -> None:
+ super().__init__(config, *args, **kwargs)
+ if config.get("runmode") in (RunMode.BACKTEST, RunMode.HYPEROPT):
+ # Archive charts run in WEBSERVER mode and need no external cache helper.
+ with PathModifier(Path(__file__).parent):
+ from BacktestIdentity import bind_backtest_implementation
+
+ bind_backtest_implementation(self)
+
@property
def can_short(self) -> bool:
return self.is_short_allowed()
deployment refit, not later rolling predictions. `timeseries_split` does not
accept zero.
+### Backtest result caching
+
+Both strategies bind native result-cache reuse to the selected strategy/model
+implementations, inherited code, loaded local Python helpers in implementation
+directories, Python/Freqtrade versions and relevant dependency versions.
+Unchanged inputs retain native parameter handling, cache-age rules and storage
+identifiers. Existing artifacts are not deleted. Version metadata does not
+detect arbitrary same-version edits to installed dependencies. Restart the bot
+or webserver after editing local code; cache identity does not reload modules.
+
+This outer cache is separate from FreqAI models and predictions. Invalidation
+does not erase their state or reconstruct a historical environment. Native result
+identity also does not hash downloaded candle contents: use `--cache none` after
+replacing market history. Use separate identifiers and storage for cold
+comparisons as described below.
+
### Archived strategy charts
Freqtrade 2026.10 can reanalyse the strategy source stored in a backtest ZIP
FreqAI model and runtime configuration; this does not reproduce a saved policy
or freeze the historical environment.
-For ReforceXY, this native chart API lacks the pairlist context required to train
-a fresh policy. Use normal backtesting for policy training and evaluation.
+ReforceXY can resolve training fees without a pairlist provider. Archived chart
+analysis still uses current data and training settings; use normal backtesting
+for controlled policy training and evaluation.
These checks run in `QuickAdapterRegressorV3` and `ReforceXY`, not in other
FreqAI models. Reserve `ft_bt_strategy*` directories containing
"diagnostics": [
{
"endCharacter": 46,
- "endLine": 1465,
+ "endLine": 1464,
"file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
"message": "Argument of type \"str | None\" cannot be assigned to parameter \"default\" of type \"str\" in function \"_validate_label_selection_metric\"\n Type \"str | None\" is not assignable to type \"str\"\n \"None\" is not assignable to \"str\"",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 24,
- "startLine": 1465
+ "startLine": 1464
},
{
"endCharacter": 79,
- "endLine": 2841,
+ "endLine": 2790,
"file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
"message": "Cannot access attribute \"index\" for class \"NDArray[Unknown]\"\n Attribute \"index\" is unknown",
"rule": "reportAttributeAccessIssue",
"severity": "error",
"startCharacter": 74,
- "startLine": 2841
+ "startLine": 2790
},
{
"endCharacter": 72,
- "endLine": 2843,
+ "endLine": 2792,
"file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
"message": "Cannot access attribute \"index\" for class \"NDArray[Unknown]\"\n Attribute \"index\" is unknown",
"rule": "reportAttributeAccessIssue",
"severity": "error",
"startCharacter": 67,
- "startLine": 2843
+ "startLine": 2792
},
{
"endCharacter": 90,
- "endLine": 2852,
+ "endLine": 2801,
"file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
"message": "Cannot access attribute \"index\" for class \"NDArray[Unknown]\"\n Attribute \"index\" is unknown",
"rule": "reportAttributeAccessIssue",
"severity": "error",
"startCharacter": 85,
- "startLine": 2852
+ "startLine": 2801
},
{
"endCharacter": 34,
- "endLine": 2864,
+ "endLine": 2813,
"file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
"message": "Argument of type \"Unknown | NDArray[Unknown] | Any | list[Unknown]\" cannot be assigned to parameter \"train_features\" of type \"DataFrame\" in function \"_filter_train_by_mask\"\n Type \"Unknown | NDArray[Unknown] | Any | list[Unknown]\" is not assignable to type \"DataFrame\"\n \"list[Unknown]\" is not assignable to \"DataFrame\"",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 20,
- "startLine": 2864
+ "startLine": 2813
},
{
"endCharacter": 32,
- "endLine": 2865,
+ "endLine": 2814,
"file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
"message": "Argument of type \"Unknown | NDArray[Unknown] | Any | list[Unknown]\" cannot be assigned to parameter \"train_labels\" of type \"DataFrame\" in function \"_filter_train_by_mask\"\n Type \"Unknown | NDArray[Unknown] | Any | list[Unknown]\" is not assignable to type \"DataFrame\"\n \"list[Unknown]\" is not assignable to \"DataFrame\"",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 20,
- "startLine": 2865
+ "startLine": 2814
},
{
"endCharacter": 38,
- "endLine": 2866,
+ "endLine": 2815,
"file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
"message": "Argument of type \"Unknown | NDArray[Unknown] | Any | list[Unknown]\" cannot be assigned to parameter \"train_weights\" of type \"NDArray[floating[Any]]\" in function \"_filter_train_by_mask\"\n Type \"Unknown | NDArray[Unknown] | Any | list[Unknown]\" is not assignable to type \"NDArray[floating[Any]]\"\n \"list[Unknown]\" is not assignable to \"ndarray[_AnyShape, dtype[floating[Any]]]\"",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 20,
- "startLine": 2866
+ "startLine": 2815
},
{
"endCharacter": 59,
- "endLine": 2869,
+ "endLine": 2818,
"file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
"message": "Argument of type \"Unknown | NDArray[Unknown] | Any | list[Unknown] | None\" cannot be assigned to parameter \"train_label_weights\" of type \"NDArray[floating[Any]] | None\" in function \"_filter_train_by_mask\"\n Type \"Unknown | NDArray[Unknown] | Any | list[Unknown] | None\" is not assignable to type \"NDArray[floating[Any]] | None\"\n Type \"list[Unknown]\" is not assignable to type \"NDArray[floating[Any]] | None\"\n \"list[Unknown]\" is not assignable to \"ndarray[_AnyShape, dtype[floating[Any]]]\"\n \"list[Unknown]\" is not assignable to \"None\"",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 40,
- "startLine": 2869
+ "startLine": 2818
},
{
"endCharacter": 34,
- "endLine": 2903,
+ "endLine": 2852,
"file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
"message": "Argument of type \"DataFrame | Unknown | NDArray[Unknown] | Any | list[Unknown]\" cannot be assigned to parameter \"features\" of type \"DataFrame\" in function \"_shuffle_split_rows\"\n Type \"DataFrame | Unknown | NDArray[Unknown] | Any | list[Unknown]\" is not assignable to type \"DataFrame\"\n \"list[Unknown]\" is not assignable to \"DataFrame\"",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 20,
- "startLine": 2903
+ "startLine": 2852
},
{
"endCharacter": 32,
- "endLine": 2904,
+ "endLine": 2853,
"file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
"message": "Argument of type \"DataFrame | Unknown | NDArray[Unknown] | Any | list[Unknown]\" cannot be assigned to parameter \"labels\" of type \"DataFrame\" in function \"_shuffle_split_rows\"\n Type \"DataFrame | Unknown | NDArray[Unknown] | Any | list[Unknown]\" is not assignable to type \"DataFrame\"\n \"list[Unknown]\" is not assignable to \"DataFrame\"",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 20,
- "startLine": 2904
+ "startLine": 2853
},
{
"endCharacter": 38,
- "endLine": 2905,
+ "endLine": 2854,
"file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
"message": "Argument of type \"NDArray[floating[Any]] | Unknown | NDArray[Unknown] | Any | list[Unknown]\" cannot be assigned to parameter \"base_weights\" of type \"NDArray[floating[Any]]\" in function \"_shuffle_split_rows\"\n Type \"NDArray[floating[Any]] | Unknown | NDArray[Unknown] | Any | list[Unknown]\" is not assignable to type \"NDArray[floating[Any]]\"\n \"list[Unknown]\" is not assignable to \"ndarray[_AnyShape, dtype[floating[Any]]]\"",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 20,
- "startLine": 2905
+ "startLine": 2854
},
{
"endCharacter": 39,
- "endLine": 2906,
+ "endLine": 2855,
"file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
"message": "Argument of type \"NDArray[floating[Any]] | Unknown | NDArray[Unknown] | Any | list[Unknown] | None\" cannot be assigned to parameter \"label_weights\" of type \"NDArray[floating[Any]] | None\" in function \"_shuffle_split_rows\"\n Type \"NDArray[floating[Any]] | Unknown | NDArray[Unknown] | Any | list[Unknown] | None\" is not assignable to type \"NDArray[floating[Any]] | None\"\n Type \"list[Unknown]\" is not assignable to type \"NDArray[floating[Any]] | None\"\n \"list[Unknown]\" is not assignable to \"ndarray[_AnyShape, dtype[floating[Any]]]\"\n \"list[Unknown]\" is not assignable to \"None\"",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 20,
- "startLine": 2906
+ "startLine": 2855
},
{
"endCharacter": 37,
- "endLine": 2913,
+ "endLine": 2862,
"file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
"message": "Argument of type \"Unknown | NDArray[Unknown] | Any | list[Unknown] | DataFrame\" cannot be assigned to parameter \"features\" of type \"DataFrame\" in function \"_shuffle_split_rows\"\n Type \"Unknown | NDArray[Unknown] | Any | list[Unknown] | DataFrame\" is not assignable to type \"DataFrame\"\n \"list[Unknown]\" is not assignable to \"DataFrame\"",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 24,
- "startLine": 2913
+ "startLine": 2862
},
{
"endCharacter": 35,
- "endLine": 2914,
+ "endLine": 2863,
"file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
"message": "Argument of type \"Unknown | NDArray[Unknown] | Any | list[Unknown] | DataFrame\" cannot be assigned to parameter \"labels\" of type \"DataFrame\" in function \"_shuffle_split_rows\"\n Type \"Unknown | NDArray[Unknown] | Any | list[Unknown] | DataFrame\" is not assignable to type \"DataFrame\"\n \"list[Unknown]\" is not assignable to \"DataFrame\"",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 24,
- "startLine": 2914
+ "startLine": 2863
},
{
"endCharacter": 41,
- "endLine": 2915,
+ "endLine": 2864,
"file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
"message": "Argument of type \"Unknown | NDArray[Unknown] | Any | list[Unknown] | ndarray[_AnyShape, dtype[floating[Any]]]\" cannot be assigned to parameter \"base_weights\" of type \"NDArray[floating[Any]]\" in function \"_shuffle_split_rows\"\n Type \"Unknown | NDArray[Unknown] | Any | list[Unknown] | ndarray[_AnyShape, dtype[floating[Any]]]\" is not assignable to type \"NDArray[floating[Any]]\"\n \"list[Unknown]\" is not assignable to \"ndarray[_AnyShape, dtype[floating[Any]]]\"",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 24,
- "startLine": 2915
+ "startLine": 2864
},
{
"endCharacter": 42,
- "endLine": 2916,
+ "endLine": 2865,
"file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
"message": "Argument of type \"Unknown | NDArray[Unknown] | Any | list[Unknown] | ndarray[_AnyShape, dtype[floating[Any]]] | None\" cannot be assigned to parameter \"label_weights\" of type \"NDArray[floating[Any]] | None\" in function \"_shuffle_split_rows\"\n Type \"Unknown | NDArray[Unknown] | Any | list[Unknown] | ndarray[_AnyShape, dtype[floating[Any]]] | None\" is not assignable to type \"NDArray[floating[Any]] | None\"\n Type \"list[Unknown]\" is not assignable to type \"NDArray[floating[Any]] | None\"\n \"list[Unknown]\" is not assignable to \"ndarray[_AnyShape, dtype[floating[Any]]]\"\n \"list[Unknown]\" is not assignable to \"None\"",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 24,
- "startLine": 2916
+ "startLine": 2865
},
{
"endCharacter": 30,
- "endLine": 2934,
+ "endLine": 2883,
"file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
"message": "Argument of type \"NDArray[floating[Any]] | Unknown | NDArray[Unknown] | Any | list[Unknown]\" cannot be assigned to parameter \"base_weights\" of type \"NDArray[floating[Any]]\" in function \"_compose_train_weights_with_support\"\n Type \"NDArray[floating[Any]] | Unknown | NDArray[Unknown] | Any | list[Unknown]\" is not assignable to type \"NDArray[floating[Any]]\"\n \"list[Unknown]\" is not assignable to \"ndarray[_AnyShape, dtype[floating[Any]]]\"",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 12,
- "startLine": 2934
+ "startLine": 2883
},
{
"endCharacter": 31,
- "endLine": 2935,
+ "endLine": 2884,
"file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
"message": "Argument of type \"NDArray[floating[Any]] | Unknown | NDArray[Unknown] | Any | list[Unknown] | None\" cannot be assigned to parameter \"label_weights\" of type \"NDArray[floating[Any]] | None\" in function \"_compose_train_weights_with_support\"\n Type \"NDArray[floating[Any]] | Unknown | NDArray[Unknown] | Any | list[Unknown] | None\" is not assignable to type \"NDArray[floating[Any]] | None\"\n Type \"list[Unknown]\" is not assignable to type \"NDArray[floating[Any]] | None\"\n \"list[Unknown]\" is not assignable to \"ndarray[_AnyShape, dtype[floating[Any]]]\"\n \"list[Unknown]\" is not assignable to \"None\"",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 12,
- "startLine": 2935
+ "startLine": 2884
},
{
"endCharacter": 33,
- "endLine": 2941,
+ "endLine": 2890,
"file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
"message": "Argument of type \"NDArray[floating[Any]] | Unknown | NDArray[Unknown] | Any | list[Unknown]\" cannot be assigned to parameter \"base_weights\" of type \"NDArray[floating[Any]]\" in function \"_compose_eval_weights\"\n Type \"NDArray[floating[Any]] | Unknown | NDArray[Unknown] | Any | list[Unknown]\" is not assignable to type \"NDArray[floating[Any]]\"\n \"list[Unknown]\" is not assignable to \"ndarray[_AnyShape, dtype[floating[Any]]]\"",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 16,
- "startLine": 2941
+ "startLine": 2890
},
{
"endCharacter": 34,
- "endLine": 2942,
+ "endLine": 2891,
"file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
"message": "Argument of type \"NDArray[floating[Any]] | Unknown | NDArray[Unknown] | Any | list[Unknown] | None\" cannot be assigned to parameter \"label_weights\" of type \"NDArray[floating[Any]] | None\" in function \"_compose_eval_weights\"\n Type \"NDArray[floating[Any]] | Unknown | NDArray[Unknown] | Any | list[Unknown] | None\" is not assignable to type \"NDArray[floating[Any]] | None\"\n Type \"list[Unknown]\" is not assignable to type \"NDArray[floating[Any]] | None\"\n \"list[Unknown]\" is not assignable to \"ndarray[_AnyShape, dtype[floating[Any]]]\"\n \"list[Unknown]\" is not assignable to \"None\"",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 16,
- "startLine": 2942
+ "startLine": 2891
},
{
"endCharacter": 26,
- "endLine": 2949,
+ "endLine": 2898,
"file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
"message": "Argument of type \"DataFrame | Unknown | NDArray[Unknown] | Any | list[Unknown]\" cannot be assigned to parameter \"train_df\" of type \"DataFrame\" in function \"build_data_dictionary\"\n Type \"DataFrame | Unknown | NDArray[Unknown] | Any | list[Unknown]\" is not assignable to type \"DataFrame\"\n \"list[Unknown]\" is not assignable to \"DataFrame\"",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 12,
- "startLine": 2949
+ "startLine": 2898
},
{
"endCharacter": 25,
- "endLine": 2950,
+ "endLine": 2899,
"file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
"message": "Argument of type \"DataFrame | Unknown | NDArray[Unknown] | Any | list[Unknown]\" cannot be assigned to parameter \"test_df\" of type \"DataFrame\" in function \"build_data_dictionary\"\n Type \"DataFrame | Unknown | NDArray[Unknown] | Any | list[Unknown]\" is not assignable to type \"DataFrame\"\n \"list[Unknown]\" is not assignable to \"DataFrame\"",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 12,
- "startLine": 2950
+ "startLine": 2899
},
{
"endCharacter": 24,
- "endLine": 2951,
+ "endLine": 2900,
"file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
"message": "Argument of type \"DataFrame | Unknown | NDArray[Unknown] | Any | list[Unknown]\" cannot be assigned to parameter \"train_labels\" of type \"DataFrame\" in function \"build_data_dictionary\"\n Type \"DataFrame | Unknown | NDArray[Unknown] | Any | list[Unknown]\" is not assignable to type \"DataFrame\"\n \"list[Unknown]\" is not assignable to \"DataFrame\"",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 12,
- "startLine": 2951
+ "startLine": 2900
},
{
"endCharacter": 23,
- "endLine": 2952,
+ "endLine": 2901,
"file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
"message": "Argument of type \"DataFrame | Unknown | NDArray[Unknown] | Any | list[Unknown]\" cannot be assigned to parameter \"test_labels\" of type \"DataFrame\" in function \"build_data_dictionary\"\n Type \"DataFrame | Unknown | NDArray[Unknown] | Any | list[Unknown]\" is not assignable to type \"DataFrame\"\n \"list[Unknown]\" is not assignable to \"DataFrame\"",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 12,
- "startLine": 2952
+ "startLine": 2901
},
{
"endCharacter": 87,
- "endLine": 3297,
+ "endLine": 3246,
"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": 3297
+ "startLine": 3246
},
{
"endCharacter": 68,
- "endLine": 3298,
+ "endLine": 3247,
"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": 3298
+ "startLine": 3247
},
{
"endCharacter": 71,
- "endLine": 3307,
+ "endLine": 3256,
"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": 3307
+ "startLine": 3256
},
{
"endCharacter": 47,
- "endLine": 3310,
+ "endLine": 3259,
"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": 3310
+ "startLine": 3259
},
{
"endCharacter": 47,
- "endLine": 3310,
+ "endLine": 3259,
"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": 3310
+ "startLine": 3259
},
{
"endCharacter": 43,
- "endLine": 3311,
+ "endLine": 3260,
"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": 3311
+ "startLine": 3260
},
{
"endCharacter": 43,
- "endLine": 3311,
+ "endLine": 3260,
"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": 3311
+ "startLine": 3260
},
{
"endCharacter": 31,
- "endLine": 3332,
+ "endLine": 3281,
"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": 3332
+ "startLine": 3281
},
{
"endCharacter": 31,
- "endLine": 3332,
+ "endLine": 3281,
"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": 3332
+ "startLine": 3281
},
{
"endCharacter": 60,
- "endLine": 3332,
+ "endLine": 3281,
"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": 3332
+ "startLine": 3281
},
{
"endCharacter": 60,
- "endLine": 3332,
+ "endLine": 3281,
"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": 3332
+ "startLine": 3281
},
{
"endCharacter": 73,
- "endLine": 3344,
+ "endLine": 3293,
"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": 3344
+ "startLine": 3293
},
{
"endCharacter": 73,
- "endLine": 3344,
+ "endLine": 3293,
"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": 3344
+ "startLine": 3293
},
{
"endCharacter": 83,
- "endLine": 3345,
+ "endLine": 3294,
"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": 3345
+ "startLine": 3294
},
{
"endCharacter": 83,
- "endLine": 3345,
+ "endLine": 3294,
"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": 3345
+ "startLine": 3294
},
{
"endCharacter": 46,
- "endLine": 3580,
+ "endLine": 3529,
"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": 3580
+ "startLine": 3529
},
{
"endCharacter": 46,
- "endLine": 3580,
+ "endLine": 3529,
"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": 3580
+ "startLine": 3529
},
{
"endCharacter": 46,
- "endLine": 3580,
+ "endLine": 3529,
"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": 3580
+ "startLine": 3529
},
{
"endCharacter": 46,
- "endLine": 3580,
+ "endLine": 3529,
"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": 3580
+ "startLine": 3529
},
{
"endCharacter": 46,
- "endLine": 3580,
+ "endLine": 3529,
"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": 3580
+ "startLine": 3529
},
{
"endCharacter": 46,
- "endLine": 3580,
+ "endLine": 3529,
"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": 3580
+ "startLine": 3529
},
{
"endCharacter": 46,
- "endLine": 3580,
+ "endLine": 3529,
"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": 3580
+ "startLine": 3529
},
{
"endCharacter": 41,
- "endLine": 3587,
+ "endLine": 3536,
"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": 3587
+ "startLine": 3536
},
{
"endCharacter": 39,
- "endLine": 3636,
+ "endLine": 3585,
"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": 3636
+ "startLine": 3585
},
{
"endCharacter": 19,
- "endLine": 3746,
+ "endLine": 3695,
"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": 3746
+ "startLine": 3695
},
{
"endCharacter": 21,
- "endLine": 3857,
+ "endLine": 3806,
"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": 3857
+ "startLine": 3806
},
{
"endCharacter": 21,
- "endLine": 3858,
+ "endLine": 3807,
"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": 3858
+ "startLine": 3807
},
{
"endCharacter": 33,
- "endLine": 3859,
+ "endLine": 3808,
"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": 3859
+ "startLine": 3808
},
{
"endCharacter": 32,
- "endLine": 3860,
+ "endLine": 3809,
"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": 3860
+ "startLine": 3809
},
{
"endCharacter": 32,
- "endLine": 3861,
+ "endLine": 3810,
"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": 3861
+ "startLine": 3810
},
{
"endCharacter": 38,
- "endLine": 3862,
+ "endLine": 3811,
"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": 3862
+ "startLine": 3811
},
{
"endCharacter": 24,
- "endLine": 3883,
+ "endLine": 3832,
"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": 3883
+ "startLine": 3832
},
{
"endCharacter": 24,
- "endLine": 3884,
+ "endLine": 3833,
"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": 3884
+ "startLine": 3833
},
{
"endCharacter": 30,
- "endLine": 3885,
+ "endLine": 3834,
"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": 3885
+ "startLine": 3834
},
{
"endCharacter": 15,
- "endLine": 3891,
+ "endLine": 3840,
"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": 3891
+ "startLine": 3840
},
{
"endCharacter": 15,
- "endLine": 3892,
+ "endLine": 3841,
"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": 3892
+ "startLine": 3841
},
{
"endCharacter": 39,
- "endLine": 3893,
+ "endLine": 3842,
"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": 3893
+ "startLine": 3842
},
{
"endCharacter": 38,
- "endLine": 3903,
+ "endLine": 3852,
"file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
"message": "\"columns\" is not a known attribute of \"None\"",
"rule": "reportOptionalMemberAccess",
"severity": "error",
"startCharacter": 31,
- "startLine": 3903
+ "startLine": 3852
},
{
"endCharacter": 34,
- "endLine": 3904,
+ "endLine": 3853,
"file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
"message": "\"index\" is not a known attribute of \"None\"",
"rule": "reportOptionalMemberAccess",
"severity": "error",
"startCharacter": 29,
- "startLine": 3904
+ "startLine": 3853
},
{
"endCharacter": 82,
- "endLine": 3906,
+ "endLine": 3855,
"file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
"message": "\"copy\" is not a known attribute of \"None\"",
"rule": "reportOptionalMemberAccess",
"severity": "error",
"startCharacter": 78,
- "startLine": 3906
+ "startLine": 3855
},
{
"endCharacter": 62,
- "endLine": 4326,
+ "endLine": 4275,
"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": 4326
+ "startLine": 4275
},
{
"endCharacter": 68,
- "endLine": 4707,
+ "endLine": 4656,
"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": 4703
+ "startLine": 4652
},
{
"endCharacter": 13,
- "endLine": 4736,
+ "endLine": 4685,
"file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
"message": "No overloads for \"cdist\" match the provided arguments",
"rule": "reportCallIssue",
"severity": "error",
"startCharacter": 19,
- "startLine": 4731
+ "startLine": 4680
},
{
"endCharacter": 38,
- "endLine": 4734,
+ "endLine": 4683,
"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": 4734
+ "startLine": 4683
},
{
"endCharacter": 9,
- "endLine": 4839,
+ "endLine": 4788,
"file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
"message": "No overloads for \"pdist\" match the provided arguments",
"rule": "reportCallIssue",
"severity": "error",
"startCharacter": 36,
- "startLine": 4837
+ "startLine": 4786
},
{
"endCharacter": 42,
- "endLine": 4838,
+ "endLine": 4787,
"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": 4838
+ "startLine": 4787
},
{
"endCharacter": 9,
- "endLine": 4916,
+ "endLine": 4865,
"file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
"message": "No overloads for \"cdist\" match the provided arguments",
"rule": "reportCallIssue",
"severity": "error",
"startCharacter": 15,
- "startLine": 4911
+ "startLine": 4860
},
{
"endCharacter": 34,
- "endLine": 4914,
+ "endLine": 4863,
"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": 4914
+ "startLine": 4863
},
{
"endCharacter": 99,
- "endLine": 5105,
+ "endLine": 5054,
"file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
"message": "No overloads for \"pdist\" match the provided arguments",
"rule": "reportCallIssue",
"severity": "error",
"startCharacter": 12,
- "startLine": 5105
+ "startLine": 5054
},
{
"endCharacter": 79,
- "endLine": 5105,
+ "endLine": 5054,
"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": 5105
+ "startLine": 5054
},
{
"endCharacter": 55,
- "endLine": 225,
+ "endLine": 226,
"file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
"message": "Type \"int\" is not assignable to declared type \"cached_property[int]\"\n \"int\" is not assignable to \"cached_property[int]\"",
"rule": "reportAssignmentType",
"severity": "error",
"startCharacter": 24,
- "startLine": 225
+ "startLine": 226
},
{
"endCharacter": 15,
- "endLine": 260,
+ "endLine": 261,
"file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
"message": "Class variable \"minimal_roi\" overrides instance variable of same name in class \"IStrategy\"",
"rule": "reportIncompatibleVariableOverride",
"severity": "error",
"startCharacter": 4,
- "startLine": 260
+ "startLine": 261
},
{
"endCharacter": 72,
- "endLine": 260,
+ "endLine": 261,
"file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
"message": "Operator \"*\" not supported for types \"cached_property[int]\" and \"Literal[864]\"",
"rule": "reportOperatorIssue",
"severity": "error",
"startCharacter": 49,
- "startLine": 260
+ "startLine": 261
},
{
"endCharacter": 64,
- "endLine": 273,
+ "endLine": 276,
"file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
"message": "Argument of type \"Any | None\" cannot be assigned to parameter \"timeframe\" of type \"str\" in function \"timeframe_to_minutes\"\n Type \"Any | None\" is not assignable to type \"str\"\n \"None\" is not assignable to \"str\"",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 36,
- "startLine": 273
+ "startLine": 276
},
{
"endCharacter": 17,
- "endLine": 282,
+ "endLine": 285,
"file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
"message": "\"can_short\" overrides symbol of same name in class \"IStrategy\"\n \"property\" is not assignable to \"bool\"",
"rule": "reportIncompatibleVariableOverride",
"severity": "error",
"startCharacter": 8,
- "startLine": 282
+ "startLine": 285
},
{
"endCharacter": 19,
- "endLine": 286,
+ "endLine": 289,
"file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
"message": "\"plot_config\" overrides symbol of same name in class \"IStrategy\"\n \"cached_property[dict[str, Any]]\" is not assignable to \"dict[Unknown, Unknown]\"",
"rule": "reportIncompatibleVariableOverride",
"severity": "error",
"startCharacter": 8,
- "startLine": 286
+ "startLine": 289
},
{
"endCharacter": 19,
- "endLine": 326,
+ "endLine": 329,
"file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
"message": "\"protections\" overrides symbol of same name in class \"IStrategy\"\n \"cached_property[list[dict[str, Any]]]\" is not assignable to \"list[Unknown]\"",
"rule": "reportIncompatibleVariableOverride",
"severity": "error",
"startCharacter": 8,
- "startLine": 326
+ "startLine": 329
},
{
"endCharacter": 28,
- "endLine": 399,
+ "endLine": 402,
"file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
"message": "\"startup_candle_count\" overrides symbol of same name in class \"IStrategy\"\n \"property\" is not assignable to \"int\"",
"rule": "reportIncompatibleVariableOverride",
"severity": "error",
"startCharacter": 8,
- "startLine": 399
+ "startLine": 402
},
{
"endCharacter": 44,
- "endLine": 508,
+ "endLine": 511,
"file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
"message": "Operator \"/\" not supported for \"None\"",
"rule": "reportOptionalOperand",
"severity": "error",
"startCharacter": 12,
- "startLine": 508
+ "startLine": 511
},
{
"endCharacter": 38,
- "endLine": 782,
+ "endLine": 785,
"file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
"message": "\"to_numpy\" is not a known attribute of \"None\"",
"rule": "reportOptionalMemberAccess",
"severity": "error",
"startCharacter": 30,
- "startLine": 782
+ "startLine": 785
},
{
"endCharacter": 44,
- "endLine": 815,
+ "endLine": 818,
"file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
"message": "Operator \"-\" not supported for \"None\"",
"rule": "reportOptionalOperand",
"severity": "error",
"startCharacter": 38,
- "startLine": 815
+ "startLine": 818
},
{
"endCharacter": 38,
- "endLine": 823,
+ "endLine": 826,
"file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
"message": "Object of type \"None\" is not subscriptable",
"rule": "reportOptionalSubscript",
"severity": "error",
"startCharacter": 36,
- "startLine": 823
+ "startLine": 826
},
{
"endCharacter": 39,
- "endLine": 824,
+ "endLine": 827,
"file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
"message": "Object of type \"None\" is not subscriptable",
"rule": "reportOptionalSubscript",
"severity": "error",
"startCharacter": 37,
- "startLine": 824
+ "startLine": 827
},
{
"endCharacter": 38,
- "endLine": 825,
+ "endLine": 828,
"file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
"message": "Object of type \"None\" is not subscriptable",
"rule": "reportOptionalSubscript",
"severity": "error",
"startCharacter": 36,
- "startLine": 825
+ "startLine": 828
},
{
"endCharacter": 44,
- "endLine": 848,
+ "endLine": 851,
"file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
"message": "Operator \"-\" not supported for types \"Series[Any] | None\" and \"Series[Any] | None\"\n Operator \"-\" not supported for types \"Series[Any]\" and \"None\"\n Operator \"-\" not supported for types \"None\" and \"Series[Any]\"\n Operator \"-\" not supported for types \"None\" and \"None\"",
"rule": "reportOperatorIssue",
"severity": "error",
"startCharacter": 29,
- "startLine": 848
+ "startLine": 851
},
{
"endCharacter": 66,
- "endLine": 848,
+ "endLine": 851,
"file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
"message": "Argument of type \"Series[Any] | None\" cannot be assigned to parameter \"s1\" of type \"Series[Any]\" in function \"non_zero_diff\"\n Type \"Series[Any] | None\" is not assignable to type \"Series[Any]\"\n \"None\" is not assignable to \"Series[Any]\"",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 61,
- "startLine": 848
+ "startLine": 851
},
{
"endCharacter": 72,
- "endLine": 848,
+ "endLine": 851,
"file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
"message": "Argument of type \"Series[Any] | None\" cannot be assigned to parameter \"s2\" of type \"Series[Any]\" in function \"non_zero_diff\"\n Type \"Series[Any] | None\" is not assignable to type \"Series[Any]\"\n \"None\" is not assignable to \"Series[Any]\"",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 68,
- "startLine": 848
+ "startLine": 851
},
{
"endCharacter": 56,
- "endLine": 854,
+ "endLine": 857,
"file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
"message": "Argument of type \"Series[Any] | None\" cannot be assigned to parameter \"p1\" of type \"T@get_distance\" in function \"get_distance\"\n Type \"Series[Any] | None\" is not assignable to type \"Series[Any]\"\n \"None\" is not assignable to \"Series[Any]\"",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 50,
- "startLine": 854
+ "startLine": 857
},
{
"endCharacter": 58,
- "endLine": 855,
+ "endLine": 858,
"file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
"message": "Argument of type \"Series[Any] | None\" cannot be assigned to parameter \"p1\" of type \"T@get_distance\" in function \"get_distance\"\n Type \"Series[Any] | None\" is not assignable to type \"Series[Any]\"\n \"None\" is not assignable to \"Series[Any]\"",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 52,
- "startLine": 855
+ "startLine": 858
},
{
"endCharacter": 57,
- "endLine": 856,
+ "endLine": 859,
"file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
"message": "Argument of type \"Series[Any] | None\" cannot be assigned to parameter \"p1\" of type \"T@get_distance\" in function \"get_distance\"\n Type \"Series[Any] | None\" is not assignable to type \"Series[Any]\"\n \"None\" is not assignable to \"Series[Any]\"",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 51,
- "startLine": 856
+ "startLine": 859
},
{
"endCharacter": 44,
- "endLine": 859,
+ "endLine": 862,
"file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
"message": "Argument of type \"Series[Any] | None\" cannot be assigned to parameter \"series\" of type \"Series[Any]\" in function \"zlema\"\n Type \"Series[Any] | None\" is not assignable to type \"Series[Any]\"\n \"None\" is not assignable to \"Series[Any]\"",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 38,
- "startLine": 859
+ "startLine": 862
},
{
"endCharacter": 44,
- "endLine": 860,
+ "endLine": 863,
"file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
"message": "Argument of type \"Series[Any] | None\" cannot be assigned to parameter \"series\" of type \"Series[Any]\" in function \"zlema\"\n Type \"Series[Any] | None\" is not assignable to type \"Series[Any]\"\n \"None\" is not assignable to \"Series[Any]\"",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 38,
- "startLine": 860
+ "startLine": 863
},
{
"endCharacter": 44,
- "endLine": 861,
+ "endLine": 864,
"file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
"message": "Argument of type \"Series[Any] | None\" cannot be assigned to parameter \"series\" of type \"Series[Any]\" in function \"zlema\"\n Type \"Series[Any] | None\" is not assignable to type \"Series[Any]\"\n \"None\" is not assignable to \"Series[Any]\"",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 38,
- "startLine": 861
+ "startLine": 864
},
{
"endCharacter": 61,
- "endLine": 862,
+ "endLine": 865,
"file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
"message": "Argument of type \"Series[Any] | None\" cannot be assigned to parameter \"p1\" of type \"T@get_distance\" in function \"get_distance\"\n Type \"Series[Any] | None\" is not assignable to type \"Series[Any]\"\n \"None\" is not assignable to \"Series[Any]\"",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 55,
- "startLine": 862
+ "startLine": 865
},
{
"endCharacter": 61,
- "endLine": 863,
+ "endLine": 866,
"file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
"message": "Argument of type \"Series[Any] | None\" cannot be assigned to parameter \"p1\" of type \"T@get_distance\" in function \"get_distance\"\n Type \"Series[Any] | None\" is not assignable to type \"Series[Any]\"\n \"None\" is not assignable to \"Series[Any]\"",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 55,
- "startLine": 863
+ "startLine": 866
},
{
"endCharacter": 61,
- "endLine": 864,
+ "endLine": 867,
"file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
"message": "Argument of type \"Series[Any] | None\" cannot be assigned to parameter \"p1\" of type \"T@get_distance\" in function \"get_distance\"\n Type \"Series[Any] | None\" is not assignable to type \"Series[Any]\"\n \"None\" is not assignable to \"Series[Any]\"",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 55,
- "startLine": 864
+ "startLine": 867
},
{
"endCharacter": 81,
- "endLine": 872,
+ "endLine": 875,
"file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
"message": "Argument of type \"Series[Any]\" cannot be assigned to parameter \"p2\" of type \"T@get_distance\" in function \"get_distance\"\n \"Series[Any]\" is not assignable to \"float\"",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 58,
- "startLine": 872
+ "startLine": 875
},
{
"endCharacter": 67,
- "endLine": 885,
+ "endLine": 888,
"file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
"message": "Argument of type \"Series[Any] | None\" cannot be assigned to parameter \"p1\" of type \"T@get_distance\" in function \"get_distance\"\n Type \"Series[Any] | None\" is not assignable to type \"Series[Any]\"\n \"None\" is not assignable to \"Series[Any]\"",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 61,
- "startLine": 885
+ "startLine": 888
},
{
"endCharacter": 68,
- "endLine": 886,
+ "endLine": 889,
"file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
"message": "Argument of type \"Series[Any] | None\" cannot be assigned to parameter \"p1\" of type \"T@get_distance\" in function \"get_distance\"\n Type \"Series[Any] | None\" is not assignable to type \"Series[Any]\"\n \"None\" is not assignable to \"Series[Any]\"",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 62,
- "startLine": 886
+ "startLine": 889
},
{
"endCharacter": 67,
- "endLine": 887,
+ "endLine": 890,
"file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
"message": "Argument of type \"Series[Any] | None\" cannot be assigned to parameter \"p1\" of type \"T@get_distance\" in function \"get_distance\"\n Type \"Series[Any] | None\" is not assignable to type \"Series[Any]\"\n \"None\" is not assignable to \"Series[Any]\"",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 61,
- "startLine": 887
+ "startLine": 890
},
{
"endCharacter": 44,
- "endLine": 888,
+ "endLine": 891,
"file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
"message": "Operator \"-\" not supported for types \"Series[Any] | None\" and \"Series[Any] | None\"\n Operator \"-\" not supported for types \"Series[Any]\" and \"None\" when expected type is \"_SetItemValueNotDataFrame\"\n Operator \"-\" not supported for types \"None\" and \"Series[Any]\" when expected type is \"_SetItemValueNotDataFrame\"\n Operator \"-\" not supported for types \"None\" and \"None\" when expected type is \"_SetItemValueNotDataFrame\"",
"rule": "reportOperatorIssue",
"severity": "error",
"startCharacter": 30,
- "startLine": 888
+ "startLine": 891
},
{
"endCharacter": 56,
- "endLine": 889,
+ "endLine": 892,
"file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
"message": "No overloads for \"__call__\" match the provided arguments",
"rule": "reportCallIssue",
"severity": "error",
"startCharacter": 31,
- "startLine": 889
+ "startLine": 892
},
{
"endCharacter": 47,
- "endLine": 889,
+ "endLine": 892,
"file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
"message": "Argument of type \"Series[Any] | None\" cannot be assigned to parameter \"x1\" of type \"ArrayLike\" in function \"__call__\"\n Type \"Series[Any] | None\" is not assignable to type \"ArrayLike\"\n Type \"None\" is not assignable to type \"ArrayLike\"\n \"None\" is incompatible with protocol \"Buffer\"\n \"__buffer__\" is not present\n \"None\" is incompatible with protocol \"_SupportsArray[dtype[Any]]\"\n \"__array__\" is not present\n \"None\" is incompatible with protocol \"_NestedSequence[_SupportsArray[dtype[Any]]]\"\n \"__len__\" is not present\n ...",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 42,
- "startLine": 889
+ "startLine": 892
},
{
"endCharacter": 55,
- "endLine": 889,
+ "endLine": 892,
"file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
"message": "Argument of type \"Series[Any] | None\" cannot be assigned to parameter \"x2\" of type \"ArrayLike\" in function \"__call__\"\n Type \"Series[Any] | None\" is not assignable to type \"ArrayLike\"\n Type \"None\" is not assignable to type \"ArrayLike\"\n \"None\" is incompatible with protocol \"Buffer\"\n \"__buffer__\" is not present\n \"None\" is incompatible with protocol \"_SupportsArray[dtype[Any]]\"\n \"__array__\" is not present\n \"None\" is incompatible with protocol \"_NestedSequence[_SupportsArray[dtype[Any]]]\"\n \"__len__\" is not present\n ...",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 49,
- "startLine": 889
+ "startLine": 892
},
{
"endCharacter": 64,
- "endLine": 890,
+ "endLine": 893,
"file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
"message": "No overloads for \"__call__\" match the provided arguments",
"rule": "reportCallIssue",
"severity": "error",
"startCharacter": 39,
- "startLine": 890
+ "startLine": 893
},
{
"endCharacter": 55,
- "endLine": 890,
+ "endLine": 893,
"file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
"message": "Argument of type \"Series[Any] | None\" cannot be assigned to parameter \"x1\" of type \"ArrayLike\" in function \"__call__\"\n Type \"Series[Any] | None\" is not assignable to type \"ArrayLike\"\n Type \"None\" is not assignable to type \"ArrayLike\"\n \"None\" is incompatible with protocol \"Buffer\"\n \"__buffer__\" is not present\n \"None\" is incompatible with protocol \"_SupportsArray[dtype[Any]]\"\n \"__array__\" is not present\n \"None\" is incompatible with protocol \"_NestedSequence[_SupportsArray[dtype[Any]]]\"\n \"__len__\" is not present\n ...",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 50,
- "startLine": 890
+ "startLine": 893
},
{
"endCharacter": 63,
- "endLine": 890,
+ "endLine": 893,
"file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
"message": "Argument of type \"Series[Any] | None\" cannot be assigned to parameter \"x2\" of type \"ArrayLike\" in function \"__call__\"\n Type \"Series[Any] | None\" is not assignable to type \"ArrayLike\"\n Type \"None\" is not assignable to type \"ArrayLike\"\n \"None\" is incompatible with protocol \"Buffer\"\n \"__buffer__\" is not present\n \"None\" is incompatible with protocol \"_SupportsArray[dtype[Any]]\"\n \"__array__\" is not present\n \"None\" is incompatible with protocol \"_NestedSequence[_SupportsArray[dtype[Any]]]\"\n \"__len__\" is not present\n ...",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 57,
- "startLine": 890
+ "startLine": 893
},
{
"endCharacter": 55,
- "endLine": 898,
+ "endLine": 901,
"file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
"message": "Argument of type \"Series[Any] | None\" cannot be assigned to parameter \"p1\" of type \"T@get_distance\" in function \"get_distance\"\n Type \"Series[Any] | None\" is not assignable to type \"Series[Any]\"\n \"None\" is not assignable to \"Series[Any]\"",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 49,
- "startLine": 898
+ "startLine": 901
},
{
"endCharacter": 55,
- "endLine": 899,
+ "endLine": 902,
"file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
"message": "Argument of type \"Series[Any] | None\" cannot be assigned to parameter \"p1\" of type \"T@get_distance\" in function \"get_distance\"\n Type \"Series[Any] | None\" is not assignable to type \"Series[Any]\"\n \"None\" is not assignable to \"Series[Any]\"",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 49,
- "startLine": 899
+ "startLine": 902
},
{
"endCharacter": 55,
- "endLine": 900,
+ "endLine": 903,
"file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
"message": "Argument of type \"Series[Any] | None\" cannot be assigned to parameter \"p1\" of type \"T@get_distance\" in function \"get_distance\"\n Type \"Series[Any] | None\" is not assignable to type \"Series[Any]\"\n \"None\" is not assignable to \"Series[Any]\"",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 49,
- "startLine": 900
+ "startLine": 903
},
{
"endCharacter": 55,
- "endLine": 901,
+ "endLine": 904,
"file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
"message": "Argument of type \"Series[Any] | None\" cannot be assigned to parameter \"p1\" of type \"T@get_distance\" in function \"get_distance\"\n Type \"Series[Any] | None\" is not assignable to type \"Series[Any]\"\n \"None\" is not assignable to \"Series[Any]\"",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 49,
- "startLine": 901
+ "startLine": 904
},
{
"endCharacter": 55,
- "endLine": 902,
+ "endLine": 905,
"file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
"message": "Argument of type \"Series[Any] | None\" cannot be assigned to parameter \"p1\" of type \"T@get_distance\" in function \"get_distance\"\n Type \"Series[Any] | None\" is not assignable to type \"Series[Any]\"\n \"None\" is not assignable to \"Series[Any]\"",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 49,
- "startLine": 902
+ "startLine": 905
},
{
"endCharacter": 55,
- "endLine": 903,
+ "endLine": 906,
"file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
"message": "Argument of type \"Series[Any] | None\" cannot be assigned to parameter \"p1\" of type \"T@get_distance\" in function \"get_distance\"\n Type \"Series[Any] | None\" is not assignable to type \"Series[Any]\"\n \"None\" is not assignable to \"Series[Any]\"",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 49,
- "startLine": 903
+ "startLine": 906
},
{
"endCharacter": 50,
- "endLine": 932,
+ "endLine": 935,
"file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
"message": "Argument of type \"Any | None\" cannot be assigned to parameter \"x\" of type \"ConvertibleToInt\" in function \"__new__\"\n Type \"Any | None\" is not assignable to type \"ConvertibleToInt\"\n Type \"None\" is not assignable to type \"ConvertibleToInt\"\n \"None\" is not assignable to \"str\"\n \"None\" is incompatible with protocol \"Buffer\"\n \"__buffer__\" is not present\n \"None\" is incompatible with protocol \"SupportsInt\"\n \"__int__\" is not present\n \"None\" is incompatible with protocol \"SupportsIndex\"",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 44,
- "startLine": 932
+ "startLine": 935
},
{
"endCharacter": 50,
- "endLine": 932,
+ "endLine": 935,
"file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
"message": "Argument of type \"Any | None\" cannot be assigned to parameter \"x\" of type \"ConvertibleToInt\" in function \"__new__\"\n Type \"Any | None\" is not assignable to type \"ConvertibleToInt\"\n Type \"None\" is not assignable to type \"ConvertibleToInt\"\n \"None\" is not assignable to \"str\"\n \"None\" is incompatible with protocol \"Buffer\"\n \"__buffer__\" is not present\n \"None\" is incompatible with protocol \"SupportsInt\"\n \"__int__\" is not present\n \"None\" is incompatible with protocol \"SupportsIndex\"\n ...",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 44,
- "startLine": 932
+ "startLine": 935
},
{
"endCharacter": 29,
- "endLine": 933,
+ "endLine": 936,
"file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
"message": "Argument of type \"Any | None\" cannot be assigned to parameter \"x\" of type \"ConvertibleToInt\" in function \"__new__\"\n Type \"Any | None\" is not assignable to type \"ConvertibleToInt\"\n Type \"None\" is not assignable to type \"ConvertibleToInt\"\n \"None\" is not assignable to \"str\"\n \"None\" is incompatible with protocol \"Buffer\"\n \"__buffer__\" is not present\n \"None\" is incompatible with protocol \"SupportsInt\"\n \"__int__\" is not present\n \"None\" is incompatible with protocol \"SupportsIndex\"",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 23,
- "startLine": 933
+ "startLine": 936
},
{
"endCharacter": 29,
- "endLine": 933,
+ "endLine": 936,
"file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
"message": "Argument of type \"Any | None\" cannot be assigned to parameter \"x\" of type \"ConvertibleToInt\" in function \"__new__\"\n Type \"Any | None\" is not assignable to type \"ConvertibleToInt\"\n Type \"None\" is not assignable to type \"ConvertibleToInt\"\n \"None\" is not assignable to \"str\"\n \"None\" is incompatible with protocol \"Buffer\"\n \"__buffer__\" is not present\n \"None\" is incompatible with protocol \"SupportsInt\"\n \"__int__\" is not present\n \"None\" is incompatible with protocol \"SupportsIndex\"\n ...",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 23,
- "startLine": 933
+ "startLine": 936
},
{
"endCharacter": 60,
- "endLine": 970,
+ "endLine": 973,
"file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
"message": "Argument of type \"Any | None\" cannot be assigned to parameter \"x\" of type \"ConvertibleToFloat\" in function \"__new__\"\n Type \"Any | None\" is not assignable to type \"ConvertibleToFloat\"\n Type \"None\" is not assignable to type \"ConvertibleToFloat\"\n \"None\" is not assignable to \"str\"\n \"None\" is incompatible with protocol \"Buffer\"\n \"__buffer__\" is not present\n \"None\" is incompatible with protocol \"SupportsFloat\"\n \"__float__\" is not present\n \"None\" is incompatible with protocol \"SupportsIndex\"",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 50,
- "startLine": 970
+ "startLine": 973
},
{
"endCharacter": 60,
- "endLine": 970,
+ "endLine": 973,
"file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
"message": "Argument of type \"Any | None\" cannot be assigned to parameter \"x\" of type \"ConvertibleToFloat\" in function \"__new__\"\n Type \"Any | None\" is not assignable to type \"ConvertibleToFloat\"\n Type \"None\" is not assignable to type \"ConvertibleToFloat\"\n \"None\" is not assignable to \"str\"\n \"None\" is incompatible with protocol \"Buffer\"\n \"__buffer__\" is not present\n \"None\" is incompatible with protocol \"SupportsFloat\"\n \"__float__\" is not present\n \"None\" is incompatible with protocol \"SupportsIndex\"\n ...",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 50,
- "startLine": 970
+ "startLine": 973
},
{
"endCharacter": 35,
- "endLine": 971,
+ "endLine": 974,
"file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
"message": "Argument of type \"Any | None\" cannot be assigned to parameter \"x\" of type \"ConvertibleToFloat\" in function \"__new__\"\n Type \"Any | None\" is not assignable to type \"ConvertibleToFloat\"\n Type \"None\" is not assignable to type \"ConvertibleToFloat\"\n \"None\" is not assignable to \"str\"\n \"None\" is incompatible with protocol \"Buffer\"\n \"__buffer__\" is not present\n \"None\" is incompatible with protocol \"SupportsFloat\"\n \"__float__\" is not present\n \"None\" is incompatible with protocol \"SupportsIndex\"",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 25,
- "startLine": 971
+ "startLine": 974
},
{
"endCharacter": 35,
- "endLine": 971,
+ "endLine": 974,
"file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
"message": "Argument of type \"Any | None\" cannot be assigned to parameter \"x\" of type \"ConvertibleToFloat\" in function \"__new__\"\n Type \"Any | None\" is not assignable to type \"ConvertibleToFloat\"\n Type \"None\" is not assignable to type \"ConvertibleToFloat\"\n \"None\" is not assignable to \"str\"\n \"None\" is incompatible with protocol \"Buffer\"\n \"__buffer__\" is not present\n \"None\" is incompatible with protocol \"SupportsFloat\"\n \"__float__\" is not present\n \"None\" is incompatible with protocol \"SupportsIndex\"\n ...",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 25,
- "startLine": 971
+ "startLine": 974
},
{
"endCharacter": 41,
- "endLine": 1196,
+ "endLine": 1199,
"file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
"message": "Operator \"<\" not supported for \"None\"",
"rule": "reportOptionalOperand",
"severity": "error",
"startCharacter": 12,
- "startLine": 1196
+ "startLine": 1199
},
{
"endCharacter": 41,
- "endLine": 1206,
+ "endLine": 1209,
"file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
"message": "Operator \">\" not supported for \"None\"",
"rule": "reportOptionalOperand",
"severity": "error",
"startCharacter": 12,
- "startLine": 1206
+ "startLine": 1209
},
{
"endCharacter": 66,
- "endLine": 1219,
+ "endLine": 1222,
"file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
"message": "Argument of type \"Any | None\" cannot be assigned to parameter \"timeframe\" of type \"str\" in function \"timeframe_to_prev_date\"\n Type \"Any | None\" is not assignable to type \"str\"\n \"None\" is not assignable to \"str\"",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 38,
- "startLine": 1219
+ "startLine": 1222
},
{
"endCharacter": 70,
- "endLine": 1350,
+ "endLine": 1353,
"file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
"message": "Expected 1 more positional argument",
"rule": "reportCallIssue",
"severity": "error",
"startCharacter": 48,
- "startLine": 1350
+ "startLine": 1353
},
{
"endCharacter": 74,
- "endLine": 1414,
+ "endLine": 1417,
"file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
"message": "Argument of type \"int | None\" cannot be assigned to parameter \"trade_duration_candles\" of type \"int\" in function \"get_trade_natr\"\n Type \"int | None\" is not assignable to type \"int\"\n \"None\" is not assignable to \"int\"",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 52,
- "startLine": 1414
+ "startLine": 1417
},
{
"endCharacter": 74,
- "endLine": 1441,
+ "endLine": 1444,
"file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
"message": "Argument of type \"int | None\" cannot be assigned to parameter \"trade_duration_candles\" of type \"int\" in function \"get_trade_natr\"\n Type \"int | None\" is not assignable to type \"int\"\n \"None\" is not assignable to \"int\"",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 52,
- "startLine": 1441
+ "startLine": 1444
},
{
"endCharacter": 96,
- "endLine": 1493,
+ "endLine": 1496,
"file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
"message": "Argument of type \"Any | None\" cannot be assigned to parameter \"timeframe\" of type \"str\" in function \"get_analyzed_dataframe\"\n Type \"Any | None\" is not assignable to type \"str\"\n \"None\" is not assignable to \"str\"",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 68,
- "startLine": 1493
+ "startLine": 1496
},
{
"endCharacter": 77,
- "endLine": 1523,
+ "endLine": 1526,
"file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
"message": "Operator \"<=\" not supported for \"None\"",
"rule": "reportOptionalOperand",
"severity": "error",
"startCharacter": 57,
- "startLine": 1523
+ "startLine": 1526
},
{
"endCharacter": 9,
- "endLine": 1528,
+ "endLine": 1531,
"file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
"message": "Operator \"+\" not supported for types \"float\" and \"float | None\"\n Operator \"+\" not supported for types \"float\" and \"None\"",
"rule": "reportOperatorIssue",
"severity": "error",
"startCharacter": 28,
- "startLine": 1526
+ "startLine": 1529
},
{
"endCharacter": 33,
- "endLine": 1527,
+ "endLine": 1530,
"file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
"message": "Operator \"-\" not supported for \"None\"",
"rule": "reportOptionalOperand",
"severity": "error",
"startCharacter": 13,
- "startLine": 1527
+ "startLine": 1530
},
{
"endCharacter": 67,
- "endLine": 1533,
+ "endLine": 1536,
"file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
"message": "Argument of type \"float | None\" cannot be assigned to parameter \"x\" of type \"ConvertibleToFloat\" in function \"__new__\"\n Type \"float | None\" is not assignable to type \"ConvertibleToFloat\"\n Type \"None\" is not assignable to type \"ConvertibleToFloat\"\n \"None\" is not assignable to \"str\"\n \"None\" is incompatible with protocol \"Buffer\"\n \"__buffer__\" is not present\n \"None\" is incompatible with protocol \"SupportsFloat\"\n \"__float__\" is not present\n \"None\" is incompatible with protocol \"SupportsIndex\"",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 47,
- "startLine": 1533
+ "startLine": 1536
},
{
"endCharacter": 67,
- "endLine": 1533,
+ "endLine": 1536,
"file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
"message": "Argument of type \"float | None\" cannot be assigned to parameter \"x\" of type \"ConvertibleToFloat\" in function \"__new__\"\n Type \"float | None\" is not assignable to type \"ConvertibleToFloat\"\n Type \"None\" is not assignable to type \"ConvertibleToFloat\"\n \"None\" is not assignable to \"str\"\n \"None\" is incompatible with protocol \"Buffer\"\n \"__buffer__\" is not present\n \"None\" is incompatible with protocol \"SupportsFloat\"\n \"__float__\" is not present\n \"None\" is incompatible with protocol \"SupportsIndex\"\n ...",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 47,
- "startLine": 1533
+ "startLine": 1536
},
{
"endCharacter": 64,
- "endLine": 1687,
+ "endLine": 1690,
"file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
"message": "\"isoformat\" is not a known attribute of \"None\"",
"rule": "reportOptionalMemberAccess",
"severity": "error",
"startCharacter": 55,
- "startLine": 1687
+ "startLine": 1690
},
{
"endCharacter": 37,
- "endLine": 1738,
+ "endLine": 1741,
"file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
"message": "Operator \"<=\" not supported for \"None\"",
"rule": "reportOptionalOperand",
"severity": "error",
"startCharacter": 15,
- "startLine": 1738
+ "startLine": 1741
},
{
"endCharacter": 48,
- "endLine": 1740,
+ "endLine": 1743,
"file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
"message": "Operator \"<=\" not supported for \"None\"",
"rule": "reportOptionalOperand",
"severity": "error",
"startCharacter": 15,
- "startLine": 1740
+ "startLine": 1743
},
{
"endCharacter": 96,
- "endLine": 1920,
+ "endLine": 1923,
"file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
"message": "Argument of type \"Any | None\" cannot be assigned to parameter \"timeframe\" of type \"str\" in function \"get_analyzed_dataframe\"\n Type \"Any | None\" is not assignable to type \"str\"\n \"None\" is not assignable to \"str\"",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 68,
- "startLine": 1920
+ "startLine": 1923
},
{
"endCharacter": 39,
- "endLine": 2023,
+ "endLine": 2026,
"file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
"message": "Operator \"+\" not supported for \"None\"",
"rule": "reportOptionalOperand",
"severity": "error",
"startCharacter": 21,
- "startLine": 2023
+ "startLine": 2026
},
{
"endCharacter": 90,
- "endLine": 2023,
+ "endLine": 2026,
"file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
"message": "Operator \"*\" not supported for types \"float\" and \"Any | None\"\n Operator \"*\" not supported for types \"float\" and \"None\"",
"rule": "reportOperatorIssue",
"severity": "error",
"startCharacter": 62,
- "startLine": 2023
+ "startLine": 2026
},
{
"endCharacter": 96,
- "endLine": 2325,
+ "endLine": 2328,
"file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
"message": "Argument of type \"Any | None\" cannot be assigned to parameter \"timeframe\" of type \"str\" in function \"get_analyzed_dataframe\"\n Type \"Any | None\" is not assignable to type \"str\"\n \"None\" is not assignable to \"str\"",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 68,
- "startLine": 2325
+ "startLine": 2328
},
{
"endCharacter": 85,
- "endLine": 2350,
+ "endLine": 2353,
"file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
"message": "\"isoformat\" is not a known attribute of \"None\"",
"rule": "reportOptionalMemberAccess",
"severity": "error",
"startCharacter": 76,
- "startLine": 2350
+ "startLine": 2353
},
{
"endCharacter": 47,
- "endLine": 2356,
+ "endLine": 2359,
"file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
"message": "Operator \"<\" not supported for \"None\"",
"rule": "reportOptionalOperand",
"severity": "error",
"startCharacter": 16,
- "startLine": 2356
+ "startLine": 2359
},
{
"endCharacter": 69,
- "endLine": 2363,
+ "endLine": 2366,
"file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
"message": "Argument of type \"int | float\" cannot be assigned to parameter \"lookback_period_candles\" of type \"int\" in function \"reversal_confirmed\"\n Type \"int | float\" is not assignable to type \"int\"\n \"float\" is not assignable to \"int\"",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 16,
- "startLine": 2363
+ "startLine": 2366
},
{
"endCharacter": 47,
- "endLine": 2374,
+ "endLine": 2377,
"file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
"message": "Operator \">\" not supported for \"None\"",
"rule": "reportOptionalOperand",
"severity": "error",
"startCharacter": 16,
- "startLine": 2374
+ "startLine": 2377
},
{
"endCharacter": 69,
- "endLine": 2381,
+ "endLine": 2384,
"file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
"message": "Argument of type \"int | float\" cannot be assigned to parameter \"lookback_period_candles\" of type \"int\" in function \"reversal_confirmed\"\n Type \"int | float\" is not assignable to type \"int\"\n \"float\" is not assignable to \"int\"",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 16,
- "startLine": 2381
+ "startLine": 2384
},
{
"endCharacter": 52,
- "endLine": 2410,
+ "endLine": 2413,
"file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
"message": "Argument of type \"datetime | None\" cannot be assigned to parameter \"current_candle_date\" of type \"datetime\" in function \"_normalize_final_take_profit_state\"\n Type \"datetime | None\" is not assignable to type \"datetime\"\n \"None\" is not assignable to \"datetime\"",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 36,
- "startLine": 2410
+ "startLine": 2413
},
{
"endCharacter": 96,
- "endLine": 2530,
+ "endLine": 2533,
"file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
"message": "Argument of type \"Any | None\" cannot be assigned to parameter \"timeframe\" of type \"str\" in function \"get_analyzed_dataframe\"\n Type \"Any | None\" is not assignable to type \"str\"\n \"None\" is not assignable to \"str\"",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 68,
- "startLine": 2530
+ "startLine": 2533
},
{
"endCharacter": 69,
- "endLine": 2541,
+ "endLine": 2544,
"file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
"message": "Argument of type \"int | float\" cannot be assigned to parameter \"lookback_period_candles\" of type \"int\" in function \"reversal_confirmed\"\n Type \"int | float\" is not assignable to type \"int\"\n \"float\" is not assignable to \"int\"",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 16,
- "startLine": 2541
+ "startLine": 2544
},
{
"endCharacter": 32,
- "endLine": 2621,
+ "endLine": 2624,
"file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
"message": "Argument of type \"LocalTrade\" cannot be assigned to parameter \"trade\" of type \"Trade\" in function \"get_trade_annotation_line_start_date\"\n \"LocalTrade\" is not assignable to \"Trade\"",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 27,
- "startLine": 2621
+ "startLine": 2624
},
{
"endCharacter": 72,
- "endLine": 2624,
+ "endLine": 2627,
"file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
"message": "Argument of type \"LocalTrade\" cannot be assigned to parameter \"trade\" of type \"Trade\" in function \"get_trade_exit_stage\"\n \"LocalTrade\" is not assignable to \"Trade\"",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 67,
- "startLine": 2624
+ "startLine": 2627
},
{
"endCharacter": 36,
- "endLine": 2631,
+ "endLine": 2634,
"file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
"message": "Argument of type \"LocalTrade\" cannot be assigned to parameter \"trade\" of type \"Trade\" in function \"get_take_profit_target\"\n \"LocalTrade\" is not assignable to \"Trade\"",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 31,
- "startLine": 2631
+ "startLine": 2634
},
{
"endCharacter": 71,
- "endLine": 2662,
+ "endLine": 2665,
"file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
"message": "Argument of type \"LocalTrade\" cannot be assigned to parameter \"trade\" of type \"Trade\" in function \"get_trade_entry_date\"\n \"LocalTrade\" is not assignable to \"Trade\"",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 66,
- "startLine": 2662
+ "startLine": 2665
},
{
"endCharacter": 32,
- "endLine": 2695,
+ "endLine": 2698,
"file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
"message": "Argument of type \"LocalTrade\" cannot be assigned to parameter \"trade\" of type \"Trade\" in function \"get_take_profit_target\"\n \"LocalTrade\" is not assignable to \"Trade\"",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 27,
- "startLine": 2695
+ "startLine": 2698
},
{
"endCharacter": 35,
"startLine": 6157
}
],
- "filesAnalyzed": 5,
+ "filesAnalyzed": 6,
"schemaVersion": 4,
"sourceFiles": [
"quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
+ "quickadapter/user_data/strategies/BacktestIdentity.py",
"quickadapter/user_data/strategies/EnumErrors.py",
"quickadapter/user_data/strategies/LabelTransformer.py",
"quickadapter/user_data/strategies/QuickAdapterV3.py",
## Backtest cache reuse
+Native result-cache reuse also checks implementation and runtime versions; see
+[backtest result caching](../docs/evaluation.md#backtest-result-caching).
+The model/prediction cache below is a separate layer.
+
Backtests store reusable models and predictions under
`models/<identifier>/backtesting/<fingerprint>/`. Cache identity includes input
data, effective model and strategy configuration (including settings outside
--- /dev/null
+"""Native result-cache behavior across implementation and SDK changes."""
+
+from qa_support import REPO_ROOT, QaTestCase, model_config, temporary_directory
+
+from scripts.backtest_cache_contract import (
+ assert_native_implementation_cache,
+ assert_native_startup_predictions,
+)
+
+
+class NativeResultCacheTest(QaTestCase):
+ def test_native_startup_and_predictions_do_not_require_test_pythonpath(self):
+ with temporary_directory() as directory:
+ assert_native_startup_predictions(
+ self, directory, model_config, REPO_ROOT / "quickadapter"
+ )
+
+ def test_implementation_changes_reject_results_but_unchanged_inputs_reuse_them(self):
+ with temporary_directory() as directory:
+ assert_native_implementation_cache(
+ self,
+ directory,
+ model_config,
+ "QuickAdapterV3",
+ REPO_ROOT / "quickadapter",
+ "from quickadapter.user_data.freqaimodels.QuickAdapterRegressorV3 import QuickAdapterRegressorV3 as CacheBase",
+ )
from datetime import datetime, timezone
from functools import cached_property, wraps
from hashlib import sha256
-from importlib.metadata import version as distribution_version
-from inspect import getfile, iscoroutinefunction, unwrap
+from inspect import iscoroutinefunction, unwrap
from pathlib import Path
from types import MethodType
from typing import (
import scipy as sp
import skimage
import sklearn
+from BacktestIdentity import implementation_fingerprint
from datasieve.pipeline import Pipeline
from datasieve.transforms import SKLearnWrapper
from freqtrade.enums import TRADE_MODES, RunMode
FreqaiDataDrawer,
)
from freqtrade.freqai.data_kitchen import FreqaiDataKitchen
-from freqtrade.strategy.interface import IStrategy
# Disabled: scikit-learn-extra 0.3.0 fails on Python 3.14 (__gxx_personality_v0).
# from sklearn_extra.cluster import KMedoids
},
"pair": pair,
"labels": {label: strategy.get_label_params(pair, label) for label in LABEL_COLUMNS},
- "versions": {
- name: distribution_version(name)
- for name in (
- "freqtrade",
- "datasieve",
- "numpy",
- "pandas",
- "scipy",
- "scikit-learn",
- "optuna",
- "optuna-integration",
- "xgboost",
- "lightgbm",
- "catboost",
- "ngboost",
- )
- },
- }
- sdk_classes = set(BaseRegressionModel.__mro__) | set(IStrategy.__mro__)
- implementations = {
- role: [cls for cls in leaf.__mro__ if cls not in sdk_classes]
- for role, leaf in (("strategy", type(strategy)), ("model", type(self)))
- }
- configuration["implementations"] = {
- role: [(cls.__module__, cls.__qualname__) for cls in classes]
- for role, classes in implementations.items()
+ "implementation": implementation_fingerprint(
+ {"strategy": type(strategy), "model": type(self)}
+ ),
}
- source_cache: dict[tuple[str, str | Path], bytes] = {}
- sources: dict[tuple[str, bytes], None] = {}
-
- def add_source(path: str | Path, snapshot: str | None = None) -> None:
- key = ("snapshot", snapshot) if snapshot is not None else ("file", Path(path).resolve())
- if key not in source_cache:
- source_cache[key] = (
- snapshot.encode() if snapshot is not None else Path(path).read_bytes()
- )
- sources[(Path(path).name, source_cache[key])] = None
-
- for classes in implementations.values():
- leaf = classes[0]
- for cls in classes:
- snapshot = cls.__dict__.get("__source__")
- path = cls.__dict__.get("__file__")
- if snapshot is None and path is None and cls.__module__ == leaf.__module__:
- snapshot = leaf.__dict__.get("__source__")
- path = leaf.__dict__.get("__file__")
- if snapshot is None and path is None:
- path = getfile(cls)
- add_source(path or cls.__module__, snapshot)
- for path in (Path(__file__), Path(getfile(LabelTransformer)), Path(getfile(fit_regressor))):
- add_source(path)
digest.update(json.dumps(configuration, sort_keys=True, default=str).encode())
- for label, payload in sources:
- digest.update(label.encode())
- digest.update(payload)
columns = [(column, str(dtype)) for column, dtype in prepared.dtypes.items()]
digest.update(json.dumps(columns).encode())
try:
--- /dev/null
+"""Implementation identity for native result and FreqAI prediction caches.
+
+Keep both standalone strategy copies identical. Native resolver search and class
+source metadata are private SDK contracts; recheck them on Freqtrade upgrades.
+"""
+
+import ast
+import json
+import platform
+import sys
+from collections.abc import Iterator, Mapping
+from hashlib import sha256
+from importlib.metadata import PackageNotFoundError, version
+from importlib.util import resolve_name
+from inspect import getfile, isfunction, unwrap
+from pathlib import Path
+from types import ModuleType
+from typing import Any, Final
+
+import freqtrade
+from freqtrade.exceptions import OperationalException
+from freqtrade.resolvers.freqaimodel_resolver import FreqaiModelResolver
+
+_IMPLEMENTATION_KEY: Final = "_freqai_strategies_implementation"
+_COMMON_DEPENDENCIES: Final = (
+ "freqtrade",
+ "datasieve",
+ "numpy",
+ "pandas",
+ "scipy",
+ "scikit-learn",
+ "optuna",
+ "optuna-integration",
+ "optunahub",
+ "cmaes",
+ "torch",
+ "botorch",
+ "gpytorch",
+ "filelock",
+ "joblib",
+ "cloudpickle",
+ "TA-Lib",
+ "technical",
+ "pandas-ta",
+)
+_REGRESSION_DEPENDENCIES: Final = ("xgboost", "lightgbm", "catboost", "ngboost", "scikit-image")
+_RL_DEPENDENCIES: Final = ("gymnasium", "stable-baselines3", "sb3-contrib")
+
+
+def _import_namespaces(source: bytes, package: str) -> Iterator[dict[str, Any]]:
+ """Find loaded imports even when a native-resolved leaf owns no methods."""
+ for node in ast.walk(ast.parse(source)):
+ if isinstance(node, ast.Import):
+ names = [alias.name for alias in node.names]
+ elif isinstance(node, ast.ImportFrom):
+ name = node.module or ""
+ if node.level:
+ if not package:
+ continue
+ try:
+ name = resolve_name("." * node.level + name, package)
+ except ImportError:
+ continue
+ names = [name, *(f"{name}.{alias.name}" for alias in node.names)]
+ else:
+ continue
+ for name in names:
+ module = sys.modules.get(name)
+ if module is not None:
+ yield vars(module)
+
+
+def _class_namespaces(cls: type) -> Iterator[dict[str, Any]]:
+ """Use actual function globals: native-resolved modules may be unregistered."""
+ for member in vars(cls).values():
+ if isinstance(member, (staticmethod, classmethod)):
+ member = member.__func__
+ elif isinstance(member, property):
+ member = member.fget
+ if callable(member):
+ member = unwrap(member)
+ if isfunction(member):
+ yield member.__globals__
+ module = sys.modules.get(cls.__module__)
+ # Data-only imported classes have no function globals. Reject name collisions.
+ if module is not None and vars(module).get(cls.__name__) is cls:
+ yield vars(module)
+
+
+def implementation_fingerprint(implementations: Mapping[str, type]) -> str:
+ """Hash selected classes, reachable local helpers and release dependencies.
+
+ Paths locate sources but are not part of identity. Resolver snapshots take
+ precedence over disk source. Local helper traversal stays inside directories
+ containing selected non-SDK MRO implementations; it never scans user data or
+ installed packages. Version metadata does not detect same-version SDK/binary
+ modifications. File hashes are not memoized across strategy constructions.
+ """
+ classes = {role: list(leaf.__mro__[:-1]) for role, leaf in implementations.items()}
+ local_classes = [
+ cls
+ for lineage in classes.values()
+ for cls in lineage
+ if cls.__module__ != "abc" and not cls.__module__.startswith("freqtrade.")
+ ]
+ sources: dict[tuple[str, bytes], None] = {}
+ source_cache: dict[tuple[str, str | Path], bytes] = {}
+ snapshots: dict[Path, str] = {}
+ imports: dict[tuple[bytes, str], tuple[dict[str, Any], ...]] = {}
+ directories: set[Path] = set()
+ namespaces: list[dict[str, Any]] = []
+
+ def add_source(path: str | Path, snapshot: str | None = None) -> bytes:
+ key = ("snapshot", snapshot) if snapshot is not None else ("file", Path(path).resolve())
+ if key not in source_cache:
+ source_cache[key] = (
+ snapshot.encode() if snapshot is not None else Path(path).read_bytes()
+ )
+ sources[(Path(path).name, source_cache[key])] = None
+ return source_cache[key]
+
+ def imported_namespaces(payload: bytes, package: str) -> tuple[dict[str, Any], ...]:
+ key = (payload, package)
+ if key not in imports:
+ imports[key] = tuple(_import_namespaces(payload, package))
+ return imports[key]
+
+ for lineage in classes.values():
+ leaf = lineage[0]
+ for cls in lineage:
+ if cls not in local_classes:
+ continue
+ snapshot = cls.__dict__.get("__source__")
+ path = cls.__dict__.get("__file__")
+ if snapshot is None and path is None and cls.__module__ == leaf.__module__:
+ snapshot = leaf.__dict__.get("__source__")
+ path = leaf.__dict__.get("__file__")
+ if snapshot is None and path is None:
+ path = getfile(cls)
+ payload = add_source(path or cls.__module__, snapshot)
+ if path is not None:
+ resolved = Path(path).resolve()
+ directories.add(resolved.parent)
+ if snapshot is not None:
+ snapshots[resolved] = snapshot
+ namespaces.extend(_class_namespaces(cls))
+ namespaces.extend(imported_namespaces(payload, cls.__module__.rpartition(".")[0]))
+
+ visited: set[int] = set()
+ while namespaces:
+ namespace = namespaces.pop()
+ if id(namespace) in visited:
+ continue
+ visited.add(id(namespace))
+ filename = namespace.get("__file__")
+ if filename is None:
+ continue
+ path = Path(filename).resolve()
+ if not any(path.is_relative_to(directory) for directory in directories):
+ continue
+ payload = add_source(path, snapshots.get(path))
+ namespaces.extend(imported_namespaces(payload, namespace.get("__package__") or ""))
+ for value in tuple(namespace.values()):
+ if callable(value):
+ value = unwrap(value)
+ if isfunction(value):
+ namespaces.append(value.__globals__)
+ elif isinstance(value, ModuleType):
+ namespaces.append(vars(value))
+ elif isinstance(value, type):
+ namespaces.extend(_class_namespaces(value))
+
+ add_source(__file__)
+ rl = any(
+ cls.__module__.startswith("freqtrade.freqai.RL.")
+ for lineage in classes.values()
+ for cls in lineage
+ )
+ dependencies = _COMMON_DEPENDENCIES + (_RL_DEPENDENCIES if rl else _REGRESSION_DEPENDENCIES)
+ versions: dict[str, str | None] = {}
+ for name in dependencies:
+ try:
+ versions[name] = version(name)
+ except PackageNotFoundError:
+ versions[name] = None
+ configuration = {
+ "python": platform.python_version(),
+ "sdk": freqtrade.__version__,
+ "versions": versions,
+ "implementations": {
+ role: [(cls.__module__, cls.__qualname__) for cls in lineage]
+ for role, lineage in classes.items()
+ },
+ }
+ digest = sha256(json.dumps(configuration, sort_keys=True).encode())
+ for label, payload in sorted(sources):
+ digest.update(json.dumps((label, len(payload))).encode())
+ digest.update(payload)
+ return digest.hexdigest()
+
+
+def bind_backtest_implementation(strategy: Any) -> None:
+ """Extend native result identity without model construction or storage changes."""
+ config = strategy.config
+ model_name = config.get("freqaimodel")
+ if not config.get("freqai", {}).get("enabled", False) or not model_name:
+ config.pop(_IMPLEMENTATION_KEY, None)
+ return
+ if model_name == "BaseRegressionModel":
+ raise OperationalException(
+ "BaseRegressionModel is a baseclass and cannot be used directly. "
+ "Please choose an existing child class or inherit from this baseclass."
+ )
+ paths = FreqaiModelResolver.build_search_paths(config, FreqaiModelResolver.user_subdir)
+ for path in paths:
+ try:
+ model, _ = FreqaiModelResolver._search_object(
+ directory=path, object_name=model_name, add_source=True
+ )
+ except FileNotFoundError:
+ continue
+ if model is not None:
+ config[_IMPLEMENTATION_KEY] = implementation_fingerprint(
+ {
+ "strategy": type(strategy),
+ "model": model,
+ }
+ )
+ return
+ raise OperationalException(
+ f"Impossible to load FreqaiModel '{model_name}'. "
+ "This class does not exist or contains Python code errors."
+ )
import numpy as np
import pandas_ta as pta
import talib.abstract as ta
+from BacktestIdentity import bind_backtest_implementation
from freqtrade.constants import EntryExit, LongShort
-from freqtrade.enums import TRADE_MODES
+from freqtrade.enums import TRADE_MODES, RunMode
from freqtrade.exchange import (
timeframe_to_minutes,
timeframe_to_prev_date,
migrate_config(config, logger)
normalize_fit_live_predictions_config(config, logger)
super().__init__(config, *args, **kwargs)
+ if config.get("runmode") in (RunMode.BACKTEST, RunMode.HYPEROPT):
+ bind_backtest_implementation(self)
if self.is_trade_runmode and self.config.get("api_server", {}).get("enabled", False):
_install_rpc_custom_data_cleanup_patch()
exit_minimum_value = (exit_minimum or 0.0) * trade.leverage
remaining_minimum_value = (remaining_minimum or 0.0) * trade.leverage
if not self.is_trade_runmode:
- # Backtesting guards quote notional against its unleveraged callback minimum.
+ # Preserve the native backtest remainder guard across SDK minimum conventions.
remaining_minimum_value = max(remaining_minimum_value, min_stake or 0.0)
remaining_minimum_value *= 1.0 + QuickAdapterV3._PARTIAL_EXIT_MIN_STAKE_MARGIN
current_position_value = trade.amount * current_exit_rate
--- /dev/null
+"""Exercise native startup and result-cache contracts for standalone strategies."""
+
+import importlib
+import json
+import os
+import subprocess
+import sys
+from copy import deepcopy
+from importlib.metadata import version as distribution_version
+from pathlib import Path
+from types import ModuleType
+from typing import Any
+from unittest import mock
+
+import freqtrade
+from freqtrade.configuration import TimeRange
+from freqtrade.enums import RunMode
+from freqtrade.optimize.backtest_caching import get_strategy_run_id
+from freqtrade.optimize.backtesting import Backtesting
+from freqtrade.optimize.optimize_reports.bt_storage import store_backtest_results
+from freqtrade.resolvers import StrategyResolver
+from freqtrade.util import dt_now
+
+
+def assert_native_implementation_cache(
+ test: Any,
+ directory: Path,
+ config_factory: Any,
+ strategy_name: str,
+ project: Path,
+ model_import: str,
+) -> None:
+ """A real native archive must hit unchanged inputs and miss changed code/SDK."""
+ implementations = directory / "implementations"
+ implementations.mkdir()
+ helper_name = f"_cache_helper_{directory.name.replace('-', '_')}"
+ helper = implementations / f"{helper_name}.py"
+ helper.write_text("VALUE = 1\ndef coefficient():\n return VALUE\n")
+ model_path = implementations / "cache_model.py"
+ model_source = (
+ f"{model_import}\n"
+ f"from {helper_name} import coefficient\n"
+ "class CacheModel(CacheBase):\n"
+ " def __init__(self, *args, **kwargs):\n"
+ " raise AssertionError('Identity must not construct a model')\n"
+ " def cache_coefficient(self):\n"
+ " return coefficient()\n"
+ )
+ model_path.write_text(model_source)
+ config = config_factory(directory)
+ config.update(
+ runmode=RunMode.BACKTEST,
+ strategy=strategy_name,
+ freqaimodel="CacheModel",
+ freqaimodel_path=str(implementations),
+ backtest_cache="day",
+ )
+ output = directory / "backtest_results"
+ output.mkdir()
+ test.addCleanup(sys.modules.pop, helper_name, None)
+ # Native exec_module does not register cache_model. A colliding module must
+ # not replace the selected class's actual globals or imported helper source.
+ collision = ModuleType("cache_model")
+ collision.__file__ = str(implementations / "unrelated.py")
+
+ def load():
+ return StrategyResolver._load_strategy(
+ strategy_name, config, extra_dir=str(project / "user_data/strategies")
+ )
+
+ def cached(strategy):
+ backtest = object.__new__(Backtesting)
+ backtest.config = strategy.config
+ backtest.strategylist = [strategy]
+ backtest.results = {}
+ backtest.timerange = TimeRange.parse_timerange("20260101-20260102")
+ backtest.load_prior_backtest()
+ return backtest.results.get("strategy", {})
+
+ def store(strategy):
+ metadata = {
+ "run_id": get_strategy_run_id(strategy),
+ "backtest_start_time": int(dt_now().timestamp()),
+ "backtest_start_ts": 1761955200,
+ "backtest_end_ts": 1762041600,
+ "timeframe": "5m",
+ }
+ store_backtest_results(
+ {"exportdirectory": output, "original_config": config},
+ {
+ "metadata": {strategy_name: metadata},
+ "strategy": {strategy_name: {"profit_total": 0.125}},
+ "strategy_comparison": [{"key": strategy_name}],
+ },
+ dt_now().strftime("%Y-%m-%d_%H-%M-%S"),
+ strategy_files={strategy_name: strategy.__file__},
+ )
+
+ with mock.patch.dict(sys.modules, {"cache_model": collision}):
+ store(load())
+ test.assertEqual(cached(load())[strategy_name]["profit_total"], 0.125)
+ nested = config["freqai"]
+ snapshot = deepcopy(nested)
+ config["api_server"] = {"enabled": False, "username": "unrelated-cache-setting"}
+ config["telegram"] = {"enabled": False}
+ (implementations / "unrelated.py").write_text("UNUSED = 123\n")
+ test.assertEqual(cached(load())[strategy_name]["profit_total"], 0.125)
+ test.assertIs(config["freqai"], nested)
+ test.assertEqual(nested, snapshot)
+ with mock.patch.object(freqtrade, "__version__", freqtrade.__version__ + "+cache-change"):
+ test.assertNotIn(strategy_name, cached(load()))
+ test.assertEqual(cached(load())[strategy_name]["profit_total"], 0.125)
+
+ def upgraded_dependency(name):
+ return "999.0+cache-test" if name == "torch" else distribution_version(name)
+
+ with mock.patch("BacktestIdentity.version", side_effect=upgraded_dependency):
+ test.assertNotIn(strategy_name, cached(load()))
+ test.assertEqual(cached(load())[strategy_name]["profit_total"], 0.125)
+ helper.write_text("VALUE = -1\ndef coefficient():\n return VALUE\n")
+ importlib.invalidate_caches()
+ test.assertNotIn(strategy_name, cached(load()))
+ helper.write_text("VALUE = 1\ndef coefficient():\n return VALUE\n")
+ model_path.write_text(model_source + "\nMODEL_REVISION = 2\n")
+ test.assertNotIn(strategy_name, cached(load()))
+ model_path.write_text(model_source)
+ test.assertEqual(cached(load())[strategy_name]["profit_total"], 0.125)
+ base_name = helper_name + "_base"
+ test.addCleanup(sys.modules.pop, base_name, None)
+ (implementations / f"{base_name}.py").write_text(
+ f"{model_import}\n"
+ "class CacheParent(CacheBase):\n"
+ " def __init__(self, *args, **kwargs):\n"
+ " raise AssertionError('Identity must not construct a model')\n"
+ " def cache_coefficient(self):\n"
+ " return self.cache_scale\n"
+ )
+ model_path.write_text(
+ f"from {base_name} import CacheParent\n"
+ f"import {helper_name} as settings\n"
+ "class CacheModel(CacheParent):\n"
+ " cache_scale = settings.VALUE\n"
+ )
+ sys.modules.pop("cache_model")
+ store(load())
+ test.assertEqual(cached(load())[strategy_name]["profit_total"], 0.125)
+ helper.write_text("VALUE = 0.5\ndef coefficient():\n return VALUE\n")
+ test.assertNotIn(strategy_name, cached(load()))
+ trainer_name = helper_name + "_trainer"
+ test.addCleanup(sys.modules.pop, trainer_name, None)
+ (implementations / f"{trainer_name}.py").write_text(
+ "def forbidden_init(self, *args, **kwargs):\n"
+ " raise AssertionError('Identity must not construct a model')\n"
+ )
+ helper.write_text("VALUE = 1\ndef coefficient():\n return VALUE\n")
+ model_path.write_text(
+ f"from {base_name} import CacheParent\n"
+ f"from {trainer_name} import forbidden_init\n"
+ f"import {helper_name} as settings\n"
+ "class CacheModel(CacheParent):\n"
+ " __init__ = forbidden_init\n"
+ " cache_scale = settings.VALUE\n"
+ )
+ store(load())
+ test.assertEqual(cached(load())[strategy_name]["profit_total"], 0.125)
+ helper.write_text("VALUE = 0.5\ndef coefficient():\n return VALUE\n")
+ test.assertNotIn(strategy_name, cached(load()))
+ helper.write_text(
+ "from functools import lru_cache\n"
+ "VALUE = 1\n@lru_cache(None)\ndef coefficient():\n return VALUE\n"
+ )
+ sys.modules.pop(helper_name)
+ model_path.write_text(model_source)
+ sys.modules["cache_model"] = collision
+ store(load())
+ test.assertEqual(cached(load())[strategy_name]["profit_total"], 0.125)
+ helper.write_text(
+ "from functools import lru_cache\n"
+ "VALUE = 0.5\n@lru_cache(None)\ndef coefficient():\n return VALUE\n"
+ )
+ test.assertNotIn(strategy_name, cached(load()))
+
+
+def assert_native_startup_predictions(
+ test: Any, directory: Path, config_factory: Any, project: Path
+) -> None:
+ """Train and predict in a fresh interpreter without QA's strategy PYTHONPATH."""
+ config = config_factory(directory)
+ info = config["freqai"]
+ if project.name == "quickadapter":
+ info["optuna_hyperopt"]["enabled"] = False
+ info["model_training_parameters"]["random_state"] = 42
+ else:
+ info["model_training_parameters"]["seed"] = 42
+ config_path = directory / "startup.json"
+ program = """
+import json
+import sys
+from pathlib import Path
+import numpy as np
+import pandas as pd
+from freqtrade.configuration import Configuration
+from freqtrade.configuration.load_config import load_config_file
+from freqtrade.enums import RunMode
+from freqtrade.freqai.data_kitchen import FreqaiDataKitchen
+from freqtrade.resolvers import StrategyResolver
+from freqtrade.resolvers.freqaimodel_resolver import FreqaiModelResolver
+project = Path(sys.argv[1])
+source = project / 'user_data'
+options_path = Path(sys.argv[2])
+options = json.loads(options_path.read_text())
+mode = sys.argv[3]
+config = load_config_file(source / 'config-template.json')
+options['exchange'] = config['exchange'] | options['exchange']
+config.update(options)
+config['user_data_dir'] = str(Path(config['user_data_dir']) / mode)
+Path(config['user_data_dir']).mkdir(parents=True, exist_ok=True)
+quick = project.name == 'quickadapter'
+config.update(strategy='QuickAdapterV3' if quick else 'RLAgentStrategy',
+ freqaimodel='QuickAdapterRegressorV3' if quick else 'ReforceXY',
+ strategy_path=str(source / 'strategies'),
+ freqaimodel_path=str(source / 'freqaimodels'))
+options_path.write_text(json.dumps(config, default=str))
+config = Configuration({'config': [str(options_path)]}, RunMode(mode)).get_config()
+strategy = StrategyResolver.load_strategy(config)
+owner = FreqaiModelResolver.load_freqaimodel(config)
+owner.live = True
+owner.can_short = False
+index = np.arange(64)
+label = '&s-extrema' if quick else '&-action'
+frame = pd.DataFrame({'date': pd.date_range('2026-01-01', periods=64, freq='5min', tz='UTC'),
+ '%-feature': np.sin(index / 4),
+ label: np.cos(index / 5) if quick else np.zeros(64)})
+if not quick:
+ for column in ('open', 'high', 'low', 'close'):
+ frame['%-raw_' + column] = 100 + index * 0.1
+kitchen = FreqaiDataKitchen(config, live=True, pair='BTC/USDT')
+kitchen.set_paths(kitchen.pair, 1767225600)
+kitchen.set_new_model_names(kitchen.pair, 1767225600)
+kitchen.data_path.mkdir(parents=True, exist_ok=True)
+kitchen.training_features_list = [name for name in frame if name.startswith('%')]
+kitchen.label_list = [label]
+try:
+ owner.model = owner.train(frame, kitchen.pair, kitchen)
+ owner.live = False
+ predictions, status = owner.predict(frame, kitchen)
+ assert np.isfinite(predictions[label]).all()
+ assert np.all(status == 1)
+ if not quick:
+ assert predictions[label].isin([0, 1, 2]).all()
+ print('NATIVE_PREDICTIONS=' + json.dumps({
+ 'rows': len(predictions), 'valid_rows': int(np.sum(status == 1)),
+ 'runmode': str(config['runmode']),
+ 'strategy_directory_on_path': str(source / 'strategies') in sys.path}))
+finally:
+ if not quick:
+ owner.close_envs()
+"""
+ environment = dict(os.environ)
+ environment.pop("PYTHONPATH", None)
+ for mode in ("dry_run", "backtest", "hyperopt"):
+ with test.subTest(runmode=mode):
+ config_path.write_text(json.dumps(config, default=str))
+ result = subprocess.run(
+ [sys.executable, "-P", "-c", program, str(project), str(config_path), mode],
+ cwd=directory,
+ env=environment,
+ capture_output=True,
+ text=True,
+ timeout=90,
+ check=False,
+ )
+ test.assertEqual(result.returncode, 0, result.stdout + result.stderr)
+ line = next(
+ row for row in result.stdout.splitlines() if row.startswith("NATIVE_PREDICTIONS=")
+ )
+ outcome = json.loads(line.removeprefix("NATIVE_PREDICTIONS="))
+ test.assertEqual(outcome["rows"], 64)
+ test.assertEqual(outcome["valid_rows"], 64)
+ test.assertEqual(outcome["runmode"], mode)
+ test.assertFalse(outcome["strategy_directory_on_path"])