"diagnostics": [
{
"endCharacter": 58,
- "endLine": 324,
+ "endLine": 323,
"file": "ReforceXY/reward_space_analysis/reward_space_analysis.py",
"message": "Type \"RewardParamValue\" is not assignable to declared type \"bool | None\"\n Type \"RewardParamValue\" is not assignable to type \"bool | None\"\n Type \"float\" is not assignable to type \"bool | None\"\n \"float\" is not assignable to \"bool\"\n \"float\" is not assignable to \"None\"",
"rule": "reportAssignmentType",
"severity": "error",
"startCharacter": 18,
- "startLine": 324
+ "startLine": 323
},
{
"endCharacter": 92,
- "endLine": 551,
+ "endLine": 571,
"file": "ReforceXY/reward_space_analysis/reward_space_analysis.py",
"message": "Argument of type \"RewardParamValue\" cannot be assigned to parameter \"x\" of type \"ConvertibleToInt\" in function \"__new__\"\n Type \"RewardParamValue\" 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": 22,
- "startLine": 551
+ "startLine": 571
},
{
"endCharacter": 92,
- "endLine": 551,
+ "endLine": 571,
"file": "ReforceXY/reward_space_analysis/reward_space_analysis.py",
"message": "Argument of type \"RewardParamValue\" cannot be assigned to parameter \"x\" of type \"ConvertibleToInt\" in function \"__new__\"\n Type \"RewardParamValue\" 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": 22,
- "startLine": 551
+ "startLine": 571
},
{
"endCharacter": 5,
- "endLine": 2048,
+ "endLine": 2095,
"file": "ReforceXY/reward_space_analysis/reward_space_analysis.py",
"message": "No overloads for \"cut\" match the provided arguments",
"rule": "reportCallIssue",
"severity": "error",
"startCharacter": 17,
- "startLine": 2043
+ "startLine": 2090
},
{
"endCharacter": 21,
- "endLine": 2045,
+ "endLine": 2092,
"file": "ReforceXY/reward_space_analysis/reward_space_analysis.py",
"message": "Argument of type \"_Array1D[Any]\" cannot be assigned to parameter \"bins\" of type \"int | Sequence[float] | Index[int] | Index[float] | IntervalIndex[Interval[Any]] | Series[Any]\" in function \"cut\"\n Type \"_Array1D[Any]\" is not assignable to type \"int | Sequence[float] | Index[int] | Index[float] | IntervalIndex[Interval[Any]] | Series[Any]\"\n \"ndarray[tuple[int], dtype[Any]]\" is not assignable to \"int\"\n \"ndarray[tuple[int], dtype[Any]]\" is not assignable to \"Sequence[float]\"\n \"ndarray[tuple[int], dtype[Any]]\" is not assignable to \"Index[int]\"\n \"ndarray[tuple[int], dtype[Any]]\" is not assignable to \"Index[float]\"\n \"ndarray[tuple[int], dtype[Any]]\" is not assignable to \"IntervalIndex[Interval[Any]]\"\n \"ndarray[tuple[int], dtype[Any]]\" is not assignable to \"Series[Any]\"",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 13,
- "startLine": 2045
+ "startLine": 2092
},
{
"endCharacter": 5,
- "endLine": 2070,
+ "endLine": 2117,
"file": "ReforceXY/reward_space_analysis/reward_space_analysis.py",
"message": "Type \"dict[bytes, bytes] | dict[str, RewardParamValue]\" is not assignable to declared type \"RewardParams\"\n Type \"dict[bytes, bytes] | dict[str, RewardParamValue]\" is not assignable to type \"RewardParams\"\n \"dict[bytes, bytes]\" is not assignable to \"dict[str, RewardParamValue]\"\n Type parameter \"_KT@dict\" is invariant, but \"bytes\" is not the same as \"str\"\n Type parameter \"_VT@dict\" is invariant, but \"bytes\" is not the same as \"RewardParamValue\"",
"rule": "reportAssignmentType",
"severity": "error",
"startCharacter": 34,
- "startLine": 2066
+ "startLine": 2113
},
{
"endCharacter": 43,
- "endLine": 2067,
+ "endLine": 2114,
"file": "ReforceXY/reward_space_analysis/reward_space_analysis.py",
"message": "No overloads for \"__init__\" match the provided arguments",
"rule": "reportCallIssue",
"severity": "error",
"startCharacter": 8,
- "startLine": 2067
+ "startLine": 2114
},
{
"endCharacter": 42,
- "endLine": 2067,
+ "endLine": 2114,
"file": "ReforceXY/reward_space_analysis/reward_space_analysis.py",
"message": "Argument of type \"Any | None\" cannot be assigned to parameter \"iterable\" of type \"Iterable[list[bytes]]\" in function \"__init__\"\n Type \"Any | None\" is not assignable to type \"Iterable[list[bytes]]\"\n \"None\" is incompatible with protocol \"Iterable[list[bytes]]\"\n \"__iter__\" is not present",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 13,
- "startLine": 2067
+ "startLine": 2114
},
{
"endCharacter": 60,
- "endLine": 2327,
+ "endLine": 2374,
"file": "ReforceXY/reward_space_analysis/reward_space_analysis.py",
"message": "Cannot access attribute \"importances_mean\" for class \"dict[Unknown, Bunch]\"\n Attribute \"importances_mean\" is unknown",
"rule": "reportAttributeAccessIssue",
"severity": "error",
"startCharacter": 44,
- "startLine": 2327
+ "startLine": 2374
},
{
"endCharacter": 58,
- "endLine": 2328,
+ "endLine": 2375,
"file": "ReforceXY/reward_space_analysis/reward_space_analysis.py",
"message": "Cannot access attribute \"importances_std\" for class \"dict[Unknown, Bunch]\"\n Attribute \"importances_std\" is unknown",
"rule": "reportAttributeAccessIssue",
"severity": "error",
"startCharacter": 43,
- "startLine": 2328
+ "startLine": 2375
},
{
"endCharacter": 88,
- "endLine": 2347,
+ "endLine": 2394,
"file": "ReforceXY/reward_space_analysis/reward_space_analysis.py",
"message": "Cannot access attribute \"columns\" for class \"NDArray[Unknown]\"\n Attribute \"columns\" is unknown",
"rule": "reportAttributeAccessIssue",
"severity": "error",
"startCharacter": 81,
- "startLine": 2347
+ "startLine": 2394
},
{
"endCharacter": 88,
- "endLine": 2347,
+ "endLine": 2394,
"file": "ReforceXY/reward_space_analysis/reward_space_analysis.py",
"message": "Cannot access attribute \"columns\" for class \"list[Unknown]\"\n Attribute \"columns\" is unknown",
"rule": "reportAttributeAccessIssue",
"severity": "error",
"startCharacter": 81,
- "startLine": 2347
+ "startLine": 2394
},
{
"endCharacter": 17,
- "endLine": 2356,
+ "endLine": 2403,
"file": "ReforceXY/reward_space_analysis/reward_space_analysis.py",
"message": "Object of type \"None\" cannot be called",
"rule": "reportOptionalCall",
"severity": "error",
"startCharacter": 28,
- "startLine": 2350
+ "startLine": 2397
},
{
"endCharacter": 40,
- "endLine": 2575,
+ "endLine": 2632,
"file": "ReforceXY/reward_space_analysis/reward_space_analysis.py",
"message": "Argument of type \"Any | object | NAType | Unknown\" cannot be assigned to parameter \"arg1\" of type \"SupportsRichComparisonT@min\" in function \"min\"\n Type \"Any | object | NAType | Unknown\" is not assignable to type \"SupportsRichComparison\"\n Type \"Any | object | NAType | Unknown\" is not assignable to type \"SupportsRichComparison\"\n Type \"object\" is not assignable to type \"SupportsRichComparison\"\n \"object\" is incompatible with protocol \"SupportsDunderLT[Any]\"\n \"__lt__\" is not present\n \"object\" is incompatible with protocol \"SupportsDunderGT[Any]\"\n \"__gt__\" is not present",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 22,
- "startLine": 2575
+ "startLine": 2632
},
{
"endCharacter": 38,
- "endLine": 2575,
+ "endLine": 2632,
"file": "ReforceXY/reward_space_analysis/reward_space_analysis.py",
"message": "Cannot access attribute \"min\" for class \"ExtensionArray\"\n Attribute \"min\" is unknown",
"rule": "reportAttributeAccessIssue",
"severity": "error",
"startCharacter": 35,
- "startLine": 2575
+ "startLine": 2632
},
{
"endCharacter": 59,
- "endLine": 2575,
+ "endLine": 2632,
"file": "ReforceXY/reward_space_analysis/reward_space_analysis.py",
"message": "Argument of type \"Any | object | NAType | Unknown\" cannot be assigned to parameter \"arg2\" of type \"SupportsRichComparisonT@min\" in function \"min\"\n Type \"Any | object | NAType | Unknown\" is not assignable to type \"SupportsRichComparison\"\n Type \"Any | object | NAType | Unknown\" is not assignable to type \"SupportsRichComparison\"\n Type \"object\" is not assignable to type \"SupportsRichComparison\"\n \"object\" is incompatible with protocol \"SupportsDunderLT[Any]\"\n \"__lt__\" is not present\n \"object\" is incompatible with protocol \"SupportsDunderGT[Any]\"\n \"__gt__\" is not present",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 42,
- "startLine": 2575
+ "startLine": 2632
},
{
"endCharacter": 57,
- "endLine": 2575,
+ "endLine": 2632,
"file": "ReforceXY/reward_space_analysis/reward_space_analysis.py",
"message": "Cannot access attribute \"min\" for class \"ExtensionArray\"\n Attribute \"min\" is unknown",
"rule": "reportAttributeAccessIssue",
"severity": "error",
"startCharacter": 54,
- "startLine": 2575
+ "startLine": 2632
},
{
"endCharacter": 40,
- "endLine": 2576,
+ "endLine": 2633,
"file": "ReforceXY/reward_space_analysis/reward_space_analysis.py",
"message": "Argument of type \"Any | object | NAType | Unknown\" cannot be assigned to parameter \"arg1\" of type \"SupportsRichComparisonT@max\" in function \"max\"\n Type \"Any | object | NAType | Unknown\" is not assignable to type \"SupportsRichComparison\"\n Type \"Any | object | NAType | Unknown\" is not assignable to type \"SupportsRichComparison\"\n Type \"object\" is not assignable to type \"SupportsRichComparison\"\n \"object\" is incompatible with protocol \"SupportsDunderLT[Any]\"\n \"__lt__\" is not present\n \"object\" is incompatible with protocol \"SupportsDunderGT[Any]\"\n \"__gt__\" is not present",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 22,
- "startLine": 2576
+ "startLine": 2633
},
{
"endCharacter": 38,
- "endLine": 2576,
+ "endLine": 2633,
"file": "ReforceXY/reward_space_analysis/reward_space_analysis.py",
"message": "Cannot access attribute \"max\" for class \"ExtensionArray\"\n Attribute \"max\" is unknown",
"rule": "reportAttributeAccessIssue",
"severity": "error",
"startCharacter": 35,
- "startLine": 2576
+ "startLine": 2633
},
{
"endCharacter": 59,
- "endLine": 2576,
+ "endLine": 2633,
"file": "ReforceXY/reward_space_analysis/reward_space_analysis.py",
"message": "Argument of type \"Any | object | NAType | Unknown\" cannot be assigned to parameter \"arg2\" of type \"SupportsRichComparisonT@max\" in function \"max\"\n Type \"Any | object | NAType | Unknown\" is not assignable to type \"SupportsRichComparison\"\n Type \"Any | object | NAType | Unknown\" is not assignable to type \"SupportsRichComparison\"\n Type \"object\" is not assignable to type \"SupportsRichComparison\"\n \"object\" is incompatible with protocol \"SupportsDunderLT[Any]\"\n \"__lt__\" is not present\n \"object\" is incompatible with protocol \"SupportsDunderGT[Any]\"\n \"__gt__\" is not present",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 42,
- "startLine": 2576
+ "startLine": 2633
},
{
"endCharacter": 57,
- "endLine": 2576,
+ "endLine": 2633,
"file": "ReforceXY/reward_space_analysis/reward_space_analysis.py",
"message": "Cannot access attribute \"max\" for class \"ExtensionArray\"\n Attribute \"max\" is unknown",
"rule": "reportAttributeAccessIssue",
"severity": "error",
"startCharacter": 54,
- "startLine": 2576
+ "startLine": 2633
},
{
"endCharacter": 76,
- "endLine": 2592,
+ "endLine": 2649,
"file": "ReforceXY/reward_space_analysis/reward_space_analysis.py",
"message": "No overloads for \"histogram\" match the provided arguments",
"rule": "reportCallIssue",
"severity": "error",
"startCharacter": 24,
- "startLine": 2592
+ "startLine": 2649
},
{
"endCharacter": 49,
- "endLine": 2592,
+ "endLine": 2649,
"file": "ReforceXY/reward_space_analysis/reward_space_analysis.py",
"message": "Argument of type \"np_1darray[Any] | ExtensionArray | Categorical[object]\" cannot be assigned to parameter \"a\" of type \"_ArrayLikeComplex_co\" in function \"histogram\"\n Type \"np_1darray[Any] | ExtensionArray | Categorical[object]\" is not assignable to type \"_ArrayLikeComplex_co\"\n Type \"ExtensionArray\" is not assignable to type \"_ArrayLikeComplex_co\"\n \"ExtensionArray\" is incompatible with protocol \"_SupportsArray[dtype[numpy.bool[builtins.bool] | number[Any, Any]]]\"\n \"__array__\" is not present\n \"ExtensionArray\" is incompatible with protocol \"_NestedSequence[_SupportsArray[dtype[numpy.bool[builtins.bool] | number[Any, Any]]]]\"\n \"__reversed__\" is not present\n \"count\" is not present\n \"index\" is not present\n ...",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 37,
- "startLine": 2592
+ "startLine": 2649
},
{
"endCharacter": 74,
- "endLine": 2593,
+ "endLine": 2650,
"file": "ReforceXY/reward_space_analysis/reward_space_analysis.py",
"message": "No overloads for \"histogram\" match the provided arguments",
"rule": "reportCallIssue",
"severity": "error",
"startCharacter": 23,
- "startLine": 2593
+ "startLine": 2650
},
{
"endCharacter": 47,
- "endLine": 2593,
+ "endLine": 2650,
"file": "ReforceXY/reward_space_analysis/reward_space_analysis.py",
"message": "Argument of type \"np_1darray[Any] | ExtensionArray | Categorical[object]\" cannot be assigned to parameter \"a\" of type \"_ArrayLikeComplex_co\" in function \"histogram\"\n Type \"np_1darray[Any] | ExtensionArray | Categorical[object]\" is not assignable to type \"_ArrayLikeComplex_co\"\n Type \"ExtensionArray\" is not assignable to type \"_ArrayLikeComplex_co\"\n \"ExtensionArray\" is incompatible with protocol \"_SupportsArray[dtype[numpy.bool[builtins.bool] | number[Any, Any]]]\"\n \"__array__\" is not present\n \"ExtensionArray\" is incompatible with protocol \"_NestedSequence[_SupportsArray[dtype[numpy.bool[builtins.bool] | number[Any, Any]]]]\"\n \"__reversed__\" is not present\n \"count\" is not present\n \"index\" is not present\n ...",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 36,
- "startLine": 2593
+ "startLine": 2650
},
{
"endCharacter": 51,
- "endLine": 2608,
+ "endLine": 2678,
"file": "ReforceXY/reward_space_analysis/reward_space_analysis.py",
"message": "Argument of type \"np_1darray[Any] | ExtensionArray | Categorical[object]\" cannot be assigned to parameter \"u_values\" of type \"ToFloatND\" in function \"wasserstein_distance\"\n Type \"np_1darray[Any] | ExtensionArray | Categorical[object]\" is not assignable to type \"ToFloatND\"\n Type \"ExtensionArray\" is not assignable to type \"ToFloatND\"\n \"ExtensionArray\" is incompatible with protocol \"_CanArrayND[floating_co]\"\n \"__array__\" is not present\n \"ExtensionArray\" is incompatible with protocol \"SequenceND[py_float | _CanArray[floating_co]]\"\n \"__reversed__\" is not present\n \"count\" is not present\n \"index\" is not present\n ...",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 39,
- "startLine": 2608
+ "startLine": 2678
},
{
"endCharacter": 64,
- "endLine": 2608,
+ "endLine": 2678,
"file": "ReforceXY/reward_space_analysis/reward_space_analysis.py",
"message": "Argument of type \"np_1darray[Any] | ExtensionArray | Categorical[object]\" cannot be assigned to parameter \"v_values\" of type \"ToFloatND\" in function \"wasserstein_distance\"\n Type \"np_1darray[Any] | ExtensionArray | Categorical[object]\" is not assignable to type \"ToFloatND\"\n Type \"ExtensionArray\" is not assignable to type \"ToFloatND\"\n \"ExtensionArray\" is incompatible with protocol \"_CanArrayND[floating_co]\"\n \"__array__\" is not present\n \"ExtensionArray\" is incompatible with protocol \"SequenceND[py_float | _CanArray[floating_co]]\"\n \"__reversed__\" is not present\n \"count\" is not present\n \"index\" is not present\n ...",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 53,
- "startLine": 2608
+ "startLine": 2678
},
{
"endCharacter": 68,
- "endLine": 2611,
+ "endLine": 2681,
"file": "ReforceXY/reward_space_analysis/reward_space_analysis.py",
"message": "No overloads for \"ks_2samp\" match the provided arguments",
"rule": "reportCallIssue",
"severity": "error",
"startCharacter": 27,
- "startLine": 2611
+ "startLine": 2681
},
{
"endCharacter": 54,
- "endLine": 2611,
+ "endLine": 2681,
"file": "ReforceXY/reward_space_analysis/reward_space_analysis.py",
"message": "Argument of type \"np_1darray[Any] | ExtensionArray | Categorical[object]\" cannot be assigned to parameter \"data1\" of type \"ToFloatND\" in function \"ks_2samp\"\n Type \"np_1darray[Any] | ExtensionArray | Categorical[object]\" is not assignable to type \"ToFloatND\"\n Type \"ExtensionArray\" is not assignable to type \"ToFloatND\"\n \"ExtensionArray\" is incompatible with protocol \"_CanArrayND[floating_co]\"\n \"__array__\" is not present\n \"ExtensionArray\" is incompatible with protocol \"SequenceND[py_float | _CanArray[floating_co]]\"\n \"__reversed__\" is not present\n \"count\" is not present\n \"index\" is not present\n ...",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 42,
- "startLine": 2611
+ "startLine": 2681
},
{
"endCharacter": 67,
- "endLine": 2611,
+ "endLine": 2681,
"file": "ReforceXY/reward_space_analysis/reward_space_analysis.py",
"message": "Argument of type \"np_1darray[Any] | ExtensionArray | Categorical[object]\" cannot be assigned to parameter \"data2\" of type \"ToFloatND\" in function \"ks_2samp\"\n Type \"np_1darray[Any] | ExtensionArray | Categorical[object]\" is not assignable to type \"ToFloatND\"\n Type \"ExtensionArray\" is not assignable to type \"ToFloatND\"\n \"ExtensionArray\" is incompatible with protocol \"_CanArrayND[floating_co]\"\n \"__array__\" is not present\n \"ExtensionArray\" is incompatible with protocol \"SequenceND[py_float | _CanArray[floating_co]]\"\n \"__reversed__\" is not present\n \"count\" is not present\n \"index\" is not present\n ...",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 56,
- "startLine": 2611
+ "startLine": 2681
},
{
"endCharacter": 29,
- "endLine": 2911,
+ "endLine": 2981,
"file": "ReforceXY/reward_space_analysis/reward_space_analysis.py",
"message": "No overloads for \"ptp\" match the provided arguments",
"rule": "reportCallIssue",
"severity": "error",
"startCharacter": 11,
- "startLine": 2911
+ "startLine": 2981
},
{
"endCharacter": 28,
- "endLine": 2911,
+ "endLine": 2981,
"file": "ReforceXY/reward_space_analysis/reward_space_analysis.py",
"message": "Argument of type \"np_1darray[Any] | ExtensionArray | Categorical[object]\" cannot be assigned to parameter \"a\" of type \"_ArrayLikeNumeric_co\" in function \"ptp\"\n Type \"np_1darray[Any] | ExtensionArray | Categorical[object]\" is not assignable to type \"_ArrayLikeNumeric_co\"\n Type \"ExtensionArray\" is not assignable to type \"_ArrayLikeNumeric_co\"\n \"ExtensionArray\" is incompatible with protocol \"_SupportsArray[dtype[number[Any, Any] | numpy.bool[builtins.bool] | object_ | timedelta64[Any]]]\"\n \"__array__\" is not present\n \"ExtensionArray\" is incompatible with protocol \"_NestedSequence[_SupportsArray[dtype[number[Any, Any] | numpy.bool[builtins.bool] | object_ | timedelta64[Any]]]]\"\n \"__reversed__\" is not present\n \"count\" is not present\n \"index\" is not present\n ...",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 18,
- "startLine": 2911
+ "startLine": 2981
},
{
"endCharacter": 65,
- "endLine": 2920,
+ "endLine": 2990,
"file": "ReforceXY/reward_space_analysis/reward_space_analysis.py",
"message": "Cannot access attribute \"mean\" for class \"Categorical[object]\"\n Attribute \"mean\" is unknown",
"rule": "reportAttributeAccessIssue",
"severity": "error",
"startCharacter": 61,
- "startLine": 2920
+ "startLine": 2990
},
{
"endCharacter": 65,
- "endLine": 2920,
+ "endLine": 2990,
"file": "ReforceXY/reward_space_analysis/reward_space_analysis.py",
"message": "Cannot access attribute \"mean\" for class \"ExtensionArray\"\n Attribute \"mean\" is unknown",
"rule": "reportAttributeAccessIssue",
"severity": "error",
"startCharacter": 61,
- "startLine": 2920
+ "startLine": 2990
},
{
"endCharacter": 5,
- "endLine": 3811,
+ "endLine": 3886,
"file": "ReforceXY/reward_space_analysis/reward_space_analysis.py",
"message": "Type \"dict[bytes, bytes] | dict[str, RewardParamValue]\" is not assignable to declared type \"RewardParams\"\n Type \"dict[bytes, bytes] | dict[str, RewardParamValue]\" is not assignable to type \"RewardParams\"\n \"dict[bytes, bytes]\" is not assignable to \"dict[str, RewardParamValue]\"\n Type parameter \"_KT@dict\" is invariant, but \"bytes\" is not the same as \"str\"\n Type parameter \"_VT@dict\" is invariant, but \"bytes\" is not the same as \"RewardParamValue\"",
"rule": "reportAssignmentType",
"severity": "error",
"startCharacter": 34,
- "startLine": 3807
+ "startLine": 3882
},
{
"endCharacter": 43,
- "endLine": 3808,
+ "endLine": 3883,
"file": "ReforceXY/reward_space_analysis/reward_space_analysis.py",
"message": "No overloads for \"__init__\" match the provided arguments",
"rule": "reportCallIssue",
"severity": "error",
"startCharacter": 8,
- "startLine": 3808
+ "startLine": 3883
},
{
"endCharacter": 42,
- "endLine": 3808,
+ "endLine": 3883,
"file": "ReforceXY/reward_space_analysis/reward_space_analysis.py",
"message": "Argument of type \"Any | None\" cannot be assigned to parameter \"iterable\" of type \"Iterable[list[bytes]]\" in function \"__init__\"\n Type \"Any | None\" is not assignable to type \"Iterable[list[bytes]]\"\n \"None\" is incompatible with protocol \"Iterable[list[bytes]]\"\n \"__iter__\" is not present",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 13,
- "startLine": 3808
+ "startLine": 3883
},
{
"endCharacter": 22,
},
{
"endCharacter": 40,
- "endLine": 4355,
+ "endLine": 4356,
"file": "ReforceXY/user_data/freqaimodels/ReforceXY.py",
"message": "\"Figure\" is not exported from module \"matplotlib.pyplot\"",
"rule": "reportPrivateImportUsage",
"severity": "error",
"startCharacter": 34,
- "startLine": 4355
+ "startLine": 4356
},
{
"endCharacter": 54,
- "endLine": 4858,
+ "endLine": 4859,
"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": 4858
+ "startLine": 4859
},
{
"endCharacter": 54,
- "endLine": 4858,
+ "endLine": 4859,
"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": 4858
+ "startLine": 4859
},
{
"endCharacter": 50,
- "endLine": 4870,
+ "endLine": 4871,
"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": 4870
+ "startLine": 4871
},
{
"endCharacter": 72,
- "endLine": 4881,
+ "endLine": 4882,
"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": 4881
+ "startLine": 4882
},
{
"endCharacter": 72,
- "endLine": 4881,
+ "endLine": 4882,
"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": 4881
+ "startLine": 4882
},
{
"endCharacter": 73,
- "endLine": 4890,
+ "endLine": 4891,
"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": 4890
+ "startLine": 4891
},
{
"endCharacter": 73,
- "endLine": 4890,
+ "endLine": 4891,
"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": 4890
+ "startLine": 4891
},
{
"endCharacter": 58,
- "endLine": 4899,
+ "endLine": 4900,
"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": 4899
+ "startLine": 4900
},
{
"endCharacter": 58,
- "endLine": 4899,
+ "endLine": 4900,
"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": 4899
+ "startLine": 4900
},
{
"endCharacter": 50,
- "endLine": 5130,
+ "endLine": 5131,
"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": 5130
+ "startLine": 5131
},
{
"endCharacter": 20,
- "endLine": 5307,
+ "endLine": 5308,
"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": 5307
+ "startLine": 5308
},
{
"endCharacter": 20,
- "endLine": 5307,
+ "endLine": 5308,
"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": 5307
+ "startLine": 5308
},
{
"endCharacter": 59,
- "endLine": 5312,
+ "endLine": 5313,
"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": 5312
+ "startLine": 5313
},
{
"endCharacter": 59,
- "endLine": 5312,
+ "endLine": 5313,
"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": 5312
+ "startLine": 5313
},
{
"endCharacter": 65,
- "endLine": 5313,
+ "endLine": 5314,
"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": 5313
+ "startLine": 5314
},
{
"endCharacter": 65,
- "endLine": 5313,
+ "endLine": 5314,
"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": 5313
+ "startLine": 5314
},
{
"endCharacter": 57,
- "endLine": 5314,
+ "endLine": 5315,
"file": "ReforceXY/user_data/freqaimodels/ReforceXY.py",
"message": "Argument of type \"Any | None\" cannot be assigned to parameter \"x\" of type \"ConvertibleToFloat\" in function \"__new__\"\n Type \"Any | None\" is not assignable to type \"ConvertibleToFloat\"\n Type \"None\" is not assignable to type \"ConvertibleToFloat\"\n \"None\" is not assignable to \"str\"\n \"None\" is incompatible with protocol \"Buffer\"\n \"__buffer__\" is not present\n \"None\" is incompatible with protocol \"SupportsFloat\"\n \"__float__\" is not present\n \"None\" is incompatible with protocol \"SupportsIndex\"",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 31,
- "startLine": 5314
+ "startLine": 5315
},
{
"endCharacter": 57,
- "endLine": 5314,
+ "endLine": 5315,
"file": "ReforceXY/user_data/freqaimodels/ReforceXY.py",
"message": "Argument of type \"Any | None\" cannot be assigned to parameter \"x\" of type \"ConvertibleToFloat\" in function \"__new__\"\n Type \"Any | None\" is not assignable to type \"ConvertibleToFloat\"\n Type \"None\" is not assignable to type \"ConvertibleToFloat\"\n \"None\" is not assignable to \"str\"\n \"None\" is incompatible with protocol \"Buffer\"\n \"__buffer__\" is not present\n \"None\" is incompatible with protocol \"SupportsFloat\"\n \"__float__\" is not present\n \"None\" is incompatible with protocol \"SupportsIndex\"\n ...",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 31,
- "startLine": 5314
+ "startLine": 5315
},
{
"endCharacter": 63,
- "endLine": 5316,
+ "endLine": 5317,
"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": 5316
+ "startLine": 5317
},
{
"endCharacter": 63,
- "endLine": 5316,
+ "endLine": 5317,
"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": 5316
+ "startLine": 5317
},
{
"endCharacter": 61,
- "endLine": 5318,
+ "endLine": 5319,
"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": 5318
+ "startLine": 5319
},
{
"endCharacter": 61,
- "endLine": 5318,
+ "endLine": 5319,
"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": 5318
+ "startLine": 5319
},
{
"endCharacter": 67,
- "endLine": 5319,
+ "endLine": 5320,
"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": 5319
+ "startLine": 5320
},
{
"endCharacter": 67,
- "endLine": 5319,
+ "endLine": 5320,
"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": 5319
+ "startLine": 5320
},
{
"endCharacter": 73,
- "endLine": 5320,
+ "endLine": 5321,
"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": 5320
+ "startLine": 5321
},
{
"endCharacter": 73,
- "endLine": 5320,
+ "endLine": 5321,
"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": 5320
+ "startLine": 5321
},
{
"endCharacter": 61,
- "endLine": 5321,
+ "endLine": 5322,
"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": 5321
+ "startLine": 5322
},
{
"endCharacter": 61,
- "endLine": 5321,
+ "endLine": 5322,
"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": 5321
+ "startLine": 5322
},
{
"endCharacter": 89,
- "endLine": 5328,
+ "endLine": 5329,
"file": "ReforceXY/user_data/freqaimodels/ReforceXY.py",
"message": "Argument of type \"Any | None\" cannot be assigned to parameter \"x\" of type \"ConvertibleToInt\" in function \"__new__\"\n Type \"Any | None\" is not assignable to type \"ConvertibleToInt\"\n Type \"None\" is not assignable to type \"ConvertibleToInt\"\n \"None\" is not assignable to \"str\"\n \"None\" is incompatible with protocol \"Buffer\"\n \"__buffer__\" is not present\n \"None\" is incompatible with protocol \"SupportsInt\"\n \"__int__\" is not present\n \"None\" is incompatible with protocol \"SupportsIndex\"",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 52,
- "startLine": 5328
+ "startLine": 5329
},
{
"endCharacter": 89,
- "endLine": 5328,
+ "endLine": 5329,
"file": "ReforceXY/user_data/freqaimodels/ReforceXY.py",
"message": "Argument of type \"Any | None\" cannot be assigned to parameter \"x\" of type \"ConvertibleToInt\" in function \"__new__\"\n Type \"Any | None\" is not assignable to type \"ConvertibleToInt\"\n Type \"None\" is not assignable to type \"ConvertibleToInt\"\n \"None\" is not assignable to \"str\"\n \"None\" is incompatible with protocol \"Buffer\"\n \"__buffer__\" is not present\n \"None\" is incompatible with protocol \"SupportsInt\"\n \"__int__\" is not present\n \"None\" is incompatible with protocol \"SupportsIndex\"\n ...",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 52,
- "startLine": 5328
+ "startLine": 5329
},
{
"endCharacter": 83,
- "endLine": 5329,
+ "endLine": 5330,
"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": 5329
+ "startLine": 5330
},
{
"endCharacter": 83,
- "endLine": 5329,
+ "endLine": 5330,
"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": 5329
+ "startLine": 5330
},
{
"endCharacter": 57,
- "endLine": 5354,
+ "endLine": 5355,
"file": "ReforceXY/user_data/freqaimodels/ReforceXY.py",
"message": "Argument of type \"Any | None\" cannot be assigned to parameter \"x\" of type \"ConvertibleToFloat\" in function \"__new__\"\n Type \"Any | None\" is not assignable to type \"ConvertibleToFloat\"\n Type \"None\" is not assignable to type \"ConvertibleToFloat\"\n \"None\" is not assignable to \"str\"\n \"None\" is incompatible with protocol \"Buffer\"\n \"__buffer__\" is not present\n \"None\" is incompatible with protocol \"SupportsFloat\"\n \"__float__\" is not present\n \"None\" is incompatible with protocol \"SupportsIndex\"",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 31,
- "startLine": 5354
+ "startLine": 5355
},
{
"endCharacter": 57,
- "endLine": 5354,
+ "endLine": 5355,
"file": "ReforceXY/user_data/freqaimodels/ReforceXY.py",
"message": "Argument of type \"Any | None\" cannot be assigned to parameter \"x\" of type \"ConvertibleToFloat\" in function \"__new__\"\n Type \"Any | None\" is not assignable to type \"ConvertibleToFloat\"\n Type \"None\" is not assignable to type \"ConvertibleToFloat\"\n \"None\" is not assignable to \"str\"\n \"None\" is incompatible with protocol \"Buffer\"\n \"__buffer__\" is not present\n \"None\" is incompatible with protocol \"SupportsFloat\"\n \"__float__\" is not present\n \"None\" is incompatible with protocol \"SupportsIndex\"\n ...",
"rule": "reportArgumentType",
"severity": "error",
"startCharacter": 31,
- "startLine": 5354
+ "startLine": 5355
},
{
"endCharacter": 65,
- "endLine": 5355,
+ "endLine": 5356,
"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": 5355
+ "startLine": 5356
},
{
"endCharacter": 65,
- "endLine": 5355,
+ "endLine": 5356,
"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": 5355
+ "startLine": 5356
},
{
"endCharacter": 67,
- "endLine": 5357,
+ "endLine": 5358,
"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": 5357
+ "startLine": 5358
},
{
"endCharacter": 67,
- "endLine": 5357,
+ "endLine": 5358,
"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": 5357
+ "startLine": 5358
},
{
"endCharacter": 87,
- "endLine": 5360,
+ "endLine": 5361,
"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": 5360
+ "startLine": 5361
},
{
"endCharacter": 87,
- "endLine": 5360,
+ "endLine": 5361,
"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": 5360
+ "startLine": 5361
},
{
"endCharacter": 93,
- "endLine": 5361,
+ "endLine": 5362,
"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": 5361
+ "startLine": 5362
},
{
"endCharacter": 93,
- "endLine": 5361,
+ "endLine": 5362,
"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": 5361
+ "startLine": 5362
},
{
"endCharacter": 89,
- "endLine": 5362,
+ "endLine": 5363,
"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": 5362
+ "startLine": 5363
},
{
"endCharacter": 89,
- "endLine": 5362,
+ "endLine": 5363,
"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": 5362
+ "startLine": 5363
},
{
"endCharacter": 89,
- "endLine": 5363,
+ "endLine": 5364,
"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": 5363
+ "startLine": 5364
},
{
"endCharacter": 89,
- "endLine": 5363,
+ "endLine": 5364,
"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": 5363
+ "startLine": 5364
},
{
"endCharacter": 75,
- "endLine": 5364,
+ "endLine": 5365,
"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": 5364
+ "startLine": 5365
},
{
"endCharacter": 75,
- "endLine": 5364,
+ "endLine": 5365,
"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": 5364
+ "startLine": 5365
},
{
"endCharacter": 33,
- **`--check_invariants`** (bool, default: true) – Enable runtime invariant
checks (diagnostics become advisory if disabled). Toggle rarely; disabling may
hide reward drift or invariance violations.
-- **`--strict_validation`** (flag, default: true) – Enforce parameter bounds and
- finite checks; raises instead of silent clamp/discard when enabled.
+- **`--strict_validation`** (flag, default: true) – Enforce parameter bounds,
+ finite checks, and exact `exit_potential_mode` choices; raises when enabled.
+ Relaxed API validation clamps bounds and canonicalizes an invalid exit mode with
+ a recorded adjustment.
- **`--strict_diagnostics`** (flag, default: false) – Raise on extreme distribution
moments instead of warning. In both modes, constants retain exact mean/std,
while undefined higher moments, normality tests and Q-Q fits remain N/A.
| `entry_fee_rate` | 0.0 | Entry fee rate (`price · (1 + fee)`) |
| `exit_fee_rate` | 0.0 | Exit fee rate (`price / (1 + fee)`) |
+Direct `calculate_reward()` calls warn on an invalid exit mode before applying the
+canonical fallback. `simulate_samples()` emits this warning once per simulation.
+
PBRS verification is evidence-based, never a raw shaping sum: complete ordered
episodes (contiguous `transition_index`, single terminal), the local identity
`reward_shaping = gamma * next_potential - prev_potential`, temporal potential
continuity, and the discounted terminal boundary residual must all hold with
sufficient ordered data; otherwise the report classifies the observed PBRS as
"Not verified" even in canonical configuration.
+Imported or API-created data with an invalid `exit_potential_mode` is reported with
+its original value and cannot receive canonical verification.
In canonical mode, the entry/exit additive terms are suppressed even if the
corresponding `*_additive_enabled` flags are set.
import numpy as np
import pandas as pd
from scipy import stats
-from scipy.spatial.distance import jensenshannon
from scipy.stats import entropy, probplot
if TYPE_CHECKING:
def _warn_unknown_mode(
mode_type: str,
- provided_value: str,
+ provided_value: Any,
valid_values: Iterable[str],
fallback_value: str,
stacklevel: int = 2,
(entry_additive_effective, exit_additive_effective, additives_suppressed)
"""
+ resolved_mode = _resolve_exit_potential_mode(exit_potential_mode)
entry_additive_effective = (
- bool(entry_additive_enabled_raw) if exit_potential_mode != "canonical" else False
+ bool(entry_additive_enabled_raw) if resolved_mode != "canonical" else False
)
exit_additive_effective = (
- bool(exit_additive_enabled_raw) if exit_potential_mode != "canonical" else False
+ bool(exit_additive_enabled_raw) if resolved_mode != "canonical" else False
)
- additives_suppressed = exit_potential_mode == "canonical" and bool(
+ additives_suppressed = resolved_mode == "canonical" and bool(
entry_additive_enabled_raw or exit_additive_enabled_raw
)
return entry_additive_effective, exit_additive_effective, additives_suppressed
+def _resolve_exit_potential_mode(
+ value: Any,
+ *,
+ warn_invalid: bool = False,
+ stacklevel: int = 2,
+) -> str:
+ """Return a supported exit-potential mode, defaulting invalid values to canonical."""
+ if isinstance(value, str) and value in ALLOWED_EXIT_POTENTIAL_MODES:
+ return value
+ if warn_invalid:
+ _warn_unknown_mode(
+ "exit_potential_mode",
+ value,
+ sorted(ALLOWED_EXIT_POTENTIAL_MODES),
+ "canonical",
+ stacklevel=stacklevel,
+ )
+ return "canonical"
+
+
def _get_float_param(
params: RewardParams, key: str, default: RewardParamValue | None = None
) -> float:
"reason": "bool_coerce",
"validation_mode": "strict" if strict else "relaxed",
}
+ if "exit_potential_mode" in sanitized:
+ original_mode = sanitized["exit_potential_mode"]
+ resolved_mode = _resolve_exit_potential_mode(original_mode)
+ if resolved_mode != original_mode:
+ if strict:
+ raise ValueError(
+ "Param: 'exit_potential_mode'="
+ f"{original_mode!r} must be one of {sorted(ALLOWED_EXIT_POTENTIAL_MODES)}"
+ )
+ sanitized["exit_potential_mode"] = resolved_mode
+ adjustments["exit_potential_mode"] = {
+ "original": original_mode,
+ "adjusted": resolved_mode,
+ "reason": "invalid_choice",
+ "validation_mode": "relaxed",
+ }
# Coerce and clamp numeric-bounded parameters
for key, bounds in _PARAMETER_BOUNDS.items():
strict=strict,
)
- if not np.isclose(adjusted, original_numeric):
+ if reason_parts:
sanitized[key] = adjusted
prev_reason = adjustments.get(key, {}).get("reason")
reason: list[str] = []
breakdown.exit_pnl = terminal_context.current_pnl
# Apply PBRS only if enabled and not neutral self-loop
- exit_mode = _get_str_param(params, "exit_potential_mode")
+ exit_mode = _resolve_exit_potential_mode(
+ params.get("exit_potential_mode", DEFAULT_MODEL_REWARD_PARAMETERS["exit_potential_mode"]),
+ warn_invalid=True,
+ stacklevel=3,
+ )
hold_potential_enabled = _get_bool_param(params, "hold_potential_enabled")
entry_additive_enabled = (
- Realized PnL appears on the exit step (position still Long/Short).
"""
+ source_params = dict(params)
+ params = dict(source_params)
+ exit_mode = _resolve_exit_potential_mode(
+ params.get("exit_potential_mode", DEFAULT_MODEL_REWARD_PARAMETERS["exit_potential_mode"]),
+ warn_invalid=True,
+ stacklevel=3,
+ )
+ params["exit_potential_mode"] = exit_mode
rng = random.Random(seed)
max_trade_duration_candles = _get_int_param(params, "max_trade_duration_candles")
short_allowed = _is_short_allowed(trading_mode)
action_masking = _get_bool_param(params, "action_masking", True)
# Theoretical PBRS invariance flag
- exit_mode = _get_str_param(params, "exit_potential_mode")
entry_enabled_raw = _get_bool_param(params, "entry_additive_enabled")
exit_enabled_raw = _get_bool_param(params, "exit_additive_enabled")
)
df = pd.DataFrame(samples)
- df.attrs["reward_params"] = dict(params)
+ df.attrs["reward_params"] = source_params
# Validate critical algorithmic invariants
_validate_simulation_invariants(df)
return df
+def _stabilize_divergence(value: float, *, bin_count: int, metric_name: str) -> float:
+ """Clamp only roundoff-sized negative divergences to their exact lower bound."""
+ if value < 0.0:
+ tolerance = 8.0 * np.finfo(float).eps * bin_count
+ if value >= -tolerance:
+ return 0.0
+ raise AssertionError(f"Stats: {metric_name} must be >= 0, got {value:.17g}")
+ return value
+
+
def compute_distribution_shift_metrics(
synthetic_df: pd.DataFrame,
real_df: pd.DataFrame,
continue
bins = np.unique(np.linspace(min_val, max_val, 50))
- # Use density=False to get counts, then normalize to probabilities
+ # Normalize counts before smoothing so proportional histograms stay identical.
hist_synth, _ = np.histogram(synth_values, bins=bins, density=False)
hist_real, _ = np.histogram(real_values, bins=bins, density=False)
+ hist_synth = hist_synth / hist_synth.sum()
+ hist_real = hist_real / hist_real.sum()
- # Add small epsilon to avoid log(0) in KL divergence
+ # Add a common epsilon to avoid log(0), then restore unit mass.
epsilon = float(INTERNAL_GUARDS["histogram_epsilon"])
hist_synth = hist_synth + epsilon
hist_real = hist_real + epsilon
- # Normalize to create probability distributions (sum to 1)
hist_synth = hist_synth / hist_synth.sum()
hist_real = hist_real / hist_real.sum()
# KL(synthetic||real): measures how much synthetic diverges from real
- metrics[f"{feature}_kl_divergence"] = float(entropy(hist_synth, hist_real))
- # JS distance (square root of JS divergence) is symmetric
- metrics[f"{feature}_js_distance"] = float(jensenshannon(hist_synth, hist_real))
+ bin_count = len(hist_synth)
+ kl_divergence = _stabilize_divergence(
+ float(entropy(hist_synth, hist_real)),
+ bin_count=bin_count,
+ metric_name=f"{feature} KL divergence",
+ )
+ metrics[f"{feature}_kl_divergence"] = kl_divergence
+ # JS distance is the square root of the symmetric JS divergence.
+ mixture = 0.5 * (hist_synth + hist_real)
+ js_divergence = _stabilize_divergence(
+ 0.5 * (float(entropy(hist_synth, mixture)) + float(entropy(hist_real, mixture))),
+ bin_count=bin_count,
+ metric_name=f"{feature} JS divergence",
+ )
+ metrics[f"{feature}_js_distance"] = math.sqrt(js_divergence)
metrics[f"{feature}_wasserstein"] = float(
stats.wasserstein_distance(synth_values, real_values)
)
prev_potential: float,
params: RewardParams,
gamma: float,
+ *,
+ mode: str | None = None,
) -> float:
"""Return exit potential using the selected mode and validated PBRS gamma."""
- mode = _get_str_param(params, "exit_potential_mode")
+ mode = _resolve_exit_potential_mode(
+ params.get("exit_potential_mode", DEFAULT_MODEL_REWARD_PARAMETERS["exit_potential_mode"])
+ if mode is None
+ else mode,
+ warn_invalid=True,
+ stacklevel=3,
+ )
if mode == "canonical" or mode == "non_canonical":
return _fail_safely("canonical_exit_potential")
elif mode == "retain_previous":
next_potential = prev_potential
else:
- _warn_unknown_mode(
- "exit_potential_mode",
- mode,
- sorted(ALLOWED_EXIT_POTENTIAL_MODES),
- "canonical (via _fail_safely)",
- stacklevel=2,
- )
- next_potential = _fail_safely("invalid_exit_potential_mode")
+ return _fail_safely("invalid_exit_potential_mode")
if not np.isfinite(next_potential):
next_potential = _fail_safely("non_finite_next_exit_potential")
prev_potential = float(prev_potential) if np.isfinite(prev_potential) else 0.0
- exit_mode = _get_str_param(params, "exit_potential_mode")
+ exit_mode = _resolve_exit_potential_mode(
+ params.get("exit_potential_mode", DEFAULT_MODEL_REWARD_PARAMETERS["exit_potential_mode"]),
+ warn_invalid=True,
+ stacklevel=3,
+ )
canonical_mode = exit_mode == "canonical"
hold_potential_enabled = _get_bool_param(params, "hold_potential_enabled")
if is_exit:
- next_potential = _compute_exit_potential(prev_potential, params, gamma)
+ next_potential = _compute_exit_potential(prev_potential, params, gamma, mode=exit_mode)
pbrs_delta = gamma * next_potential - prev_potential
reward_shaping = pbrs_delta
else:
"exit_additive_enabled",
}
classification_metadata_available = classification_keys.issubset(reward_params)
+ raw_exit_potential_mode = (
+ reward_params.get("exit_potential_mode") if classification_metadata_available else None
+ )
+ classification_metadata_valid = (
+ classification_metadata_available
+ and isinstance(raw_exit_potential_mode, str)
+ and raw_exit_potential_mode in ALLOWED_EXIT_POTENTIAL_MODES
+ )
max_trade_duration_candles = _get_int_param(reward_params, "max_trade_duration_candles")
# Helpers: consistent Markdown table renderers
# Get configuration for proper invariance assessment
if classification_metadata_available:
- exit_potential_mode: str | None = _get_str_param(
- reward_params, "exit_potential_mode"
+ exit_potential_mode: str | None = (
+ raw_exit_potential_mode
+ if isinstance(raw_exit_potential_mode, str)
+ else repr(raw_exit_potential_mode)
)
entry_additive_enabled_raw: bool | None = _get_bool_param(
reward_params, "entry_additive_enabled", False
exit_additive_enabled_raw: bool | None = _get_bool_param(
reward_params, "exit_additive_enabled", False
)
- (
- entry_additive_effective,
- exit_additive_effective,
- additives_suppressed,
- ) = _resolve_additive_enablement(
- exit_potential_mode,
- entry_additive_enabled_raw,
- exit_additive_enabled_raw,
- )
+ if classification_metadata_valid:
+ (
+ entry_additive_effective,
+ exit_additive_effective,
+ additives_suppressed,
+ ) = _resolve_additive_enablement(
+ exit_potential_mode,
+ entry_additive_enabled_raw,
+ exit_additive_enabled_raw,
+ )
+ else:
+ entry_additive_effective = False
+ exit_additive_effective = False
+ additives_suppressed = False
else:
exit_potential_mode = None
entry_additive_enabled_raw = None
"reason": "Trajectory verification skipped without reward configuration evidence",
}
)
- canonical_configuration = classification_metadata_available and (
+ canonical_configuration = classification_metadata_valid and (
exit_potential_mode == "canonical"
and not (entry_additive_effective or exit_additive_effective)
)
observed_additive_issues.append(f"{column} contains non-zero values")
canonical_observations = not observed_additive_issues
- if not classification_metadata_available:
+ if not classification_metadata_available or not classification_metadata_valid:
invariance_status = "Not verified"
elif not canonical_configuration:
invariance_status = "Non-canonical: not verified"
invariance_note = evidence["reason"] + ". Raw shaping sums do not certify invariance."
if not classification_metadata_available:
invariance_note += " Reward configuration evidence is missing or incomplete."
+ elif not classification_metadata_valid:
+ invariance_note += (
+ " Reward configuration evidence is invalid: "
+ f"invalid exit_potential_mode={raw_exit_potential_mode!r}."
+ )
elif not canonical_configuration:
reasons = []
if exit_potential_mode != "canonical":
f"| Exit Additive Enabled | {bool(exit_additive_enabled_raw) if exit_additive_enabled_raw is not None else 'unknown'} |\n"
)
f.write(
- f"| Entry Additive Effective | {bool(entry_additive_effective) if classification_metadata_available else 'unknown'} |\n"
+ f"| Entry Additive Effective | {bool(entry_additive_effective) if classification_metadata_valid else 'unknown'} |\n"
)
f.write(
- f"| Exit Additive Effective | {bool(exit_additive_effective) if classification_metadata_available else 'unknown'} |\n"
+ f"| Exit Additive Effective | {bool(exit_additive_effective) if classification_metadata_valid else 'unknown'} |\n"
)
f.write(f"| Σ Shaping Reward | {total_shaping:.6f} |\n")
f.write(f"| Abs Σ Shaping Reward | {abs(total_shaping):.6e} |\n")
interrupted: NotRequired[bool]
-_WARN_HEADER_RE = re.compile(r"^\s*(?:[A-Za-z]+Warning|WARNING)\b:?", re.IGNORECASE)
+_WARN_HEADER_RE = re.compile(
+ r"^(?:WARNING:|(?:[A-Za-z_][A-Za-z0-9_]*)?Warning:|.+:[1-9]\d*: (?:[A-Za-z_][A-Za-z0-9_]*)?Warning:)"
+)
def _is_warning_header(line: str) -> bool:
return False
if "warnings.warn" in line_str.lower():
return False
- return bool(_WARN_HEADER_RE.search(line_str))
+ return bool(_WARN_HEADER_RE.match(line_str))
def build_arg_matrix(
| statistics-independence-contract-123 | statistics | Inferential helpers require independent_observations=True | statistics/test_statistics.py:636 | Covers hypothesis tests and bootstrap intervals |
| report-independent-sections-124 | integration | CI, diagnostics and shift sections do not depend on hypothesis-test output | integration/test_report_formatting.py:28 | Also verifies the reported bootstrap resample count |
| pbrs-discounted-evidence-125 | pbrs | Verification requires local identity, continuity and discounted terminal boundary | pbrs/test_pbrs.py:1699 | Discontinuous potentials are not verified |
+| statistics-proportional-histograms-126 | statistics | Proportional histograms ignore sample count; moved mass yields positive KL/JS | statistics/test_statistics.py:119 | KL and JS remain finite and non-negative |
+| pbrs-near-bound-clamp-127 | pbrs | Relaxed near-bound clamps apply exact endpoints and retain all reasons | pbrs/test_pbrs.py:1276 | Includes numeric-string coercion |
+| pbrs-exit-mode-validation-128 | pbrs | Exit-potential choices are strict or canonicalized; direct calls fail safe | pbrs/test_pbrs.py:1296 | Direct calculation and simulation boundaries warn before fallback; PBRS calls suppress additives |
+| cli-invalid-exit-mode-129 | cli | Invalid `--params exit_potential_mode` fails before artifacts | cli/test_cli_params_and_csv.py:322 | Strict CLI validation |
+| cli-warning-header-recognition-130 | cli | Warning counts accept only anchored Python warning header formats | cli/test_cli_params_and_csv.py:49 | Covers POSIX, relative, synthetic and Windows source locations |
+| pbrs-invalid-mode-provenance-131 | pbrs | Invalid imported exit-mode metadata cannot certify canonical invariance | pbrs/test_pbrs.py:475 | Preserves the invalid raw value and reports effective additive settings as unknown |
### Non-Owning Smoke / Reference Checks
Actions,
get_max_idle_duration_candles,
)
+from test_reward_space_analysis_cli import _is_warning_header, run_scenario
from ..constants import SCENARIOS, SEEDS, TOLERANCE
from ..test_base import RewardSpaceTestBase
testcase.assertEqual(result.returncode, 0, f"CLI failed: {result.stderr}")
+class TestWarningHeaderRecognition(RewardSpaceTestBase):
+ """Recognize only real Python warning header formats."""
+
+ def test_warning_header_positive_and_negative_formats(self):
+ positive = (
+ "WARNING: explicit header",
+ "Warning: base category header",
+ "UserWarning: category header",
+ "RewardDiagnosticsWarning: custom category",
+ "/tmp/pkg/file.py:12: UserWarning: POSIX path",
+ "/tmp/a.py:1: Warning: base category path",
+ "relative/file.py:1: RuntimeWarning: relative path",
+ "<string>:7: FutureWarning: synthetic source",
+ r"C:\work\file.py:42: DeprecationWarning: Windows path",
+ )
+ negative = (
+ "warning: wrong case",
+ "Some prose about UserWarning: not a header",
+ "warnings.warn('source code', UserWarning)",
+ "/tmp/file.py:0: UserWarning: zero line",
+ "/tmp/file.py:-1: UserWarning: negative line",
+ "/tmp/file.py:1: WarningExtra: wrong suffix",
+ "/tmp/file.py:1: UserWarningExtra: wrong suffix",
+ "UserWarningExtra: wrong suffix",
+ "WARNING without colon",
+ "prefix WARNING: embedded prose",
+ )
+
+ for line in positive:
+ with self.subTest(line=line):
+ self.assertTrue(_is_warning_header(line))
+ for line in negative:
+ with self.subTest(line=line):
+ self.assertFalse(_is_warning_header(line))
+
+ def test_run_scenario_counts_only_warning_headers(self):
+ """Scenario warning totals use the same strict header recognizer."""
+ script = self.output_path / "warning_emitter.py"
+ script.write_text(
+ "import sys\n"
+ "print('UserWarning: first')\n"
+ "print('ordinary prose mentioning Warning:')\n"
+ "print('<string>:2: RuntimeWarning: second', file=sys.stderr)\n",
+ encoding="utf-8",
+ )
+
+ result = run_scenario(
+ script=script,
+ out_dir=self.output_path / "warning_counter",
+ idx=0,
+ num_samples=1,
+ conf=("canonical", "linear", 0.95, 0, 0, 0),
+ strict=False,
+ timeout=10,
+ )
+
+ self.assertEqual(result["status"], "ok")
+ self.assertEqual(result["warnings"], 2)
+
+
class TestCsvEncoding(RewardSpaceTestBase):
"""Validate CSV output encoding invariants."""
int(rp["max_trade_duration_candles"]), SCENARIOS.CLI_MAX_TRADE_DURATION_PARAMS
)
+ def test_invalid_exit_potential_mode_params_fails_before_artifacts(self):
+ """An invalid --params exit-potential mode fails strict validation before output creation."""
+ out_dir = self.output_path / "invalid_exit_potential_mode"
+
+ result = _run_cli(
+ out_dir=out_dir,
+ args=["--params", "exit_potential_mode=unsupported"],
+ )
+
+ self.assertNotEqual(result.returncode, 0)
+ self.assertIn("exit_potential_mode", result.stderr + result.stdout)
+ self.assertFalse(out_dir.exists())
+
def test_missing_real_episodes_fails_before_artifacts(self):
"""An explicitly requested but missing episodes file fails the run with no artifacts."""
out_dir = self.output_path / "missing_real"
self.assertIn("reward_entry_additive contains non-zero values", content)
self.assertIn("| Σ Entry Additive | 0.000000 |", content)
+ def test_report_rejects_invalid_exit_mode_provenance(self):
+ """Invalid imported mode metadata cannot certify canonical invariance."""
+ df = simulate_samples(
+ params=self.base_params(
+ exit_potential_mode="canonical",
+ entry_additive_enabled=False,
+ exit_additive_enabled=False,
+ hold_potential_enabled=True,
+ ),
+ num_samples=40,
+ seed=SEEDS.BASE,
+ base_factor=PARAMS.BASE_FACTOR,
+ profit_aim=PARAMS.PROFIT_AIM,
+ risk_reward_ratio=PARAMS.RISK_REWARD_RATIO,
+ max_duration_ratio=2.0,
+ trading_mode="futures",
+ pnl_base_std=PARAMS.PNL_STD,
+ pnl_duration_vol_scale=PARAMS.PNL_DUR_VOL_SCALE,
+ )
+ df.attrs["reward_params"]["exit_potential_mode"] = "canoncial"
+ out_dir = self.output_path / "invalid_exit_mode_provenance"
+ write_complete_statistical_analysis(
+ df,
+ output_dir=out_dir,
+ profit_aim=PARAMS.PROFIT_AIM,
+ risk_reward_ratio=PARAMS.RISK_REWARD_RATIO,
+ seed=SEEDS.BASE,
+ skip_feature_analysis=True,
+ skip_partial_dependence=True,
+ bootstrap_resamples=SCENARIOS.BOOTSTRAP_MINIMAL_ITERATIONS,
+ )
+ content = (out_dir / "statistical_analysis.md").read_text(encoding="utf-8")
+ self.assertIn("| Invariance Status | Not verified |", content)
+ self.assertIn("invalid exit_potential_mode='canoncial'", content)
+ self.assertIn("| Exit Potential Mode | canoncial |", content)
+ self.assertIn("| Entry Additive Effective | unknown |", content)
+ self.assertNotIn("Canonical: observed PBRS verified", content)
+
def test_non_canonical_report_classifies_both_outputs(self):
"""Zero correction cannot certify a non-canonical potential mode."""
df = simulate_samples(
msg="PBRS disabled total must equal base_reward",
)
+ def test_invalid_exit_mode_warns_at_direct_and_simulation_boundaries(self):
+ """Invalid direct modes warn once before canonical fallback can disable PBRS."""
+ params = self.base_params(
+ exit_potential_mode="unsupported",
+ hold_potential_enabled=False,
+ entry_additive_enabled=True,
+ exit_additive_enabled=True,
+ )
+ context = self.make_ctx(position=Positions.Neutral, action=Actions.Neutral)
+ warning_match = "unknown exit_potential_mode 'unsupported'.*falling back to 'canonical'"
+
+ with pytest.warns(
+ reward_space_analysis.RewardDiagnosticsWarning, match=warning_match
+ ) as direct_warnings:
+ breakdown = calculate_reward_with_defaults(context, params)
+
+ self.assertEqual(len(direct_warnings), 1)
+ self.assertNearZero(breakdown.reward_shaping, atol=TOLERANCE.IDENTITY_STRICT)
+ self.assertNearZero(breakdown.entry_additive, atol=TOLERANCE.IDENTITY_STRICT)
+ self.assertNearZero(breakdown.exit_additive, atol=TOLERANCE.IDENTITY_STRICT)
+
+ with pytest.warns(
+ reward_space_analysis.RewardDiagnosticsWarning, match=warning_match
+ ) as simulation_warnings:
+ simulated = simulate_samples(
+ params=params,
+ num_samples=4,
+ seed=SEEDS.BASE,
+ base_factor=PARAMS.BASE_FACTOR,
+ profit_aim=PARAMS.PROFIT_AIM,
+ risk_reward_ratio=PARAMS.RISK_REWARD_RATIO,
+ max_duration_ratio=2.0,
+ trading_mode="futures",
+ pnl_base_std=PARAMS.PNL_STD,
+ pnl_duration_vol_scale=PARAMS.PNL_DUR_VOL_SCALE,
+ )
+
+ self.assertEqual(len(simulation_warnings), 1)
+ self.assertEqual(simulated.attrs["reward_params"]["exit_potential_mode"], "unsupported")
+
def test_exit_potential_canonical(self):
"""Verifies canonical exit resets potential (no params mutation)."""
params = self.base_params(
},
)
+ def test_validate_reward_parameters_records_near_bound_clamps_exactly(self):
+ """Relaxed validation applies near-bound clamps without approximate-equality suppression."""
+ cases = (
+ (-1e-12, 0.0, "min=0.0"),
+ (1.0 + 1e-12, 1.0, "max=1.0"),
+ ("-1e-12", 0.0, "numeric_coerce,min=0.0"),
+ )
+ for original, expected, expected_reason in cases:
+ with self.subTest(original=original):
+ params = DEFAULT_MODEL_REWARD_PARAMETERS.copy()
+ params["potential_gamma"] = original
+
+ sanitized, adjustments = validate_reward_parameters(params, strict=False)
+
+ self.assertEqual(sanitized["potential_gamma"], expected)
+ self.assertEqual(adjustments["potential_gamma"]["original"], original)
+ self.assertEqual(adjustments["potential_gamma"]["adjusted"], expected)
+ self.assertEqual(adjustments["potential_gamma"]["reason"], expected_reason)
+ self.assertEqual(adjustments["potential_gamma"]["validation_mode"], "relaxed")
+
+ def test_validate_reward_parameters_enforces_exit_potential_mode_choice(self):
+ """Invalid exit-potential modes raise in strict mode and canonicalize in relaxed mode."""
+ params = DEFAULT_MODEL_REWARD_PARAMETERS.copy()
+ params["exit_potential_mode"] = "Canonical"
+
+ with self.assertRaisesRegex(ValueError, "exit_potential_mode"):
+ validate_reward_parameters(params, strict=True)
+
+ sanitized, adjustments = validate_reward_parameters(params, strict=False)
+ self.assertEqual(sanitized["exit_potential_mode"], "canonical")
+ self.assertEqual(
+ adjustments["exit_potential_mode"],
+ {
+ "original": "Canonical",
+ "adjusted": "canonical",
+ "reason": "invalid_choice",
+ "validation_mode": "relaxed",
+ },
+ )
+
+ def test_compute_pbrs_components_invalid_mode_falls_back_to_canonical(self):
+ """Direct PBRS calls warn and suppress additives for an invalid mode."""
+ params = self.base_params(
+ exit_potential_mode="unsupported",
+ hold_potential_enabled=True,
+ entry_additive_enabled=True,
+ exit_additive_enabled=True,
+ )
+
+ with self.assertWarnsRegex(
+ reward_space_analysis.RewardDiagnosticsWarning,
+ "unknown exit_potential_mode 'unsupported'.*falling back to 'canonical'",
+ ):
+ components = reward_space_analysis.compute_pbrs_components(
+ current_pnl=0.02,
+ pnl_target=PARAMS.PROFIT_AIM * PARAMS.RISK_REWARD_RATIO,
+ current_duration_ratio=0.5,
+ next_pnl=0.01,
+ next_duration_ratio=0.6,
+ params=params,
+ base_factor=PARAMS.BASE_FACTOR,
+ risk_reward_ratio=PARAMS.RISK_REWARD_RATIO,
+ prev_potential=0.25,
+ entry_pnl=0.0,
+ is_exit=True,
+ is_entry=True,
+ )
+
+ self.assertEqual(components[1], 0.0)
+ self.assertEqual(components[3], 0.0)
+ self.assertEqual(components[4], 0.0)
+
# ---------------- Exit potential mode comparisons ---------------- #
def test_compute_exit_potential_mode_differences(self):
msg=f"Expected 1.0 for {p_key}",
)
+ def test_distribution_shift_proportional_histograms_ignore_sample_count(self):
+ """Proportional histograms of different sizes have finite, non-negative zero shift."""
+ values = np.repeat(np.arange(4, dtype=float), 10)
+ synthetic = pd.DataFrame(
+ {
+ "pnl": values,
+ "trade_duration": values + 10.0,
+ "idle_duration": values + 20.0,
+ }
+ )
+ real = pd.concat([synthetic, synthetic], ignore_index=True)
+
+ metrics = compute_distribution_shift_metrics(synthetic, real)
+
+ for feature in ("pnl", "trade_duration", "idle_duration"):
+ for suffix in ("kl_divergence", "js_distance"):
+ value = metrics[f"{feature}_{suffix}"]
+ self.assertTrue(np.isfinite(value))
+ self.assertGreaterEqual(value, 0.0)
+ self.assertLessEqual(value, TOLERANCE.GENERIC_EQ)
+
+ def test_distribution_shift_detects_one_observation_moved_between_bins(self):
+ """Moving one observation between occupied bins produces positive KL and JS shift."""
+ values = np.repeat(np.arange(4, dtype=float), 10)
+ synthetic = pd.DataFrame(
+ {
+ "pnl": values,
+ "trade_duration": values + 10.0,
+ "idle_duration": values + 20.0,
+ }
+ )
+ real = synthetic.copy()
+ real.loc[0, "pnl"] = 3.0
+
+ metrics = compute_distribution_shift_metrics(synthetic, real)
+
+ self.assertGreater(metrics["pnl_kl_divergence"], 0.0)
+ self.assertGreater(metrics["pnl_js_distance"], 0.0)
+
def test_statistics_distribution_shift_metrics(self):
"""KL/JS/Wasserstein metrics."""
df1 = self._make_idle_variance_df(100)
class PortfolioReturnsTest(unittest.TestCase):
- def make_env(self, prices, *, compound=True, fee=0.0015):
- frame = pd.DataFrame({"open": prices})
+ def make_env(self, prices, *, compound=True, fee=0.0015, price_index=None):
+ frame = pd.DataFrame({"open": prices}, index=price_index)
env = MyRLEnv(
df=frame.copy(),
prices=frame,
[(1, "long_enter"), (2, "long_exit")],
)
+ def test_history_joins_prices_by_position_without_mutating_price_index(self):
+ """Price labels never affect transition joins, including collisions and duplicates."""
+ prices = [100.0, 100.0, 110.0, 110.0]
+ index_cases = {
+ "zero_based": [0, 1, 2, 3],
+ "nonzero": [10, 11, 12, 13],
+ "collision": [1, 2, 1, 2],
+ "duplicated": [7, 7, 7, 7],
+ }
+ baseline = None
+
+ for name, price_index in index_cases.items():
+ with self.subTest(index=name):
+ env = self.make_env(prices, price_index=price_index)
+ original_index = env.prices.index.copy()
+ env.step(Actions.Long_enter.value)
+ env.step(Actions.Long_exit.value)
+
+ history = env.get_env_history()
+
+ self.assertEqual(len(history), 2)
+ self.assertEqual(history["open"].tolist(), [110.0, 110.0])
+ self.assertTrue(env.prices.index.equals(original_index))
+ if baseline is None:
+ baseline = history
+ else:
+ pd.testing.assert_frame_equal(history, baseline)
+
def test_terminal_entry_preserves_two_events_and_plot_markers(self):
env = self.make_env([100.0, 100.0, 90.0])
_, _, terminated, truncated, info = env.step(Actions.Long_enter.value)
try:
history = merge(
_history_df,
- self.prices,
+ self.prices.reset_index(drop=True),
left_on="tick",
right_index=True,
how="left",
+ sort=False,
)
except Exception as e:
logger.warning(