Spaces:
Running
Running
Upload Quasar_axrvi_ranker.py
Browse files- Quasar_axrvi_ranker.py +77 -44
Quasar_axrvi_ranker.py
CHANGED
|
@@ -368,8 +368,6 @@ DERIV_WS_URL = "wss://ws.binaryws.com/websockets/v3?app_id=1089"
|
|
| 368 |
# Deriv API symbol β AXRVI internal symbol
|
| 369 |
SYMBOL_MAP = {
|
| 370 |
"R_25": "V25",
|
| 371 |
-
"1HZ30V": "V30_1s",
|
| 372 |
-
"R_50": "V50",
|
| 373 |
"1HZ50V": "V50_1s",
|
| 374 |
"R_75": "V75",
|
| 375 |
"1HZ75V": "V75_1s",
|
|
@@ -398,8 +396,6 @@ del _reverse_check, _deriv_sym, _axrvi_id
|
|
| 398 |
# Per-asset metadata: base volatility and max position fraction
|
| 399 |
ASSET_REGISTRY: Dict[str, dict] = {
|
| 400 |
"V25": {"symbol": "R_25", "base_vol": 25.0, "max_pos": 0.006},
|
| 401 |
-
"V30_1s": {"symbol": "1HZ30V", "base_vol": 30.0, "max_pos": 0.004},
|
| 402 |
-
"V50": {"symbol": "R_50", "base_vol": 50.0, "max_pos": 0.005},
|
| 403 |
"V50_1s": {"symbol": "1HZ50V", "base_vol": 50.0, "max_pos": 0.004},
|
| 404 |
"V75": {"symbol": "R_75", "base_vol": 75.0, "max_pos": 0.005},
|
| 405 |
"V75_1s": {"symbol": "1HZ75V", "base_vol": 75.0, "max_pos": 0.003},
|
|
@@ -423,8 +419,6 @@ ASSET_REGISTRY: Dict[str, dict] = {
|
|
| 423 |
#
|
| 424 |
# Accepted ranges per Deriv broker:
|
| 425 |
# V25 β [160, 400, 800, 1200, 1600] β use 160
|
| 426 |
-
# V30_1s β [140, 400, 700, 1000, 1400] β use 140
|
| 427 |
-
# V50 β [80, 200, 400, 600, 800] β use 80 β FIXED: broker confirmed, NOT [50,100,200,300,500]
|
| 428 |
# V50_1s β [80, 200, 400, 600, 800] β use 80
|
| 429 |
# V75 β [50, 100, 200, 300, 500] β use 50
|
| 430 |
# V75_1s β [50, 100, 200, 300, 500] β use 50
|
|
@@ -436,8 +430,6 @@ ASSET_REGISTRY: Dict[str, dict] = {
|
|
| 436 |
# STEP200 β [400, 1000, 2000, 3000, 4000] β use 400
|
| 437 |
ASSET_MULTIPLIER: Dict[str, int] = {
|
| 438 |
"V25": 160, # FIXED: was 50 β rejected, now 160 β
|
| 439 |
-
"V30_1s": 140, # smallest accepted from [140, 400, 700, 1000, 1400] β
|
| 440 |
-
"V50": 80, # FIXED: was 50 β rejected (broker accepts 80,200,400,600,800), now 80 β
|
| 441 |
"V50_1s": 80, # FIXED: was 30 β rejected, now 80 β
|
| 442 |
"V75": 50, # FIXED: was 30 β rejected, now 50 β
|
| 443 |
"V75_1s": 50, # FIXED: was 20 β rejected, now 50 β
|
|
@@ -452,8 +444,6 @@ ASSET_MULTIPLIER: Dict[str, int] = {
|
|
| 452 |
# ββ Broker's acceptable multiplier ranges (for validation & future fallback) ββ
|
| 453 |
ASSET_ACCEPTABLE_MULTIPLIERS: Dict[str, List[int]] = {
|
| 454 |
"V25": [160, 400, 800, 1200, 1600],
|
| 455 |
-
"V30_1s": [140, 400, 700, 1000, 1400], # confirmed: 140 is lowest accepted
|
| 456 |
-
"V50": [80, 200, 400, 600, 800], # FIXED: broker confirmed NOT [50,100,200,300,500]
|
| 457 |
"V50_1s": [80, 200, 400, 600, 800],
|
| 458 |
"V75": [50, 100, 200, 300, 500],
|
| 459 |
"V75_1s": [50, 100, 200, 300, 500],
|
|
@@ -469,8 +459,6 @@ ASSET_ACCEPTABLE_MULTIPLIERS: Dict[str, List[int]] = {
|
|
| 469 |
# e.g. 0.50 = close when $0.50 of the $1 stake is lost
|
| 470 |
ASSET_STOP_LOSS_FRAC: Dict[str, float] = {
|
| 471 |
"V25": 0.60,
|
| 472 |
-
"V30_1s": 0.55,
|
| 473 |
-
"V50": 0.55,
|
| 474 |
"V50_1s": 0.55,
|
| 475 |
"V75": 0.50,
|
| 476 |
"V75_1s": 0.45,
|
|
@@ -485,8 +473,6 @@ ASSET_STOP_LOSS_FRAC: Dict[str, float] = {
|
|
| 485 |
# Take-profit as fraction of stake (exit early when profit target hit)
|
| 486 |
ASSET_TAKE_PROFIT_FRAC: Dict[str, float] = {
|
| 487 |
"V25": 1.00,
|
| 488 |
-
"V30_1s": 0.90,
|
| 489 |
-
"V50": 0.90,
|
| 490 |
"V50_1s": 0.90,
|
| 491 |
"V75": 0.80,
|
| 492 |
"V75_1s": 0.75,
|
|
@@ -4620,8 +4606,8 @@ def create_axrvi_v8(num_assets: int = 5,
|
|
| 4620 |
|
| 4621 |
Example::
|
| 4622 |
|
| 4623 |
-
model = create_axrvi_v8(num_assets=
|
| 4624 |
-
out = model(sequences) # (1,
|
| 4625 |
loss = v8_total_loss(out, rank_t, returns, model.distributional.quantile_levels)
|
| 4626 |
"""
|
| 4627 |
if config is None:
|
|
@@ -6813,9 +6799,9 @@ class QuasarAXRVIBridge:
|
|
| 6813 |
reward_strategy: str = "simple",
|
| 6814 |
hub_ws_url: str = os.environ.get("QUASAR_HUB_URL", "ws://localhost:7860/ws/subscribe"),
|
| 6815 |
enable_logging: bool = True,
|
| 6816 |
-
checkpoint_dir: str = "./
|
| 6817 |
-
resume: bool = False,
|
| 6818 |
-
hf_repo_id: Optional[str] = "KarlQuant/
|
| 6819 |
):
|
| 6820 |
self.config = config or AssetRankerConfig()
|
| 6821 |
self.trade_config = trade_config or TradeConfig()
|
|
@@ -6825,7 +6811,7 @@ class QuasarAXRVIBridge:
|
|
| 6825 |
# ββ Checkpoint manager (local + optional HF sync) βββββββββββββββββββββ
|
| 6826 |
self.checkpoint_mgr = RankerCheckpointManager(
|
| 6827 |
checkpoint_dir=checkpoint_dir,
|
| 6828 |
-
hf_repo_id=hf_repo_id,
|
| 6829 |
)
|
| 6830 |
self.resume = resume
|
| 6831 |
|
|
@@ -8737,6 +8723,22 @@ class HFDatasetCheckpointManager:
|
|
| 8737 |
def _hf_ckpt_path(self, step: int) -> str:
|
| 8738 |
return f"step_{step:07d}.pt"
|
| 8739 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 8740 |
# ββ Upload βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 8741 |
|
| 8742 |
def upload(
|
|
@@ -8758,6 +8760,9 @@ class HFDatasetCheckpointManager:
|
|
| 8758 |
if not self._ensure_hf():
|
| 8759 |
return False
|
| 8760 |
|
|
|
|
|
|
|
|
|
|
| 8761 |
local_path = Path(local_path)
|
| 8762 |
if not local_path.exists():
|
| 8763 |
logger.warning(f"βοΈ HF upload skipped β file not found: {local_path}")
|
|
@@ -9078,7 +9083,7 @@ class RankerCheckpointManager:
|
|
| 9078 |
|
| 9079 |
def __init__(
|
| 9080 |
self,
|
| 9081 |
-
checkpoint_dir: str = "./
|
| 9082 |
hf_repo_id: Optional[str] = None,
|
| 9083 |
):
|
| 9084 |
self.checkpoint_dir = checkpoint_dir
|
|
@@ -9245,10 +9250,12 @@ class RankerCheckpointManager:
|
|
| 9245 |
def _build_checkpoint(self, bridge, step: int, reason: str) -> dict:
|
| 9246 |
"""Collect all live bridge state into a flat checkpoint dict."""
|
| 9247 |
ckpt: dict = {
|
| 9248 |
-
"version":
|
| 9249 |
-
"step":
|
| 9250 |
-
"reason":
|
| 9251 |
-
"timestamp":
|
|
|
|
|
|
|
| 9252 |
}
|
| 9253 |
|
| 9254 |
# ββ Model βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
@@ -9306,22 +9313,48 @@ class RankerCheckpointManager:
|
|
| 9306 |
# ββ Validate critical keys βββββββββββββββββββββββββββββββββββββββββββββ
|
| 9307 |
assert "step" in ckpt, "Checkpoint missing 'step' key"
|
| 9308 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 9309 |
# ββ Model βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 9310 |
if "axrvi_net" in ckpt and bridge.axrvi_net is not None:
|
| 9311 |
-
|
| 9312 |
-
|
| 9313 |
-
|
| 9314 |
-
|
| 9315 |
-
|
| 9316 |
-
|
|
|
|
|
|
|
|
|
|
| 9317 |
|
| 9318 |
# ββ Trainer βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 9319 |
if bridge.trainer is not None:
|
| 9320 |
tr = bridge.trainer
|
| 9321 |
-
if
|
| 9322 |
-
|
| 9323 |
-
|
| 9324 |
-
|
|
|
|
|
|
|
|
|
|
| 9325 |
tr.train_step = ckpt.get("train_step", ckpt.get("step", tr.train_step))
|
| 9326 |
tr.lambda_ce = ckpt.get("lambda_ce", tr.lambda_ce)
|
| 9327 |
tr.lambda_ql = ckpt.get("lambda_ql", tr.lambda_ql)
|
|
@@ -10387,9 +10420,9 @@ async def run_live_trading_system(
|
|
| 10387 |
hub_ws_url: str = "ws://localhost:7860/ws/subscribe",
|
| 10388 |
enable_logging: bool = True,
|
| 10389 |
shreve_config: Optional[ShreveConfig] = None,
|
| 10390 |
-
checkpoint_dir: str = "./
|
| 10391 |
resume: bool = False, # FIX: fresh start
|
| 10392 |
-
hf_repo_id: Optional[str] = "KarlQuant/
|
| 10393 |
) -> None:
|
| 10394 |
config = AssetRankerConfig(
|
| 10395 |
asset_symbols = asset_symbols or list(ASSET_REGISTRY.keys()),
|
|
@@ -10701,12 +10734,12 @@ def _parse_args():
|
|
| 10701 |
help="[S6/S8] Trade horizon Ο in seconds (default 60)")
|
| 10702 |
parser.add_argument("--martingale-epsilon", type=float, default=0.05,
|
| 10703 |
help="[S7] Gate E martingale deviation threshold (default 0.05)")
|
| 10704 |
-
parser.add_argument("--checkpoint-dir", default="./
|
| 10705 |
-
help="Directory for full-state checkpoints (default ./
|
| 10706 |
parser.add_argument("--no-resume", dest="no_resume", action="store_true", default=True,
|
| 10707 |
help="Default True β always fresh start.")
|
| 10708 |
parser.add_argument("--resume", dest="no_resume", action="store_false",
|
| 10709 |
-
help="Restore from latest
|
| 10710 |
parser.add_argument("--hf-repo", default=None,
|
| 10711 |
metavar="OWNER/REPO",
|
| 10712 |
help="Hugging Face Dataset repo for checkpoint sync "
|
|
@@ -10763,8 +10796,8 @@ if __name__ == "__main__":
|
|
| 10763 |
hub_ws_url = args.hub,
|
| 10764 |
enable_logging = not args.no_logs,
|
| 10765 |
checkpoint_dir = args.checkpoint_dir,
|
| 10766 |
-
resume = not args.no_resume, # default False β always start fresh on
|
| 10767 |
-
hf_repo_id = args.hf_repo or "KarlQuant/
|
| 10768 |
)
|
| 10769 |
|
| 10770 |
try:
|
|
@@ -10786,8 +10819,8 @@ if __name__ == "__main__":
|
|
| 10786 |
hub_ws_url = args.hub,
|
| 10787 |
enable_logging = not args.no_logs,
|
| 10788 |
checkpoint_dir = args.checkpoint_dir, # FIX 1: was silently ignored
|
| 10789 |
-
resume = not args.no_resume, # FIX 2: default
|
| 10790 |
-
hf_repo_id = args.hf_repo or "KarlQuant/
|
| 10791 |
))
|
| 10792 |
except KeyboardInterrupt:
|
| 10793 |
print("\nπ Shutting downβ¦")
|
|
|
|
| 368 |
# Deriv API symbol β AXRVI internal symbol
|
| 369 |
SYMBOL_MAP = {
|
| 370 |
"R_25": "V25",
|
|
|
|
|
|
|
| 371 |
"1HZ50V": "V50_1s",
|
| 372 |
"R_75": "V75",
|
| 373 |
"1HZ75V": "V75_1s",
|
|
|
|
| 396 |
# Per-asset metadata: base volatility and max position fraction
|
| 397 |
ASSET_REGISTRY: Dict[str, dict] = {
|
| 398 |
"V25": {"symbol": "R_25", "base_vol": 25.0, "max_pos": 0.006},
|
|
|
|
|
|
|
| 399 |
"V50_1s": {"symbol": "1HZ50V", "base_vol": 50.0, "max_pos": 0.004},
|
| 400 |
"V75": {"symbol": "R_75", "base_vol": 75.0, "max_pos": 0.005},
|
| 401 |
"V75_1s": {"symbol": "1HZ75V", "base_vol": 75.0, "max_pos": 0.003},
|
|
|
|
| 419 |
#
|
| 420 |
# Accepted ranges per Deriv broker:
|
| 421 |
# V25 β [160, 400, 800, 1200, 1600] β use 160
|
|
|
|
|
|
|
| 422 |
# V50_1s β [80, 200, 400, 600, 800] β use 80
|
| 423 |
# V75 β [50, 100, 200, 300, 500] β use 50
|
| 424 |
# V75_1s β [50, 100, 200, 300, 500] β use 50
|
|
|
|
| 430 |
# STEP200 β [400, 1000, 2000, 3000, 4000] β use 400
|
| 431 |
ASSET_MULTIPLIER: Dict[str, int] = {
|
| 432 |
"V25": 160, # FIXED: was 50 β rejected, now 160 β
|
|
|
|
|
|
|
| 433 |
"V50_1s": 80, # FIXED: was 30 β rejected, now 80 β
|
| 434 |
"V75": 50, # FIXED: was 30 β rejected, now 50 β
|
| 435 |
"V75_1s": 50, # FIXED: was 20 β rejected, now 50 β
|
|
|
|
| 444 |
# ββ Broker's acceptable multiplier ranges (for validation & future fallback) ββ
|
| 445 |
ASSET_ACCEPTABLE_MULTIPLIERS: Dict[str, List[int]] = {
|
| 446 |
"V25": [160, 400, 800, 1200, 1600],
|
|
|
|
|
|
|
| 447 |
"V50_1s": [80, 200, 400, 600, 800],
|
| 448 |
"V75": [50, 100, 200, 300, 500],
|
| 449 |
"V75_1s": [50, 100, 200, 300, 500],
|
|
|
|
| 459 |
# e.g. 0.50 = close when $0.50 of the $1 stake is lost
|
| 460 |
ASSET_STOP_LOSS_FRAC: Dict[str, float] = {
|
| 461 |
"V25": 0.60,
|
|
|
|
|
|
|
| 462 |
"V50_1s": 0.55,
|
| 463 |
"V75": 0.50,
|
| 464 |
"V75_1s": 0.45,
|
|
|
|
| 473 |
# Take-profit as fraction of stake (exit early when profit target hit)
|
| 474 |
ASSET_TAKE_PROFIT_FRAC: Dict[str, float] = {
|
| 475 |
"V25": 1.00,
|
|
|
|
|
|
|
| 476 |
"V50_1s": 0.90,
|
| 477 |
"V75": 0.80,
|
| 478 |
"V75_1s": 0.75,
|
|
|
|
| 4606 |
|
| 4607 |
Example::
|
| 4608 |
|
| 4609 |
+
model = create_axrvi_v8(num_assets=10, config=cfg, device="cpu")
|
| 4610 |
+
out = model(sequences) # (1, 10, 20, 26)
|
| 4611 |
loss = v8_total_loss(out, rank_t, returns, model.distributional.quantile_levels)
|
| 4612 |
"""
|
| 4613 |
if config is None:
|
|
|
|
| 6799 |
reward_strategy: str = "simple",
|
| 6800 |
hub_ws_url: str = os.environ.get("QUASAR_HUB_URL", "ws://localhost:7860/ws/subscribe"),
|
| 6801 |
enable_logging: bool = True,
|
| 6802 |
+
checkpoint_dir: str = "./Ranker10", # new folder for 10-asset build
|
| 6803 |
+
resume: bool = False, # FIX: fresh start
|
| 6804 |
+
hf_repo_id: Optional[str] = "KarlQuant/quasar-axrvi-v10", # new HF repo (10 assets)
|
| 6805 |
):
|
| 6806 |
self.config = config or AssetRankerConfig()
|
| 6807 |
self.trade_config = trade_config or TradeConfig()
|
|
|
|
| 6811 |
# ββ Checkpoint manager (local + optional HF sync) βββββββββββββββββββββ
|
| 6812 |
self.checkpoint_mgr = RankerCheckpointManager(
|
| 6813 |
checkpoint_dir=checkpoint_dir,
|
| 6814 |
+
hf_repo_id=hf_repo_id,
|
| 6815 |
)
|
| 6816 |
self.resume = resume
|
| 6817 |
|
|
|
|
| 8723 |
def _hf_ckpt_path(self, step: int) -> str:
|
| 8724 |
return f"step_{step:07d}.pt"
|
| 8725 |
|
| 8726 |
+
def _ensure_repo_exists(self) -> None:
|
| 8727 |
+
"""Create the HF Dataset repo if it does not already exist. No-op if it exists."""
|
| 8728 |
+
if not self._ensure_hf():
|
| 8729 |
+
return
|
| 8730 |
+
try:
|
| 8731 |
+
self._hfapi.create_repo(
|
| 8732 |
+
repo_id = self.repo_id,
|
| 8733 |
+
repo_type = "dataset",
|
| 8734 |
+
exist_ok = True, # safe to call even if repo already exists
|
| 8735 |
+
private = True,
|
| 8736 |
+
)
|
| 8737 |
+
if self.verbose:
|
| 8738 |
+
logger.info(f"βοΈ HF repo ready (created or already exists): {self.repo_id}")
|
| 8739 |
+
except Exception as exc:
|
| 8740 |
+
logger.warning(f"βοΈ Could not ensure HF repo exists (non-fatal): {exc}")
|
| 8741 |
+
|
| 8742 |
# ββ Upload βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 8743 |
|
| 8744 |
def upload(
|
|
|
|
| 8760 |
if not self._ensure_hf():
|
| 8761 |
return False
|
| 8762 |
|
| 8763 |
+
# Auto-create the repo if this is a new HF folder (no-op if it already exists)
|
| 8764 |
+
self._ensure_repo_exists()
|
| 8765 |
+
|
| 8766 |
local_path = Path(local_path)
|
| 8767 |
if not local_path.exists():
|
| 8768 |
logger.warning(f"βοΈ HF upload skipped β file not found: {local_path}")
|
|
|
|
| 9083 |
|
| 9084 |
def __init__(
|
| 9085 |
self,
|
| 9086 |
+
checkpoint_dir: str = "./Ranker10",
|
| 9087 |
hf_repo_id: Optional[str] = None,
|
| 9088 |
):
|
| 9089 |
self.checkpoint_dir = checkpoint_dir
|
|
|
|
| 9250 |
def _build_checkpoint(self, bridge, step: int, reason: str) -> dict:
|
| 9251 |
"""Collect all live bridge state into a flat checkpoint dict."""
|
| 9252 |
ckpt: dict = {
|
| 9253 |
+
"version": "2.1",
|
| 9254 |
+
"step": step,
|
| 9255 |
+
"reason": reason,
|
| 9256 |
+
"timestamp": datetime.now().isoformat(),
|
| 9257 |
+
"num_assets": bridge.axrvi_net.num_assets if bridge.axrvi_net is not None else 0,
|
| 9258 |
+
"asset_symbols": list(bridge.config.asset_symbols),
|
| 9259 |
}
|
| 9260 |
|
| 9261 |
# ββ Model βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
|
|
| 9313 |
# ββ Validate critical keys βββββββββββββββββββββββββββββββββββββββββββββ
|
| 9314 |
assert "step" in ckpt, "Checkpoint missing 'step' key"
|
| 9315 |
|
| 9316 |
+
# ββ num_assets compatibility guard ββββββββββββββββββββββββββββββββββββ
|
| 9317 |
+
# If the checkpoint was saved with a different asset count (e.g. 12 before
|
| 9318 |
+
# V50/V30_1s were removed), the QCSAM/FABLE weight tensors will have the
|
| 9319 |
+
# wrong shape. We detect this early and skip model + optimizer weights so
|
| 9320 |
+
# the rest of the state (replay, bandit, counters) can still be restored.
|
| 9321 |
+
ckpt_num_assets = ckpt.get("num_assets", -1)
|
| 9322 |
+
current_num_assets = bridge.axrvi_net.num_assets if bridge.axrvi_net is not None else -1
|
| 9323 |
+
_model_compatible = True
|
| 9324 |
+
|
| 9325 |
+
if ckpt_num_assets != -1 and ckpt_num_assets != current_num_assets:
|
| 9326 |
+
ckpt_assets = ckpt.get("asset_symbols", "unknown")
|
| 9327 |
+
logger.warning(
|
| 9328 |
+
f"β οΈ [Restore] Asset count mismatch: checkpoint has {ckpt_num_assets} assets "
|
| 9329 |
+
f"({ckpt_assets}), but current model has {current_num_assets} assets "
|
| 9330 |
+
f"({list(bridge.config.asset_symbols)}). "
|
| 9331 |
+
f"Skipping axrvi_net + optimizer weights β model starts fresh. "
|
| 9332 |
+
f"All other state (replay, bandit, counters) will be restored."
|
| 9333 |
+
)
|
| 9334 |
+
_model_compatible = False
|
| 9335 |
+
|
| 9336 |
# ββ Model βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 9337 |
if "axrvi_net" in ckpt and bridge.axrvi_net is not None:
|
| 9338 |
+
if _model_compatible:
|
| 9339 |
+
incompatible = bridge.axrvi_net.load_state_dict(ckpt["axrvi_net"], strict=False)
|
| 9340 |
+
if incompatible.missing_keys:
|
| 9341 |
+
logger.warning(f"[Restore] axrvi_net missing keys: {incompatible.missing_keys}")
|
| 9342 |
+
if incompatible.unexpected_keys:
|
| 9343 |
+
logger.warning(f"[Restore] axrvi_net unexpected keys: {incompatible.unexpected_keys}")
|
| 9344 |
+
logger.info(" β
axrvi_net restored")
|
| 9345 |
+
else:
|
| 9346 |
+
logger.info(" βοΈ axrvi_net skipped (asset count mismatch β fresh weights kept)")
|
| 9347 |
|
| 9348 |
# ββ Trainer βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 9349 |
if bridge.trainer is not None:
|
| 9350 |
tr = bridge.trainer
|
| 9351 |
+
if _model_compatible:
|
| 9352 |
+
if "optimizer" in ckpt:
|
| 9353 |
+
tr.optimizer.load_state_dict(ckpt["optimizer"])
|
| 9354 |
+
if "scheduler" in ckpt:
|
| 9355 |
+
tr.scheduler.load_state_dict(ckpt["scheduler"])
|
| 9356 |
+
else:
|
| 9357 |
+
logger.info(" βοΈ optimizer/scheduler skipped (asset count mismatch β fresh state kept)")
|
| 9358 |
tr.train_step = ckpt.get("train_step", ckpt.get("step", tr.train_step))
|
| 9359 |
tr.lambda_ce = ckpt.get("lambda_ce", tr.lambda_ce)
|
| 9360 |
tr.lambda_ql = ckpt.get("lambda_ql", tr.lambda_ql)
|
|
|
|
| 10420 |
hub_ws_url: str = "ws://localhost:7860/ws/subscribe",
|
| 10421 |
enable_logging: bool = True,
|
| 10422 |
shreve_config: Optional[ShreveConfig] = None,
|
| 10423 |
+
checkpoint_dir: str = "./Ranker10",
|
| 10424 |
resume: bool = False, # FIX: fresh start
|
| 10425 |
+
hf_repo_id: Optional[str] = "KarlQuant/quasar-axrvi-v10", # new HF repo (10 assets)
|
| 10426 |
) -> None:
|
| 10427 |
config = AssetRankerConfig(
|
| 10428 |
asset_symbols = asset_symbols or list(ASSET_REGISTRY.keys()),
|
|
|
|
| 10734 |
help="[S6/S8] Trade horizon Ο in seconds (default 60)")
|
| 10735 |
parser.add_argument("--martingale-epsilon", type=float, default=0.05,
|
| 10736 |
help="[S7] Gate E martingale deviation threshold (default 0.05)")
|
| 10737 |
+
parser.add_argument("--checkpoint-dir", default="./Ranker10",
|
| 10738 |
+
help="Directory for full-state checkpoints (default ./Ranker10)")
|
| 10739 |
parser.add_argument("--no-resume", dest="no_resume", action="store_true", default=True,
|
| 10740 |
help="Default True β always fresh start.")
|
| 10741 |
parser.add_argument("--resume", dest="no_resume", action="store_false",
|
| 10742 |
+
help="Restore from latest Ranker10 checkpoint")
|
| 10743 |
parser.add_argument("--hf-repo", default=None,
|
| 10744 |
metavar="OWNER/REPO",
|
| 10745 |
help="Hugging Face Dataset repo for checkpoint sync "
|
|
|
|
| 10796 |
hub_ws_url = args.hub,
|
| 10797 |
enable_logging = not args.no_logs,
|
| 10798 |
checkpoint_dir = args.checkpoint_dir,
|
| 10799 |
+
resume = not args.no_resume, # default False β always start fresh on Ranker10
|
| 10800 |
+
hf_repo_id = args.hf_repo or "KarlQuant/quasar-axrvi-v10",
|
| 10801 |
)
|
| 10802 |
|
| 10803 |
try:
|
|
|
|
| 10819 |
hub_ws_url = args.hub,
|
| 10820 |
enable_logging = not args.no_logs,
|
| 10821 |
checkpoint_dir = args.checkpoint_dir, # FIX 1: was silently ignored
|
| 10822 |
+
resume = not args.no_resume, # FIX 2: default False (always fresh start)
|
| 10823 |
+
hf_repo_id = args.hf_repo or "KarlQuant/quasar-axrvi-v10",
|
| 10824 |
))
|
| 10825 |
except KeyboardInterrupt:
|
| 10826 |
print("\nπ Shutting downβ¦")
|