Spaces:
Running
Running
Upload Quasar_axrvi_ranker.py
Browse files- Quasar_axrvi_ranker.py +45 -28
Quasar_axrvi_ranker.py
CHANGED
|
@@ -378,7 +378,7 @@ SYMBOL_MAP = {
|
|
| 378 |
"1HZ100V": "V100_1s",
|
| 379 |
"CRASH500": "CRASH500",
|
| 380 |
"CRASH1000": "CRASH1000",
|
| 381 |
-
"stpRNG2": "STEP200", # CONFIRMED: live Deriv WS API returns "stpRNG2"
|
| 382 |
}
|
| 383 |
SYMBOL_MAP_REVERSE = {v: k for k, v in SYMBOL_MAP.items()}
|
| 384 |
|
|
@@ -408,7 +408,7 @@ ASSET_REGISTRY: Dict[str, dict] = {
|
|
| 408 |
"V100_1s": {"symbol": "1HZ100V", "base_vol": 100.0, "max_pos": 0.002},
|
| 409 |
"CRASH500": {"symbol": "CRASH500", "base_vol": 50.0, "max_pos": 0.003},
|
| 410 |
"CRASH1000":{"symbol": "CRASH1000", "base_vol": 100.0, "max_pos": 0.002},
|
| 411 |
-
"STEP200": {"symbol": "stpRNG2", "base_vol": 200.0, "max_pos": 0.002}, # CONFIRMED
|
| 412 |
}
|
| 413 |
|
| 414 |
# ββ Per-asset MULTUP/MULTDOWN multipliers (BROKER-VALIDATED ACCEPTABLE RANGES) ββ
|
|
@@ -468,16 +468,16 @@ ASSET_ACCEPTABLE_MULTIPLIERS: Dict[str, List[int]] = {
|
|
| 468 |
# Stop-loss as fraction of stake per asset (capped to protect $6 account)
|
| 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,
|
| 477 |
-
"JD100": 0.50,
|
| 478 |
-
"V100": 0.50,
|
| 479 |
"V100_1s": 0.40,
|
| 480 |
-
"CRASH500": 0.50,
|
| 481 |
"CRASH1000":0.50,
|
| 482 |
"STEP200": 0.55,
|
| 483 |
}
|
|
@@ -486,12 +486,12 @@ ASSET_STOP_LOSS_FRAC: Dict[str, float] = {
|
|
| 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,
|
| 493 |
-
"JD100": 0.80,
|
| 494 |
-
"V100": 0.80,
|
| 495 |
"V100_1s": 0.70,
|
| 496 |
"CRASH500": 0.80,
|
| 497 |
"CRASH1000":0.80,
|
|
@@ -521,8 +521,8 @@ GAMMA = 0.99
|
|
| 521 |
LAMBDA_RANK = 0.4
|
| 522 |
LAMBDA_RISK = 0.3
|
| 523 |
REPLAY_CAPACITY = 10_000
|
| 524 |
-
TRAIN_BATCH = 2 # FIX
|
| 525 |
-
TRAIN_EVERY_N = 2 # FIX
|
| 526 |
|
| 527 |
# Connection
|
| 528 |
WS_RECONNECT_DELAY = 5
|
|
@@ -829,15 +829,29 @@ class AssetSnapshot:
|
|
| 829 |
self.training_steps = int(training.get("training_steps", self.training_steps))
|
| 830 |
|
| 831 |
if voting:
|
| 832 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 833 |
self.dominant_signal = (
|
| 834 |
-
|
| 835 |
-
if isinstance(
|
| 836 |
-
and
|
| 837 |
else "NEUTRAL"
|
| 838 |
)
|
| 839 |
self.buy_count = int(voting.get("buy_count", self.buy_count))
|
| 840 |
self.sell_count = int(voting.get("sell_count", self.sell_count))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 841 |
|
| 842 |
self.last_updated = snapshot.get("last_updated", time.time())
|
| 843 |
|
|
@@ -847,6 +861,9 @@ class AssetSnapshot:
|
|
| 847 |
|
| 848 |
@property
|
| 849 |
def signal_confidence(self) -> float:
|
|
|
|
|
|
|
|
|
|
| 850 |
if self.total_votes == 0:
|
| 851 |
return 0.0
|
| 852 |
return max(self.buy_count, self.sell_count) / self.total_votes
|
|
@@ -6510,7 +6527,7 @@ class PortfolioRiskManager:
|
|
| 6510 |
if self._peak_equity <= 0:
|
| 6511 |
return 0.0
|
| 6512 |
raw_dd = (self._peak_equity - self._current_equity) / self._peak_equity
|
| 6513 |
-
return min(1.0, max(0.0, raw_dd)) # FIX
|
| 6514 |
|
| 6515 |
def _get_max_pos(self, asset_id: str) -> float:
|
| 6516 |
return self.asset_registry.get(asset_id, {}).get("max_pos", 0.002)
|
|
@@ -6796,8 +6813,8 @@ class QuasarAXRVIBridge:
|
|
| 6796 |
reward_strategy: str = "simple",
|
| 6797 |
hub_ws_url: str = os.environ.get("QUASAR_HUB_URL", "ws://localhost:7860/ws/subscribe"),
|
| 6798 |
enable_logging: bool = True,
|
| 6799 |
-
checkpoint_dir: str = "./
|
| 6800 |
-
resume: bool = False, # FIX
|
| 6801 |
hf_repo_id: Optional[str] = "KarlQuant/k1rl-checkpoints", # HF Dataset repo
|
| 6802 |
):
|
| 6803 |
self.config = config or AssetRankerConfig()
|
|
@@ -9061,7 +9078,7 @@ class RankerCheckpointManager:
|
|
| 9061 |
|
| 9062 |
def __init__(
|
| 9063 |
self,
|
| 9064 |
-
checkpoint_dir: str = "./
|
| 9065 |
hf_repo_id: Optional[str] = None,
|
| 9066 |
):
|
| 9067 |
self.checkpoint_dir = checkpoint_dir
|
|
@@ -10370,8 +10387,8 @@ async def run_live_trading_system(
|
|
| 10370 |
hub_ws_url: str = "ws://localhost:7860/ws/subscribe",
|
| 10371 |
enable_logging: bool = True,
|
| 10372 |
shreve_config: Optional[ShreveConfig] = None,
|
| 10373 |
-
checkpoint_dir: str = "./
|
| 10374 |
-
resume: bool = False, # FIX
|
| 10375 |
hf_repo_id: Optional[str] = "KarlQuant/k1rl-checkpoints", # HF Dataset repo
|
| 10376 |
) -> None:
|
| 10377 |
config = AssetRankerConfig(
|
|
@@ -10655,7 +10672,7 @@ def test_components() -> None:
|
|
| 10655 |
def _parse_args():
|
| 10656 |
"""Parse CLI args, stripping any Jupyter kernel args."""
|
| 10657 |
filtered = [a for a in sys.argv[1:] if not a.startswith("-f")]
|
| 10658 |
-
parser = argparse.ArgumentParser(description="QUASAR AXRVI Ranker v7 β Shreve Framework
|
| 10659 |
parser.add_argument("--test", action="store_true",
|
| 10660 |
help="Run component tests and exit")
|
| 10661 |
parser.add_argument("--assets", nargs="+",
|
|
@@ -10684,12 +10701,12 @@ def _parse_args():
|
|
| 10684 |
help="[S6/S8] Trade horizon Ο in seconds (default 60)")
|
| 10685 |
parser.add_argument("--martingale-epsilon", type=float, default=0.05,
|
| 10686 |
help="[S7] Gate E martingale deviation threshold (default 0.05)")
|
| 10687 |
-
parser.add_argument("--checkpoint-dir", default="./
|
| 10688 |
-
help="Directory for full-state checkpoints (default ./Ranker7
|
| 10689 |
parser.add_argument("--no-resume", dest="no_resume", action="store_true", default=True,
|
| 10690 |
-
help="
|
| 10691 |
parser.add_argument("--resume", dest="no_resume", action="store_false",
|
| 10692 |
-
help="Restore from latest Ranker7 checkpoint
|
| 10693 |
parser.add_argument("--hf-repo", default=None,
|
| 10694 |
metavar="OWNER/REPO",
|
| 10695 |
help="Hugging Face Dataset repo for checkpoint sync "
|
|
@@ -10746,7 +10763,7 @@ if __name__ == "__main__":
|
|
| 10746 |
hub_ws_url = args.hub,
|
| 10747 |
enable_logging = not args.no_logs,
|
| 10748 |
checkpoint_dir = args.checkpoint_dir,
|
| 10749 |
-
resume = not args.no_resume, #
|
| 10750 |
hf_repo_id = args.hf_repo or "KarlQuant/k1rl-checkpoints",
|
| 10751 |
)
|
| 10752 |
|
|
|
|
| 378 |
"1HZ100V": "V100_1s",
|
| 379 |
"CRASH500": "CRASH500",
|
| 380 |
"CRASH1000": "CRASH1000",
|
| 381 |
+
"stpRNG2": "STEP200", # CONFIRMED: live Deriv WS API returns "stpRNG2"
|
| 382 |
}
|
| 383 |
SYMBOL_MAP_REVERSE = {v: k for k, v in SYMBOL_MAP.items()}
|
| 384 |
|
|
|
|
| 408 |
"V100_1s": {"symbol": "1HZ100V", "base_vol": 100.0, "max_pos": 0.002},
|
| 409 |
"CRASH500": {"symbol": "CRASH500", "base_vol": 50.0, "max_pos": 0.003},
|
| 410 |
"CRASH1000":{"symbol": "CRASH1000", "base_vol": 100.0, "max_pos": 0.002},
|
| 411 |
+
"STEP200": {"symbol": "stpRNG2", "base_vol": 200.0, "max_pos": 0.002}, # CONFIRMED live symbol
|
| 412 |
}
|
| 413 |
|
| 414 |
# ββ Per-asset MULTUP/MULTDOWN multipliers (BROKER-VALIDATED ACCEPTABLE RANGES) ββ
|
|
|
|
| 468 |
# Stop-loss as fraction of stake per asset (capped to protect $6 account)
|
| 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,
|
| 477 |
+
"JD100": 0.50,
|
| 478 |
+
"V100": 0.50,
|
| 479 |
"V100_1s": 0.40,
|
| 480 |
+
"CRASH500": 0.50,
|
| 481 |
"CRASH1000":0.50,
|
| 482 |
"STEP200": 0.55,
|
| 483 |
}
|
|
|
|
| 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,
|
| 493 |
+
"JD100": 0.80,
|
| 494 |
+
"V100": 0.80,
|
| 495 |
"V100_1s": 0.70,
|
| 496 |
"CRASH500": 0.80,
|
| 497 |
"CRASH1000":0.80,
|
|
|
|
| 521 |
LAMBDA_RANK = 0.4
|
| 522 |
LAMBDA_RISK = 0.3
|
| 523 |
REPLAY_CAPACITY = 10_000
|
| 524 |
+
TRAIN_BATCH = 2 # FIX: Lowered to 2 β trains after 2 closed trades
|
| 525 |
+
TRAIN_EVERY_N = 2 # FIX: Check every 2 rank cycles
|
| 526 |
|
| 527 |
# Connection
|
| 528 |
WS_RECONNECT_DELAY = 5
|
|
|
|
| 829 |
self.training_steps = int(training.get("training_steps", self.training_steps))
|
| 830 |
|
| 831 |
if voting:
|
| 832 |
+
# ββ CORE FIX 6: prefer latest_signal (per-message, always fresh) ββ
|
| 833 |
+
# dominant_signal = accumulated ALL-TIME vote majority β stale.
|
| 834 |
+
# With 7.5K historical SELL votes, a fresh BUY is invisible.
|
| 835 |
+
# latest_signal = set by hub on EVERY voting message received β
|
| 836 |
+
# always reflects the engine's most recent inference output.
|
| 837 |
+
_raw_latest = voting.get("latest_signal", "")
|
| 838 |
+
_raw_dominant = voting.get("dominant_signal", self.dominant_signal)
|
| 839 |
+
# Use latest_signal if present and valid, else fall back to dominant
|
| 840 |
+
_preferred = _raw_latest if _raw_latest.upper() in {"BUY", "SELL", "NEUTRAL"} else _raw_dominant
|
| 841 |
self.dominant_signal = (
|
| 842 |
+
_preferred.upper()
|
| 843 |
+
if isinstance(_preferred, str)
|
| 844 |
+
and _preferred.upper() in {"BUY", "SELL", "NEUTRAL"}
|
| 845 |
else "NEUTRAL"
|
| 846 |
)
|
| 847 |
self.buy_count = int(voting.get("buy_count", self.buy_count))
|
| 848 |
self.sell_count = int(voting.get("sell_count", self.sell_count))
|
| 849 |
+
# When using latest_signal, confidence = 1.0 (direct model output,
|
| 850 |
+
# not a vote ratio). Override only if we actually got latest_signal.
|
| 851 |
+
if _raw_latest.upper() in {"BUY", "SELL"}:
|
| 852 |
+
self._latest_signal_confidence = 1.0
|
| 853 |
+
else:
|
| 854 |
+
self._latest_signal_confidence = None # use vote ratio
|
| 855 |
|
| 856 |
self.last_updated = snapshot.get("last_updated", time.time())
|
| 857 |
|
|
|
|
| 861 |
|
| 862 |
@property
|
| 863 |
def signal_confidence(self) -> float:
|
| 864 |
+
# ββ CORE FIX 6b: use 1.0 when signal came from latest_signal ββ
|
| 865 |
+
if hasattr(self, "_latest_signal_confidence") and self._latest_signal_confidence is not None:
|
| 866 |
+
return self._latest_signal_confidence
|
| 867 |
if self.total_votes == 0:
|
| 868 |
return 0.0
|
| 869 |
return max(self.buy_count, self.sell_count) / self.total_votes
|
|
|
|
| 6527 |
if self._peak_equity <= 0:
|
| 6528 |
return 0.0
|
| 6529 |
raw_dd = (self._peak_equity - self._current_equity) / self._peak_equity
|
| 6530 |
+
return min(1.0, max(0.0, raw_dd)) # FIX: clamp [0,1]
|
| 6531 |
|
| 6532 |
def _get_max_pos(self, asset_id: str) -> float:
|
| 6533 |
return self.asset_registry.get(asset_id, {}).get("max_pos", 0.002)
|
|
|
|
| 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 = "./Ranker8", # FIX: fresh folder
|
| 6817 |
+
resume: bool = False, # FIX: fresh start
|
| 6818 |
hf_repo_id: Optional[str] = "KarlQuant/k1rl-checkpoints", # HF Dataset repo
|
| 6819 |
):
|
| 6820 |
self.config = config or AssetRankerConfig()
|
|
|
|
| 9078 |
|
| 9079 |
def __init__(
|
| 9080 |
self,
|
| 9081 |
+
checkpoint_dir: str = "./Ranker8",
|
| 9082 |
hf_repo_id: Optional[str] = None,
|
| 9083 |
):
|
| 9084 |
self.checkpoint_dir = checkpoint_dir
|
|
|
|
| 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 = "./Ranker8",
|
| 10391 |
+
resume: bool = False, # FIX: fresh start
|
| 10392 |
hf_repo_id: Optional[str] = "KarlQuant/k1rl-checkpoints", # HF Dataset repo
|
| 10393 |
) -> None:
|
| 10394 |
config = AssetRankerConfig(
|
|
|
|
| 10672 |
def _parse_args():
|
| 10673 |
"""Parse CLI args, stripping any Jupyter kernel args."""
|
| 10674 |
filtered = [a for a in sys.argv[1:] if not a.startswith("-f")]
|
| 10675 |
+
parser = argparse.ArgumentParser(description="QUASAR AXRVI Ranker v7 β Shreve Framework")
|
| 10676 |
parser.add_argument("--test", action="store_true",
|
| 10677 |
help="Run component tests and exit")
|
| 10678 |
parser.add_argument("--assets", nargs="+",
|
|
|
|
| 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="./Ranker8",
|
| 10705 |
+
help="Directory for full-state checkpoints (default ./Ranker7)")
|
| 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 Ranker7 checkpoint")
|
| 10710 |
parser.add_argument("--hf-repo", default=None,
|
| 10711 |
metavar="OWNER/REPO",
|
| 10712 |
help="Hugging Face Dataset repo for checkpoint sync "
|
|
|
|
| 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 Ranker8
|
| 10767 |
hf_repo_id = args.hf_repo or "KarlQuant/k1rl-checkpoints",
|
| 10768 |
)
|
| 10769 |
|