Prefer replay-qualified Torch calibration
This commit is contained in:
@@ -62,7 +62,7 @@ TIME_SERIES_FORECAST_ENABLED=true
|
|||||||
TIME_SERIES_MIN_CANDLES=120
|
TIME_SERIES_MIN_CANDLES=120
|
||||||
TIME_SERIES_FORECAST_HORIZON=3
|
TIME_SERIES_FORECAST_HORIZON=3
|
||||||
TIME_SERIES_MIN_EDGE_PERCENT=0.10
|
TIME_SERIES_MIN_EDGE_PERCENT=0.10
|
||||||
TIME_SERIES_MIN_PROBABILITY_UP=0.52
|
TIME_SERIES_MIN_PROBABILITY_UP=0.57
|
||||||
TIME_SERIES_MIN_CONFIDENCE=0.4
|
TIME_SERIES_MIN_CONFIDENCE=0.4
|
||||||
TIME_SERIES_MAX_ADJUSTMENT=0.08
|
TIME_SERIES_MAX_ADJUSTMENT=0.08
|
||||||
TIME_SERIES_LSTM_ENABLED=true
|
TIME_SERIES_LSTM_ENABLED=true
|
||||||
|
|||||||
@@ -50,118 +50,128 @@
|
|||||||
},
|
},
|
||||||
"recommended": {
|
"recommended": {
|
||||||
"edge": 0.1,
|
"edge": 0.1,
|
||||||
"probability": 0.52,
|
"probability": 0.57,
|
||||||
"confidence": 0.72,
|
"confidence": 0.4,
|
||||||
"trades": 30,
|
"trades": 38,
|
||||||
"wins": 17,
|
"wins": 20,
|
||||||
"win_rate": 0.5666666666666667,
|
"win_rate": 0.5263157894736842,
|
||||||
"total_net_percent": 12.82679871911413,
|
"total_net_percent": 10.8553482857082,
|
||||||
"average_net_percent": 0.42755995730380436,
|
"average_net_percent": 0.28566706015021576,
|
||||||
"max_drawdown_percent": 1.812991648733242,
|
"max_drawdown_percent": 3.0444999196004408,
|
||||||
"profit_factor": 3.2963631842987433,
|
"profit_factor": 2.166318971301155,
|
||||||
"score": 0.5882388552951857
|
"score": 0.3782149184267729
|
||||||
},
|
},
|
||||||
"full_replay": {
|
"full_replay": {
|
||||||
"trades": 8,
|
"trades": 9,
|
||||||
"wins": 8,
|
"wins": 8,
|
||||||
"win_rate": 1.0,
|
"win_rate": 0.8889,
|
||||||
"total_net_percent": 21.0484,
|
"total_net_percent": 18.8986,
|
||||||
"avg_net_percent": 2.631,
|
"avg_net_percent": 2.0998,
|
||||||
"max_drawdown_percent": 0.0,
|
"max_drawdown_percent": 0.2996,
|
||||||
"profit_factor": 999.0,
|
"profit_factor": 64.0689,
|
||||||
"trades_detail": [
|
"trades_detail": [
|
||||||
{
|
{
|
||||||
"symbol": "ETHUSDT",
|
"symbol": "ETHUSDT",
|
||||||
"entry_timestamp": 1779832800000,
|
"entry_timestamp": 1779832800000,
|
||||||
"exit_timestamp": 1779868800000,
|
"exit_timestamp": 1779861600000,
|
||||||
"net_percent": 0.5281,
|
"net_percent": 0.2649,
|
||||||
"reason": "forecast_weak_profit_lock",
|
"reason": "forecast_weak_profit_lock",
|
||||||
"held_bars": 10,
|
"held_bars": 8,
|
||||||
"entry_probability": 0.5747,
|
"entry_probability": 0.5763,
|
||||||
"entry_expected_percent": 0.3453
|
"entry_expected_percent": 0.3499
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"symbol": "ETHUSDT",
|
"symbol": "ETHUSDT",
|
||||||
"entry_timestamp": 1779940800000,
|
"entry_timestamp": 1779930000000,
|
||||||
"exit_timestamp": 1779984000000,
|
"exit_timestamp": 1779987600000,
|
||||||
"net_percent": 1.3185,
|
"net_percent": -0.2996,
|
||||||
|
"reason": "forecast_negative",
|
||||||
|
"held_bars": 16,
|
||||||
|
"entry_probability": 0.5855,
|
||||||
|
"entry_expected_percent": 0.1752
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"symbol": "ETHUSDT",
|
||||||
|
"entry_timestamp": 1780297200000,
|
||||||
|
"exit_timestamp": 1780340400000,
|
||||||
|
"net_percent": 1.163,
|
||||||
"reason": "forecast_weak_profit_lock",
|
"reason": "forecast_weak_profit_lock",
|
||||||
"held_bars": 12,
|
"held_bars": 12,
|
||||||
"entry_probability": 0.6018,
|
"entry_probability": 0.578,
|
||||||
"entry_expected_percent": 0.3155
|
"entry_expected_percent": 0.2182
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"symbol": "ETHUSDT",
|
"symbol": "ETHUSDT",
|
||||||
"entry_timestamp": 1780300800000,
|
"entry_timestamp": 1780776000000,
|
||||||
"exit_timestamp": 1780347600000,
|
"exit_timestamp": 1780794000000,
|
||||||
"net_percent": 0.2591,
|
"net_percent": 1.8208,
|
||||||
"reason": "forecast_weak_profit_lock",
|
"reason": "forecast_weak_profit_lock",
|
||||||
"held_bars": 13,
|
"held_bars": 5,
|
||||||
"entry_probability": 0.6164,
|
"entry_probability": 0.5736,
|
||||||
"entry_expected_percent": 0.3215
|
"entry_expected_percent": 0.6405
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"symbol": "ETHUSDT",
|
"symbol": "ETHUSDT",
|
||||||
"entry_timestamp": 1780768800000,
|
"entry_timestamp": 1781136000000,
|
||||||
"exit_timestamp": 1780855200000,
|
"exit_timestamp": 1781197200000,
|
||||||
"net_percent": 4.4581,
|
"net_percent": 3.4248,
|
||||||
|
"reason": "forecast_weak_profit_lock",
|
||||||
|
"held_bars": 17,
|
||||||
|
"entry_probability": 0.5767,
|
||||||
|
"entry_expected_percent": 0.282
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"symbol": "ETHUSDT",
|
||||||
|
"entry_timestamp": 1781434800000,
|
||||||
|
"exit_timestamp": 1781521200000,
|
||||||
|
"net_percent": 5.1663,
|
||||||
"reason": "max_hold",
|
"reason": "max_hold",
|
||||||
"held_bars": 24,
|
"held_bars": 24,
|
||||||
"entry_probability": 0.5632,
|
"entry_probability": 0.5737,
|
||||||
"entry_expected_percent": 0.5685
|
"entry_expected_percent": 0.2332
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"symbol": "ETHUSDT",
|
"symbol": "ETHUSDT",
|
||||||
"entry_timestamp": 1780862400000,
|
"entry_timestamp": 1781524800000,
|
||||||
"exit_timestamp": 1780869600000,
|
"exit_timestamp": 1781535600000,
|
||||||
"net_percent": 2.4609,
|
"net_percent": 3.5713,
|
||||||
"reason": "forecast_weak_profit_lock",
|
"reason": "forecast_weak_profit_lock",
|
||||||
"held_bars": 2,
|
"held_bars": 3,
|
||||||
"entry_probability": 0.5368,
|
"entry_probability": 0.689,
|
||||||
"entry_expected_percent": 0.4055
|
"entry_expected_percent": 0.4931
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"symbol": "ETHUSDT",
|
"symbol": "ETHUSDT",
|
||||||
"entry_timestamp": 1781139600000,
|
"entry_timestamp": 1781586000000,
|
||||||
"exit_timestamp": 1781204400000,
|
"exit_timestamp": 1781596800000,
|
||||||
"net_percent": 2.0707,
|
"net_percent": 2.0739,
|
||||||
"reason": "forecast_weak_profit_lock",
|
"reason": "forecast_weak_profit_lock",
|
||||||
"held_bars": 18,
|
"held_bars": 3,
|
||||||
"entry_probability": 0.5775,
|
"entry_probability": 0.5721,
|
||||||
"entry_expected_percent": 0.3013
|
"entry_expected_percent": 0.1205
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"symbol": "ETHUSDT",
|
"symbol": "ETHUSDT",
|
||||||
"entry_timestamp": 1781445600000,
|
"entry_timestamp": 1781863200000,
|
||||||
"exit_timestamp": 1781532000000,
|
"exit_timestamp": 1781931600000,
|
||||||
"net_percent": 9.0305,
|
"net_percent": 1.7132,
|
||||||
"reason": "max_hold",
|
|
||||||
"held_bars": 24,
|
|
||||||
"entry_probability": 0.6014,
|
|
||||||
"entry_expected_percent": 0.2946
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"symbol": "ETHUSDT",
|
|
||||||
"entry_timestamp": 1781892000000,
|
|
||||||
"exit_timestamp": 1781942400000,
|
|
||||||
"net_percent": 0.9224,
|
|
||||||
"reason": "forecast_weak_profit_lock",
|
"reason": "forecast_weak_profit_lock",
|
||||||
"held_bars": 14,
|
"held_bars": 19,
|
||||||
"entry_probability": 0.5966,
|
"entry_probability": 0.5705,
|
||||||
"entry_expected_percent": 0.2647
|
"entry_expected_percent": 0.1482
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"walk_forward": {
|
"walk_forward": {
|
||||||
"summary": {
|
"summary": {
|
||||||
"trades": 16,
|
"trades": 17,
|
||||||
"wins": 8,
|
"wins": 8,
|
||||||
"win_rate": 0.5,
|
"win_rate": 0.4706,
|
||||||
"total_net_percent": 6.8682,
|
"total_net_percent": 10.3038,
|
||||||
"avg_net_percent": 0.4293,
|
"avg_net_percent": 0.6061,
|
||||||
"max_drawdown_percent": 1.3024,
|
"max_drawdown_percent": 1.5511,
|
||||||
"profit_factor": 3.1396,
|
"profit_factor": 3.6814,
|
||||||
"status": "warn"
|
"status": "ok"
|
||||||
},
|
},
|
||||||
"folds": [
|
"folds": [
|
||||||
{
|
{
|
||||||
@@ -171,24 +181,24 @@
|
|||||||
"thresholds": {
|
"thresholds": {
|
||||||
"edge": 0.1,
|
"edge": 0.1,
|
||||||
"probability": 0.6,
|
"probability": 0.6,
|
||||||
"confidence": 0.72,
|
"confidence": 0.4,
|
||||||
"trades": 2,
|
"trades": 6,
|
||||||
"wins": 1,
|
"wins": 3,
|
||||||
"win_rate": 0.5,
|
"win_rate": 0.5,
|
||||||
"total_net_percent": -0.10348384852443271,
|
"total_net_percent": -0.04776569264114405,
|
||||||
"average_net_percent": -0.051741924262216354,
|
"average_net_percent": -0.00796094877352401,
|
||||||
"max_drawdown_percent": 0.5106090484004788,
|
"max_drawdown_percent": 1.812991648733242,
|
||||||
"profit_factor": 0.7973325211360753,
|
"profit_factor": 0.9736536609672094,
|
||||||
"score": -0.0037694524148430344
|
"score": -0.04306718362513842
|
||||||
},
|
},
|
||||||
"test": {
|
"test": {
|
||||||
"trades": 4,
|
"trades": 0,
|
||||||
"wins": 2,
|
"wins": 0,
|
||||||
"win_rate": 0.5,
|
"win_rate": 0.0,
|
||||||
"total_net_percent": 0.0557,
|
"total_net_percent": 0,
|
||||||
"avg_net_percent": 0.0139,
|
"avg_net_percent": 0.0,
|
||||||
"max_drawdown_percent": 1.3024,
|
"max_drawdown_percent": 0.0,
|
||||||
"profit_factor": 1.0428
|
"profit_factor": 0.0
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -197,25 +207,25 @@
|
|||||||
"test_records": 720,
|
"test_records": 720,
|
||||||
"thresholds": {
|
"thresholds": {
|
||||||
"edge": 0.1,
|
"edge": 0.1,
|
||||||
"probability": 0.52,
|
"probability": 0.57,
|
||||||
"confidence": 0.72,
|
"confidence": 0.4,
|
||||||
"trades": 18,
|
"trades": 14,
|
||||||
"wins": 11,
|
"wins": 9,
|
||||||
"win_rate": 0.6111111111111112,
|
"win_rate": 0.6428571428571429,
|
||||||
"total_net_percent": 6.01434645293809,
|
"total_net_percent": 0.4316747127586451,
|
||||||
"average_net_percent": 0.3341303584965606,
|
"average_net_percent": 0.030833908054188935,
|
||||||
"max_drawdown_percent": 1.812991648733242,
|
"max_drawdown_percent": 3.0444999196004408,
|
||||||
"profit_factor": 2.6352078385564366,
|
"profit_factor": 1.0927846710457836,
|
||||||
"score": 0.3944002502730791
|
"score": -0.02831168312815889
|
||||||
},
|
},
|
||||||
"test": {
|
"test": {
|
||||||
"trades": 11,
|
"trades": 17,
|
||||||
"wins": 6,
|
"wins": 8,
|
||||||
"win_rate": 0.5455,
|
"win_rate": 0.4706,
|
||||||
"total_net_percent": 7.119,
|
"total_net_percent": 10.3038,
|
||||||
"avg_net_percent": 0.6472,
|
"avg_net_percent": 0.6061,
|
||||||
"max_drawdown_percent": 1.0894,
|
"max_drawdown_percent": 1.5511,
|
||||||
"profit_factor": 5.4462
|
"profit_factor": 3.6814
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -224,24 +234,24 @@
|
|||||||
"test_records": 720,
|
"test_records": 720,
|
||||||
"thresholds": {
|
"thresholds": {
|
||||||
"edge": 0.1,
|
"edge": 0.1,
|
||||||
"probability": 0.52,
|
"probability": 0.62,
|
||||||
"confidence": 0.72,
|
"confidence": 0.4,
|
||||||
"trades": 29,
|
"trades": 10,
|
||||||
"wins": 17,
|
"wins": 4,
|
||||||
"win_rate": 0.5862068965517241,
|
"win_rate": 0.4,
|
||||||
"total_net_percent": 13.13332018590817,
|
"total_net_percent": 8.297644920429114,
|
||||||
"average_net_percent": 0.4528731098589024,
|
"average_net_percent": 0.8297644920429115,
|
||||||
"max_drawdown_percent": 1.812991648733242,
|
"max_drawdown_percent": 1.4887951136316468,
|
||||||
"profit_factor": 3.48775770371021,
|
"profit_factor": 4.295314421439746,
|
||||||
"score": 0.6189314390475966
|
"score": 0.9255653124403987
|
||||||
},
|
},
|
||||||
"test": {
|
"test": {
|
||||||
"trades": 1,
|
"trades": 0,
|
||||||
"wins": 0,
|
"wins": 0,
|
||||||
"win_rate": 0.0,
|
"win_rate": 0.0,
|
||||||
"total_net_percent": -0.3065,
|
"total_net_percent": 0,
|
||||||
"avg_net_percent": -0.3065,
|
"avg_net_percent": 0.0,
|
||||||
"max_drawdown_percent": 0.3065,
|
"max_drawdown_percent": 0.0,
|
||||||
"profit_factor": 0.0
|
"profit_factor": 0.0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -253,63 +263,63 @@
|
|||||||
{
|
{
|
||||||
"bucket": "0.30-0.35",
|
"bucket": "0.30-0.35",
|
||||||
"samples": 38,
|
"samples": 38,
|
||||||
"avg_probability": 0.336,
|
"avg_probability": 0.3361,
|
||||||
"actual_win_rate": 0.1053,
|
"actual_win_rate": 0.1053,
|
||||||
"avg_future_net_percent": -0.6575
|
"avg_future_net_percent": -0.6575
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"bucket": "0.35-0.40",
|
"bucket": "0.35-0.40",
|
||||||
"samples": 418,
|
"samples": 406,
|
||||||
"avg_probability": 0.3839,
|
"avg_probability": 0.3838,
|
||||||
"actual_win_rate": 0.2225,
|
"actual_win_rate": 0.2192,
|
||||||
"avg_future_net_percent": -0.6359
|
"avg_future_net_percent": -0.641
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"bucket": "0.40-0.45",
|
"bucket": "0.40-0.45",
|
||||||
"samples": 1065,
|
"samples": 1043,
|
||||||
"avg_probability": 0.427,
|
"avg_probability": 0.4276,
|
||||||
"actual_win_rate": 0.2873,
|
"actual_win_rate": 0.2809,
|
||||||
"avg_future_net_percent": -0.4036
|
"avg_future_net_percent": -0.4529
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"bucket": "0.45-0.50",
|
"bucket": "0.45-0.50",
|
||||||
"samples": 911,
|
"samples": 918,
|
||||||
"avg_probability": 0.4746,
|
"avg_probability": 0.4744,
|
||||||
"actual_win_rate": 0.3271,
|
"actual_win_rate": 0.3301,
|
||||||
"avg_future_net_percent": -0.3061
|
"avg_future_net_percent": -0.3166
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"bucket": "0.50-0.55",
|
"bucket": "0.50-0.55",
|
||||||
"samples": 290,
|
"samples": 312,
|
||||||
"avg_probability": 0.5188,
|
"avg_probability": 0.5195,
|
||||||
"actual_win_rate": 0.3966,
|
"actual_win_rate": 0.3846,
|
||||||
"avg_future_net_percent": -0.0583
|
"avg_future_net_percent": -0.1107
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"bucket": "0.55-0.60",
|
"bucket": "0.55-0.60",
|
||||||
"samples": 104,
|
"samples": 108,
|
||||||
"avg_probability": 0.5758,
|
"avg_probability": 0.5753,
|
||||||
"actual_win_rate": 0.4327,
|
"actual_win_rate": 0.4259,
|
||||||
"avg_future_net_percent": 0.0173
|
"avg_future_net_percent": 0.0115
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"bucket": "0.60-0.65",
|
"bucket": "0.60-0.65",
|
||||||
"samples": 42,
|
"samples": 42,
|
||||||
"avg_probability": 0.6138,
|
"avg_probability": 0.6136,
|
||||||
"actual_win_rate": 0.4762,
|
"actual_win_rate": 0.4762,
|
||||||
"avg_future_net_percent": -0.0041
|
"avg_future_net_percent": 0.0003
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"bucket": "0.65-0.70",
|
"bucket": "0.65-0.70",
|
||||||
"samples": 6,
|
"samples": 7,
|
||||||
"avg_probability": 0.6679,
|
"avg_probability": 0.666,
|
||||||
"actual_win_rate": 0.3333,
|
"actual_win_rate": 0.2857,
|
||||||
"avg_future_net_percent": 0.6587
|
"avg_future_net_percent": 0.538
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"bucket": "0.70-0.75",
|
"bucket": "0.70-0.75",
|
||||||
"samples": 6,
|
"samples": 6,
|
||||||
"avg_probability": 0.7103,
|
"avg_probability": 0.7106,
|
||||||
"actual_win_rate": 0.8333,
|
"actual_win_rate": 0.8333,
|
||||||
"avg_future_net_percent": 2.1268
|
"avg_future_net_percent": 2.1268
|
||||||
}
|
}
|
||||||
@@ -318,198 +328,393 @@
|
|||||||
"top_results": [
|
"top_results": [
|
||||||
{
|
{
|
||||||
"edge": 0.1,
|
"edge": 0.1,
|
||||||
"probability": 0.52,
|
"probability": 0.62,
|
||||||
"confidence": 0.72,
|
"confidence": 0.4,
|
||||||
"trades": 30,
|
"trades": 10,
|
||||||
"wins": 17,
|
"wins": 4,
|
||||||
"win_rate": 0.5666666666666667,
|
"win_rate": 0.4,
|
||||||
"total_net_percent": 12.82679871911413,
|
"total_net_percent": 8.297644920429114,
|
||||||
"average_net_percent": 0.42755995730380436,
|
"average_net_percent": 0.8297644920429115,
|
||||||
"max_drawdown_percent": 1.812991648733242,
|
"max_drawdown_percent": 1.4887951136316468,
|
||||||
"profit_factor": 3.2963631842987433,
|
"profit_factor": 4.295314421439746,
|
||||||
"score": 0.5882388552951857
|
"score": 0.7872712304332469
|
||||||
},
|
|
||||||
{
|
|
||||||
"edge": 0.1,
|
|
||||||
"probability": 0.5,
|
|
||||||
"confidence": 0.72,
|
|
||||||
"trades": 30,
|
|
||||||
"wins": 17,
|
|
||||||
"win_rate": 0.5666666666666667,
|
|
||||||
"total_net_percent": 12.82679871911413,
|
|
||||||
"average_net_percent": 0.42755995730380436,
|
|
||||||
"max_drawdown_percent": 1.812991648733242,
|
|
||||||
"profit_factor": 3.2963631842987433,
|
|
||||||
"score": 0.5882388552951857
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"edge": 0.1,
|
|
||||||
"probability": 0.52,
|
|
||||||
"confidence": 0.68,
|
|
||||||
"trades": 38,
|
|
||||||
"wins": 19,
|
|
||||||
"win_rate": 0.5,
|
|
||||||
"total_net_percent": 13.314209250896504,
|
|
||||||
"average_net_percent": 0.35037392765517117,
|
|
||||||
"max_drawdown_percent": 2.2311766078638495,
|
|
||||||
"profit_factor": 2.618335500149353,
|
|
||||||
"score": 0.5031517681827032
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"edge": 0.1,
|
|
||||||
"probability": 0.5,
|
|
||||||
"confidence": 0.68,
|
|
||||||
"trades": 38,
|
|
||||||
"wins": 19,
|
|
||||||
"win_rate": 0.5,
|
|
||||||
"total_net_percent": 13.314209250896504,
|
|
||||||
"average_net_percent": 0.35037392765517117,
|
|
||||||
"max_drawdown_percent": 2.2311766078638495,
|
|
||||||
"profit_factor": 2.618335500149353,
|
|
||||||
"score": 0.5031517681827032
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"edge": 0.08,
|
"edge": 0.08,
|
||||||
"probability": 0.52,
|
"probability": 0.62,
|
||||||
"confidence": 0.64,
|
"confidence": 0.4,
|
||||||
"trades": 56,
|
"trades": 10,
|
||||||
"wins": 28,
|
"wins": 4,
|
||||||
"win_rate": 0.5,
|
"win_rate": 0.4,
|
||||||
"total_net_percent": 17.433321755380405,
|
"total_net_percent": 8.297644920429114,
|
||||||
"average_net_percent": 0.31130931706036435,
|
"average_net_percent": 0.8297644920429115,
|
||||||
"max_drawdown_percent": 3.6509791332801522,
|
"max_drawdown_percent": 1.4887951136316468,
|
||||||
"profit_factor": 2.1428339375966368,
|
"profit_factor": 4.295314421439746,
|
||||||
"score": 0.4832797693926659
|
"score": 0.7872712304332469
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"edge": 0.06,
|
"edge": 0.06,
|
||||||
"probability": 0.52,
|
"probability": 0.62,
|
||||||
"confidence": 0.68,
|
"confidence": 0.4,
|
||||||
"trades": 56,
|
"trades": 10,
|
||||||
"wins": 28,
|
"wins": 4,
|
||||||
"win_rate": 0.5,
|
"win_rate": 0.4,
|
||||||
"total_net_percent": 17.433321755380405,
|
"total_net_percent": 8.297644920429114,
|
||||||
"average_net_percent": 0.31130931706036435,
|
"average_net_percent": 0.8297644920429115,
|
||||||
"max_drawdown_percent": 3.6509791332801522,
|
"max_drawdown_percent": 1.4887951136316468,
|
||||||
"profit_factor": 2.1428339375966368,
|
"profit_factor": 4.295314421439746,
|
||||||
"score": 0.4832797693926659
|
"score": 0.7872712304332469
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"edge": 0.05,
|
"edge": 0.05,
|
||||||
"probability": 0.52,
|
"probability": 0.62,
|
||||||
"confidence": 0.68,
|
"confidence": 0.4,
|
||||||
"trades": 60,
|
"trades": 10,
|
||||||
"wins": 29,
|
"wins": 4,
|
||||||
"win_rate": 0.48333333333333334,
|
"win_rate": 0.4,
|
||||||
"total_net_percent": 16.9130381260749,
|
"total_net_percent": 8.297644920429114,
|
||||||
"average_net_percent": 0.281883968767915,
|
"average_net_percent": 0.8297644920429115,
|
||||||
"max_drawdown_percent": 3.7288680658046136,
|
"max_drawdown_percent": 1.4887951136316468,
|
||||||
"profit_factor": 1.9655257883521706,
|
"profit_factor": 4.295314421439746,
|
||||||
"score": 0.44304683201823336
|
"score": 0.7872712304332469
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"edge": 0.08,
|
"edge": 0.04,
|
||||||
"probability": 0.52,
|
"probability": 0.62,
|
||||||
"confidence": 0.72,
|
"confidence": 0.4,
|
||||||
"trades": 38,
|
"trades": 10,
|
||||||
"wins": 16,
|
"wins": 4,
|
||||||
"win_rate": 0.42105263157894735,
|
"win_rate": 0.4,
|
||||||
"total_net_percent": 12.356704347142244,
|
"total_net_percent": 8.297644920429114,
|
||||||
"average_net_percent": 0.3251764301879538,
|
"average_net_percent": 0.8297644920429115,
|
||||||
"max_drawdown_percent": 2.826650409116027,
|
"max_drawdown_percent": 1.4887951136316468,
|
||||||
"profit_factor": 2.4329654894966497,
|
"profit_factor": 4.295314421439746,
|
||||||
"score": 0.44256958838476457
|
"score": 0.7872712304332469
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"edge": 0.08,
|
"edge": 0.02,
|
||||||
"probability": 0.5,
|
"probability": 0.62,
|
||||||
"confidence": 0.72,
|
"confidence": 0.4,
|
||||||
"trades": 38,
|
"trades": 10,
|
||||||
"wins": 16,
|
"wins": 4,
|
||||||
"win_rate": 0.42105263157894735,
|
"win_rate": 0.4,
|
||||||
"total_net_percent": 12.356704347142244,
|
"total_net_percent": 8.297644920429114,
|
||||||
"average_net_percent": 0.3251764301879538,
|
"average_net_percent": 0.8297644920429115,
|
||||||
"max_drawdown_percent": 2.826650409116027,
|
"max_drawdown_percent": 1.4887951136316468,
|
||||||
"profit_factor": 2.4329654894966497,
|
"profit_factor": 4.295314421439746,
|
||||||
"score": 0.44256958838476457
|
"score": 0.7872712304332469
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"edge": 0.0,
|
||||||
|
"probability": 0.62,
|
||||||
|
"confidence": 0.4,
|
||||||
|
"trades": 10,
|
||||||
|
"wins": 4,
|
||||||
|
"win_rate": 0.4,
|
||||||
|
"total_net_percent": 8.297644920429114,
|
||||||
|
"average_net_percent": 0.8297644920429115,
|
||||||
|
"max_drawdown_percent": 1.4887951136316468,
|
||||||
|
"profit_factor": 4.295314421439746,
|
||||||
|
"score": 0.7872712304332469
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"edge": 0.1,
|
"edge": 0.1,
|
||||||
"probability": 0.52,
|
"probability": 0.68,
|
||||||
"confidence": 0.6,
|
"confidence": 0.4,
|
||||||
"trades": 59,
|
"trades": 3,
|
||||||
"wins": 28,
|
"wins": 2,
|
||||||
"win_rate": 0.4745762711864407,
|
"win_rate": 0.6666666666666666,
|
||||||
"total_net_percent": 16.704033568694644,
|
"total_net_percent": 6.378880906676532,
|
||||||
"average_net_percent": 0.2831192130287228,
|
"average_net_percent": 2.1262936355588438,
|
||||||
"max_drawdown_percent": 3.9030543543860263,
|
"max_drawdown_percent": 0.33852124402657946,
|
||||||
"profit_factor": 2.053895519143829,
|
"profit_factor": 19.84336956464595,
|
||||||
"score": 0.4355711367750193
|
"score": 0.6437676518357281
|
||||||
},
|
|
||||||
{
|
|
||||||
"edge": 0.1,
|
|
||||||
"probability": 0.54,
|
|
||||||
"confidence": 0.72,
|
|
||||||
"trades": 29,
|
|
||||||
"wins": 16,
|
|
||||||
"win_rate": 0.5517241379310345,
|
|
||||||
"total_net_percent": 9.266858120167019,
|
|
||||||
"average_net_percent": 0.3195468317298972,
|
|
||||||
"max_drawdown_percent": 1.812991648733242,
|
|
||||||
"profit_factor": 2.659032178431275,
|
|
||||||
"score": 0.41557735852998334
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"edge": 0.1,
|
|
||||||
"probability": 0.55,
|
|
||||||
"confidence": 0.72,
|
|
||||||
"trades": 25,
|
|
||||||
"wins": 14,
|
|
||||||
"win_rate": 0.56,
|
|
||||||
"total_net_percent": 9.16979950649479,
|
|
||||||
"average_net_percent": 0.3667919802597916,
|
|
||||||
"max_drawdown_percent": 1.812991648733242,
|
|
||||||
"profit_factor": 3.155095090386423,
|
|
||||||
"score": 0.41121722668525085
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"edge": 0.08,
|
"edge": 0.08,
|
||||||
"probability": 0.5,
|
"probability": 0.68,
|
||||||
"confidence": 0.64,
|
"confidence": 0.4,
|
||||||
"trades": 57,
|
"trades": 3,
|
||||||
"wins": 28,
|
"wins": 2,
|
||||||
"win_rate": 0.49122807017543857,
|
"win_rate": 0.6666666666666666,
|
||||||
"total_net_percent": 15.383105036720245,
|
"total_net_percent": 6.378880906676532,
|
||||||
"average_net_percent": 0.2698790357319341,
|
"average_net_percent": 2.1262936355588438,
|
||||||
"max_drawdown_percent": 3.6509791332801522,
|
"max_drawdown_percent": 0.33852124402657946,
|
||||||
"profit_factor": 1.8889561886320847,
|
"profit_factor": 19.84336956464595,
|
||||||
"score": 0.4107453600913507
|
"score": 0.6437676518357281
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"edge": 0.06,
|
"edge": 0.06,
|
||||||
"probability": 0.5,
|
"probability": 0.68,
|
||||||
"confidence": 0.68,
|
"confidence": 0.4,
|
||||||
"trades": 57,
|
"trades": 3,
|
||||||
"wins": 28,
|
"wins": 2,
|
||||||
"win_rate": 0.49122807017543857,
|
"win_rate": 0.6666666666666666,
|
||||||
"total_net_percent": 15.383105036720245,
|
"total_net_percent": 6.378880906676532,
|
||||||
"average_net_percent": 0.2698790357319341,
|
"average_net_percent": 2.1262936355588438,
|
||||||
"max_drawdown_percent": 3.6509791332801522,
|
"max_drawdown_percent": 0.33852124402657946,
|
||||||
"profit_factor": 1.8889561886320847,
|
"profit_factor": 19.84336956464595,
|
||||||
"score": 0.4107453600913507
|
"score": 0.6437676518357281
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"edge": 0.05,
|
||||||
|
"probability": 0.68,
|
||||||
|
"confidence": 0.4,
|
||||||
|
"trades": 3,
|
||||||
|
"wins": 2,
|
||||||
|
"win_rate": 0.6666666666666666,
|
||||||
|
"total_net_percent": 6.378880906676532,
|
||||||
|
"average_net_percent": 2.1262936355588438,
|
||||||
|
"max_drawdown_percent": 0.33852124402657946,
|
||||||
|
"profit_factor": 19.84336956464595,
|
||||||
|
"score": 0.6437676518357281
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"edge": 0.04,
|
||||||
|
"probability": 0.68,
|
||||||
|
"confidence": 0.4,
|
||||||
|
"trades": 3,
|
||||||
|
"wins": 2,
|
||||||
|
"win_rate": 0.6666666666666666,
|
||||||
|
"total_net_percent": 6.378880906676532,
|
||||||
|
"average_net_percent": 2.1262936355588438,
|
||||||
|
"max_drawdown_percent": 0.33852124402657946,
|
||||||
|
"profit_factor": 19.84336956464595,
|
||||||
|
"score": 0.6437676518357281
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"edge": 0.02,
|
||||||
|
"probability": 0.68,
|
||||||
|
"confidence": 0.4,
|
||||||
|
"trades": 3,
|
||||||
|
"wins": 2,
|
||||||
|
"win_rate": 0.6666666666666666,
|
||||||
|
"total_net_percent": 6.378880906676532,
|
||||||
|
"average_net_percent": 2.1262936355588438,
|
||||||
|
"max_drawdown_percent": 0.33852124402657946,
|
||||||
|
"profit_factor": 19.84336956464595,
|
||||||
|
"score": 0.6437676518357281
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"edge": 0.0,
|
||||||
|
"probability": 0.68,
|
||||||
|
"confidence": 0.4,
|
||||||
|
"trades": 3,
|
||||||
|
"wins": 2,
|
||||||
|
"win_rate": 0.6666666666666666,
|
||||||
|
"total_net_percent": 6.378880906676532,
|
||||||
|
"average_net_percent": 2.1262936355588438,
|
||||||
|
"max_drawdown_percent": 0.33852124402657946,
|
||||||
|
"profit_factor": 19.84336956464595,
|
||||||
|
"score": 0.6437676518357281
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"edge": 0.1,
|
"edge": 0.1,
|
||||||
"probability": 0.55,
|
"probability": 0.66,
|
||||||
"confidence": 0.68,
|
"confidence": 0.4,
|
||||||
"trades": 32,
|
"trades": 4,
|
||||||
"wins": 16,
|
"wins": 2,
|
||||||
"win_rate": 0.5,
|
"win_rate": 0.5,
|
||||||
"total_net_percent": 9.83610967545454,
|
"total_net_percent": 6.065901369307769,
|
||||||
"average_net_percent": 0.3073784273579544,
|
"average_net_percent": 1.5164753423269421,
|
||||||
"max_drawdown_percent": 2.2311766078638495,
|
"max_drawdown_percent": 0.6515007813953422,
|
||||||
"profit_factor": 2.5019571623752666,
|
"profit_factor": 10.31065862471602,
|
||||||
"score": 0.40798477425385704
|
"score": 0.5969352778734036
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"edge": 0.08,
|
||||||
|
"probability": 0.66,
|
||||||
|
"confidence": 0.4,
|
||||||
|
"trades": 4,
|
||||||
|
"wins": 2,
|
||||||
|
"win_rate": 0.5,
|
||||||
|
"total_net_percent": 6.065901369307769,
|
||||||
|
"average_net_percent": 1.5164753423269421,
|
||||||
|
"max_drawdown_percent": 0.6515007813953422,
|
||||||
|
"profit_factor": 10.31065862471602,
|
||||||
|
"score": 0.5969352778734036
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"edge": 0.06,
|
||||||
|
"probability": 0.66,
|
||||||
|
"confidence": 0.4,
|
||||||
|
"trades": 4,
|
||||||
|
"wins": 2,
|
||||||
|
"win_rate": 0.5,
|
||||||
|
"total_net_percent": 6.065901369307769,
|
||||||
|
"average_net_percent": 1.5164753423269421,
|
||||||
|
"max_drawdown_percent": 0.6515007813953422,
|
||||||
|
"profit_factor": 10.31065862471602,
|
||||||
|
"score": 0.5969352778734036
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"edge": 0.05,
|
||||||
|
"probability": 0.66,
|
||||||
|
"confidence": 0.4,
|
||||||
|
"trades": 4,
|
||||||
|
"wins": 2,
|
||||||
|
"win_rate": 0.5,
|
||||||
|
"total_net_percent": 6.065901369307769,
|
||||||
|
"average_net_percent": 1.5164753423269421,
|
||||||
|
"max_drawdown_percent": 0.6515007813953422,
|
||||||
|
"profit_factor": 10.31065862471602,
|
||||||
|
"score": 0.5969352778734036
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"edge": 0.04,
|
||||||
|
"probability": 0.66,
|
||||||
|
"confidence": 0.4,
|
||||||
|
"trades": 4,
|
||||||
|
"wins": 2,
|
||||||
|
"win_rate": 0.5,
|
||||||
|
"total_net_percent": 6.065901369307769,
|
||||||
|
"average_net_percent": 1.5164753423269421,
|
||||||
|
"max_drawdown_percent": 0.6515007813953422,
|
||||||
|
"profit_factor": 10.31065862471602,
|
||||||
|
"score": 0.5969352778734036
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"edge": 0.02,
|
||||||
|
"probability": 0.66,
|
||||||
|
"confidence": 0.4,
|
||||||
|
"trades": 4,
|
||||||
|
"wins": 2,
|
||||||
|
"win_rate": 0.5,
|
||||||
|
"total_net_percent": 6.065901369307769,
|
||||||
|
"average_net_percent": 1.5164753423269421,
|
||||||
|
"max_drawdown_percent": 0.6515007813953422,
|
||||||
|
"profit_factor": 10.31065862471602,
|
||||||
|
"score": 0.5969352778734036
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"edge": 0.0,
|
||||||
|
"probability": 0.66,
|
||||||
|
"confidence": 0.4,
|
||||||
|
"trades": 4,
|
||||||
|
"wins": 2,
|
||||||
|
"win_rate": 0.5,
|
||||||
|
"total_net_percent": 6.065901369307769,
|
||||||
|
"average_net_percent": 1.5164753423269421,
|
||||||
|
"max_drawdown_percent": 0.6515007813953422,
|
||||||
|
"profit_factor": 10.31065862471602,
|
||||||
|
"score": 0.5969352778734036
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"edge": 0.1,
|
||||||
|
"probability": 0.64,
|
||||||
|
"confidence": 0.4,
|
||||||
|
"trades": 5,
|
||||||
|
"wins": 3,
|
||||||
|
"win_rate": 0.6,
|
||||||
|
"total_net_percent": 5.9312659261036345,
|
||||||
|
"average_net_percent": 1.186253185220727,
|
||||||
|
"max_drawdown_percent": 0.48325866434849596,
|
||||||
|
"profit_factor": 13.27348077473139,
|
||||||
|
"score": 0.5927433894697359
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"edge": 0.08,
|
||||||
|
"probability": 0.64,
|
||||||
|
"confidence": 0.4,
|
||||||
|
"trades": 5,
|
||||||
|
"wins": 3,
|
||||||
|
"win_rate": 0.6,
|
||||||
|
"total_net_percent": 5.9312659261036345,
|
||||||
|
"average_net_percent": 1.186253185220727,
|
||||||
|
"max_drawdown_percent": 0.48325866434849596,
|
||||||
|
"profit_factor": 13.27348077473139,
|
||||||
|
"score": 0.5927433894697359
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"edge": 0.06,
|
||||||
|
"probability": 0.64,
|
||||||
|
"confidence": 0.4,
|
||||||
|
"trades": 5,
|
||||||
|
"wins": 3,
|
||||||
|
"win_rate": 0.6,
|
||||||
|
"total_net_percent": 5.9312659261036345,
|
||||||
|
"average_net_percent": 1.186253185220727,
|
||||||
|
"max_drawdown_percent": 0.48325866434849596,
|
||||||
|
"profit_factor": 13.27348077473139,
|
||||||
|
"score": 0.5927433894697359
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"edge": 0.05,
|
||||||
|
"probability": 0.64,
|
||||||
|
"confidence": 0.4,
|
||||||
|
"trades": 5,
|
||||||
|
"wins": 3,
|
||||||
|
"win_rate": 0.6,
|
||||||
|
"total_net_percent": 5.9312659261036345,
|
||||||
|
"average_net_percent": 1.186253185220727,
|
||||||
|
"max_drawdown_percent": 0.48325866434849596,
|
||||||
|
"profit_factor": 13.27348077473139,
|
||||||
|
"score": 0.5927433894697359
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"edge": 0.04,
|
||||||
|
"probability": 0.64,
|
||||||
|
"confidence": 0.4,
|
||||||
|
"trades": 5,
|
||||||
|
"wins": 3,
|
||||||
|
"win_rate": 0.6,
|
||||||
|
"total_net_percent": 5.9312659261036345,
|
||||||
|
"average_net_percent": 1.186253185220727,
|
||||||
|
"max_drawdown_percent": 0.48325866434849596,
|
||||||
|
"profit_factor": 13.27348077473139,
|
||||||
|
"score": 0.5927433894697359
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"edge": 0.02,
|
||||||
|
"probability": 0.64,
|
||||||
|
"confidence": 0.4,
|
||||||
|
"trades": 5,
|
||||||
|
"wins": 3,
|
||||||
|
"win_rate": 0.6,
|
||||||
|
"total_net_percent": 5.9312659261036345,
|
||||||
|
"average_net_percent": 1.186253185220727,
|
||||||
|
"max_drawdown_percent": 0.48325866434849596,
|
||||||
|
"profit_factor": 13.27348077473139,
|
||||||
|
"score": 0.5927433894697359
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"edge": 0.0,
|
||||||
|
"probability": 0.64,
|
||||||
|
"confidence": 0.4,
|
||||||
|
"trades": 5,
|
||||||
|
"wins": 3,
|
||||||
|
"win_rate": 0.6,
|
||||||
|
"total_net_percent": 5.9312659261036345,
|
||||||
|
"average_net_percent": 1.186253185220727,
|
||||||
|
"max_drawdown_percent": 0.48325866434849596,
|
||||||
|
"profit_factor": 13.27348077473139,
|
||||||
|
"score": 0.5927433894697359
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"edge": 0.1,
|
||||||
|
"probability": 0.6,
|
||||||
|
"confidence": 0.4,
|
||||||
|
"trades": 16,
|
||||||
|
"wins": 9,
|
||||||
|
"win_rate": 0.5625,
|
||||||
|
"total_net_percent": 7.917141995065846,
|
||||||
|
"average_net_percent": 0.49482137469161536,
|
||||||
|
"max_drawdown_percent": 1.812991648733242,
|
||||||
|
"profit_factor": 3.629214989861449,
|
||||||
|
"score": 0.5816887551556057
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"edge": 0.08,
|
||||||
|
"probability": 0.6,
|
||||||
|
"confidence": 0.4,
|
||||||
|
"trades": 16,
|
||||||
|
"wins": 9,
|
||||||
|
"win_rate": 0.5625,
|
||||||
|
"total_net_percent": 7.917141995065846,
|
||||||
|
"average_net_percent": 0.49482137469161536,
|
||||||
|
"max_drawdown_percent": 1.812991648733242,
|
||||||
|
"profit_factor": 3.629214989861449,
|
||||||
|
"score": 0.5816887551556057
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -138,10 +138,17 @@ def main() -> None:
|
|||||||
for result in results[: min(args.top, len(results))]:
|
for result in results[: min(args.top, len(results))]:
|
||||||
print(_result_line(result))
|
print(_result_line(result))
|
||||||
|
|
||||||
recommended = _choose_recommendation(results, min_trades=args.min_trades)
|
recommended, full_backtest = _choose_replay_recommendation(
|
||||||
|
results,
|
||||||
|
records,
|
||||||
|
min_trades=args.min_trades,
|
||||||
|
min_full_replay_trades=args.min_full_replay_trades,
|
||||||
|
horizon=horizon,
|
||||||
|
round_trip_cost=round_trip_cost,
|
||||||
|
settings=settings,
|
||||||
|
)
|
||||||
print("\nRECOMMENDED")
|
print("\nRECOMMENDED")
|
||||||
print(_result_line(recommended))
|
print(_result_line(recommended))
|
||||||
full_backtest = _full_backtest(records, recommended, horizon=horizon, round_trip_cost=round_trip_cost, settings=settings)
|
|
||||||
print("\nFULL_REPLAY")
|
print("\nFULL_REPLAY")
|
||||||
print(_stats_line(full_backtest))
|
print(_stats_line(full_backtest))
|
||||||
walk_forward = _walk_forward(
|
walk_forward = _walk_forward(
|
||||||
@@ -186,9 +193,10 @@ def _parse_args() -> argparse.Namespace:
|
|||||||
parser.add_argument("--calibration-window", type=int, default=720, help="Tail records used for calibration.")
|
parser.add_argument("--calibration-window", type=int, default=720, help="Tail records used for calibration.")
|
||||||
parser.add_argument("--horizon", type=int, default=0, help="Forecast horizon to calibrate.")
|
parser.add_argument("--horizon", type=int, default=0, help="Forecast horizon to calibrate.")
|
||||||
parser.add_argument("--min-trades", type=int, default=12, help="Minimum non-overlapping trades for recommendation.")
|
parser.add_argument("--min-trades", type=int, default=12, help="Minimum non-overlapping trades for recommendation.")
|
||||||
|
parser.add_argument("--min-full-replay-trades", type=int, default=8, help="Prefer recommendations with at least this many full replay trades.")
|
||||||
parser.add_argument("--edge-grid", default="0.00,0.02,0.04,0.05,0.06,0.08,0.10", help="Percent edge thresholds.")
|
parser.add_argument("--edge-grid", default="0.00,0.02,0.04,0.05,0.06,0.08,0.10", help="Percent edge thresholds.")
|
||||||
parser.add_argument("--probability-grid", default="0.55,0.56,0.57,0.58,0.59,0.60,0.62,0.64,0.66,0.68,0.70", help="P(up) thresholds.")
|
parser.add_argument("--probability-grid", default="0.55,0.56,0.57,0.58,0.59,0.60,0.62,0.64,0.66,0.68,0.70", help="P(up) thresholds.")
|
||||||
parser.add_argument("--confidence-grid", default="0.50,0.56,0.60,0.64,0.68,0.72", help="Confidence thresholds.")
|
parser.add_argument("--confidence-grid", default="0.40,0.50,0.56,0.60,0.64,0.68,0.72", help="Confidence thresholds.")
|
||||||
parser.add_argument("--top", type=int, default=15, help="How many top results to print and save.")
|
parser.add_argument("--top", type=int, default=15, help="How many top results to print and save.")
|
||||||
parser.add_argument("--output", default="", help="Optional JSON output path.")
|
parser.add_argument("--output", default="", help="Optional JSON output path.")
|
||||||
parser.add_argument("--batch-size", type=int, default=256, help="Torch inference batch size.")
|
parser.add_argument("--batch-size", type=int, default=256, help="Torch inference batch size.")
|
||||||
@@ -799,6 +807,51 @@ def _choose_recommendation(results: list[CalibrationResult], *, min_trades: int)
|
|||||||
return viable[0] if viable else results[0]
|
return viable[0] if viable else results[0]
|
||||||
|
|
||||||
|
|
||||||
|
def _choose_replay_recommendation(
|
||||||
|
results: list[CalibrationResult],
|
||||||
|
records: list[ForecastRecord],
|
||||||
|
*,
|
||||||
|
min_trades: int,
|
||||||
|
min_full_replay_trades: int,
|
||||||
|
horizon: int,
|
||||||
|
round_trip_cost: float,
|
||||||
|
settings: Any,
|
||||||
|
) -> tuple[CalibrationResult, dict[str, Any]]:
|
||||||
|
fallback = _choose_recommendation(results, min_trades=min_trades)
|
||||||
|
fallback_replay = _full_backtest(records, fallback, horizon=horizon, round_trip_cost=round_trip_cost, settings=settings)
|
||||||
|
if min_full_replay_trades <= 0:
|
||||||
|
return fallback, fallback_replay
|
||||||
|
|
||||||
|
viable: list[tuple[CalibrationResult, dict[str, Any]]] = []
|
||||||
|
for result in results:
|
||||||
|
if result.trades < min(4, min_trades):
|
||||||
|
continue
|
||||||
|
if result.average_net_percent <= 0 or result.total_net_percent <= 0 or result.profit_factor < 1.05:
|
||||||
|
continue
|
||||||
|
replay = _full_backtest(records, result, horizon=horizon, round_trip_cost=round_trip_cost, settings=settings)
|
||||||
|
if int(replay.get("trades", 0) or 0) < min_full_replay_trades:
|
||||||
|
continue
|
||||||
|
if float(replay.get("avg_net_percent", 0.0) or 0.0) <= 0:
|
||||||
|
continue
|
||||||
|
if float(replay.get("profit_factor", 0.0) or 0.0) < 1.05:
|
||||||
|
continue
|
||||||
|
viable.append((result, replay))
|
||||||
|
|
||||||
|
if not viable:
|
||||||
|
return fallback, fallback_replay
|
||||||
|
viable.sort(
|
||||||
|
key=lambda item: (
|
||||||
|
item[0].score,
|
||||||
|
float(item[1].get("avg_net_percent", 0.0) or 0.0),
|
||||||
|
float(item[1].get("total_net_percent", 0.0) or 0.0),
|
||||||
|
int(item[1].get("trades", 0) or 0),
|
||||||
|
item[0].confidence,
|
||||||
|
),
|
||||||
|
reverse=True,
|
||||||
|
)
|
||||||
|
return viable[0]
|
||||||
|
|
||||||
|
|
||||||
def _forecast_confidence(expected_return: float, probability_up: float, skill: float, min_edge: float) -> float:
|
def _forecast_confidence(expected_return: float, probability_up: float, skill: float, min_edge: float) -> float:
|
||||||
expected_return = max(0.0, expected_return)
|
expected_return = max(0.0, expected_return)
|
||||||
skill = max(0.0, skill)
|
skill = max(0.0, skill)
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ $RepoRoot = (Resolve-Path (Join-Path $PSScriptRoot "..")).Path
|
|||||||
$RuntimeDir = Join-Path $RepoRoot "runtime"
|
$RuntimeDir = Join-Path $RepoRoot "runtime"
|
||||||
$LoopLog = Join-Path $RuntimeDir "torch_retrain_until_replay8.log"
|
$LoopLog = Join-Path $RuntimeDir "torch_retrain_until_replay8.log"
|
||||||
$GuardReport = Join-Path $RuntimeDir "torch_retrain_guard.json"
|
$GuardReport = Join-Path $RuntimeDir "torch_retrain_guard.json"
|
||||||
|
$ActiveCalibration = Join-Path $RuntimeDir "torch_threshold_calibration.json"
|
||||||
$Runner = Join-Path $RepoRoot "tools\run_torch_retrain.ps1"
|
$Runner = Join-Path $RepoRoot "tools\run_torch_retrain.ps1"
|
||||||
New-Item -ItemType Directory -Force -Path $RuntimeDir | Out-Null
|
New-Item -ItemType Directory -Force -Path $RuntimeDir | Out-Null
|
||||||
|
|
||||||
@@ -45,7 +46,8 @@ function Read-GuardSummary {
|
|||||||
return [pscustomobject]@{
|
return [pscustomobject]@{
|
||||||
Accepted = $false
|
Accepted = $false
|
||||||
Reason = "guard_report_missing"
|
Reason = "guard_report_missing"
|
||||||
ReplayTrades = 0
|
CandidateReplayTrades = 0
|
||||||
|
CurrentReplayTrades = 0
|
||||||
WalkForwardTrades = 0
|
WalkForwardTrades = 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -54,7 +56,8 @@ function Read-GuardSummary {
|
|||||||
return [pscustomobject]@{
|
return [pscustomobject]@{
|
||||||
Accepted = [bool]$payload.accepted
|
Accepted = [bool]$payload.accepted
|
||||||
Reason = [string]$payload.reason
|
Reason = [string]$payload.reason
|
||||||
ReplayTrades = ConvertTo-IntOrZero $payload.candidate.full_replay.trades
|
CandidateReplayTrades = ConvertTo-IntOrZero $payload.candidate.full_replay.trades
|
||||||
|
CurrentReplayTrades = ConvertTo-IntOrZero $payload.current.full_replay.trades
|
||||||
WalkForwardTrades = ConvertTo-IntOrZero $payload.candidate.walk_forward_summary.trades
|
WalkForwardTrades = ConvertTo-IntOrZero $payload.candidate.walk_forward_summary.trades
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -62,14 +65,34 @@ function Read-GuardSummary {
|
|||||||
return [pscustomobject]@{
|
return [pscustomobject]@{
|
||||||
Accepted = $false
|
Accepted = $false
|
||||||
Reason = "guard_report_unreadable"
|
Reason = "guard_report_unreadable"
|
||||||
ReplayTrades = 0
|
CandidateReplayTrades = 0
|
||||||
|
CurrentReplayTrades = 0
|
||||||
WalkForwardTrades = 0
|
WalkForwardTrades = 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function Read-ActiveReplayTrades {
|
||||||
|
if (-not (Test-Path $ActiveCalibration)) {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
$payload = Get-Content -Raw -LiteralPath $ActiveCalibration | ConvertFrom-Json
|
||||||
|
return ConvertTo-IntOrZero $payload.full_replay.trades
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$attempt = 0
|
$attempt = 0
|
||||||
while ($true) {
|
while ($true) {
|
||||||
|
$activeReplayTrades = Read-ActiveReplayTrades
|
||||||
|
if ($activeReplayTrades -ge $MinReplayTrades) {
|
||||||
|
Write-LoopLog "Stop condition reached: active calibration full_replay.trades=$activeReplayTrades >= $MinReplayTrades."
|
||||||
|
exit 0
|
||||||
|
}
|
||||||
|
|
||||||
$attempt += 1
|
$attempt += 1
|
||||||
if ($SeedStart -gt 0) {
|
if ($SeedStart -gt 0) {
|
||||||
$attemptSeed = $SeedStart + $attempt - 1
|
$attemptSeed = $SeedStart + $attempt - 1
|
||||||
@@ -98,10 +121,14 @@ while ($true) {
|
|||||||
& powershell.exe @runnerArgs 2>&1 | Tee-Object -FilePath $LoopLog -Append
|
& powershell.exe @runnerArgs 2>&1 | Tee-Object -FilePath $LoopLog -Append
|
||||||
$runnerExit = $LASTEXITCODE
|
$runnerExit = $LASTEXITCODE
|
||||||
$summary = Read-GuardSummary
|
$summary = Read-GuardSummary
|
||||||
Write-LoopLog "Attempt $attempt finished; runner_exit=$runnerExit accepted=$($summary.Accepted) reason=$($summary.Reason) full_replay.trades=$($summary.ReplayTrades) walk_forward.trades=$($summary.WalkForwardTrades)."
|
Write-LoopLog "Attempt $attempt finished; runner_exit=$runnerExit accepted=$($summary.Accepted) reason=$($summary.Reason) candidate_full_replay.trades=$($summary.CandidateReplayTrades) current_full_replay.trades=$($summary.CurrentReplayTrades) walk_forward.trades=$($summary.WalkForwardTrades)."
|
||||||
|
|
||||||
if ($summary.ReplayTrades -ge $MinReplayTrades) {
|
if ($summary.Accepted -and $summary.CandidateReplayTrades -ge $MinReplayTrades) {
|
||||||
Write-LoopLog "Stop condition reached: full_replay.trades=$($summary.ReplayTrades) >= $MinReplayTrades."
|
Write-LoopLog "Stop condition reached: accepted candidate full_replay.trades=$($summary.CandidateReplayTrades) >= $MinReplayTrades."
|
||||||
|
exit 0
|
||||||
|
}
|
||||||
|
if ($summary.CurrentReplayTrades -ge $MinReplayTrades) {
|
||||||
|
Write-LoopLog "Stop condition reached: current artifact full_replay.trades=$($summary.CurrentReplayTrades) >= $MinReplayTrades."
|
||||||
exit 0
|
exit 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user