Promote production portfolio strategy
This commit is contained in:
@@ -34,7 +34,12 @@ def _parse_args() -> argparse.Namespace:
|
||||
default=None,
|
||||
help="JSON report path. Defaults to reports/backtest-<timestamp>.json.",
|
||||
)
|
||||
parser.add_argument("--workers", type=int, default=None, help="Override backtest worker count.")
|
||||
parser.add_argument(
|
||||
"--workers",
|
||||
type=int,
|
||||
default=None,
|
||||
help="Override backtest worker count. On an 8-thread machine, 6 is a good starting point.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--allow-spawn",
|
||||
action="store_true",
|
||||
@@ -53,6 +58,10 @@ def _pct(value: Any) -> str:
|
||||
return "-" if value is None else f"{float(value):+.1f}%"
|
||||
|
||||
|
||||
def _drawdown_pct(value: Any) -> str:
|
||||
return "-" if value is None else f"-{abs(float(value)):.1f}%"
|
||||
|
||||
|
||||
def _r(value: Any) -> str:
|
||||
return "-" if value is None else f"{float(value):+.2f}R"
|
||||
|
||||
@@ -79,10 +88,46 @@ def _print_summary(report: dict) -> None:
|
||||
print(f" 30d hold total R: {_r(hold_30.get('total_r'))}")
|
||||
if hold_policy:
|
||||
print(f" hold CAGR: {_pct(hold_policy.get('cagr_pct'))}")
|
||||
print(f" hold max drawdown: {_pct(hold_policy.get('max_drawdown_pct'))}")
|
||||
print(f" hold max drawdown: {_drawdown_pct(hold_policy.get('max_drawdown_pct'))}")
|
||||
print(f" hold Sharpe: {hold_policy.get('sharpe')}")
|
||||
print(f" hold trades: {hold_policy.get('trades')}")
|
||||
|
||||
variants = list((report.get("strategy_variants") or {}).get("variants") or [])
|
||||
ranked = sorted(
|
||||
(v for v in variants if v.get("sharpe") is not None),
|
||||
key=lambda v: v.get("sharpe"),
|
||||
reverse=True,
|
||||
)
|
||||
if ranked:
|
||||
print(" top strategy variants by Sharpe:")
|
||||
for row in ranked[:5]:
|
||||
print(
|
||||
" "
|
||||
f"{row.get('variant')}: "
|
||||
f"Sharpe {row.get('sharpe')}, "
|
||||
f"CAGR {_pct(row.get('cagr_pct'))}, "
|
||||
f"DD {_drawdown_pct(row.get('max_drawdown_pct'))}, "
|
||||
f"trades {row.get('trades')}"
|
||||
)
|
||||
|
||||
exits = list((report.get("exit_policy_variants") or {}).get("variants") or [])
|
||||
ranked_exits = sorted(
|
||||
(v for v in exits if v.get("sharpe") is not None),
|
||||
key=lambda v: v.get("sharpe"),
|
||||
reverse=True,
|
||||
)
|
||||
if ranked_exits:
|
||||
print(" exit policies for 80/20 entry by Sharpe:")
|
||||
for row in ranked_exits[:5]:
|
||||
print(
|
||||
" "
|
||||
f"{row.get('exit_policy')}: "
|
||||
f"Sharpe {row.get('sharpe')}, "
|
||||
f"CAGR {_pct(row.get('cagr_pct'))}, "
|
||||
f"DD {_drawdown_pct(row.get('max_drawdown_pct'))}, "
|
||||
f"trades {row.get('trades')}"
|
||||
)
|
||||
|
||||
|
||||
async def _main() -> None:
|
||||
args = _parse_args()
|
||||
|
||||
Reference in New Issue
Block a user