@vizzor/cli 0.13.1 → 0.14.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/README.md +250 -192
  2. package/chronovisor-engine/pyproject.toml +31 -0
  3. package/chronovisor-engine/src/__init__.py +0 -0
  4. package/chronovisor-engine/src/inference/__init__.py +0 -0
  5. package/chronovisor-engine/src/inference/predict.py +44 -0
  6. package/chronovisor-engine/src/model_catalog.py +219 -0
  7. package/chronovisor-engine/src/models/__init__.py +0 -0
  8. package/chronovisor-engine/src/models/anomaly_detector.py +104 -0
  9. package/chronovisor-engine/src/models/blockchain_cycle_analyzer.py +217 -0
  10. package/chronovisor-engine/src/models/catalyst_event_model.py +70 -0
  11. package/chronovisor-engine/src/models/conformal_interval.py +50 -0
  12. package/chronovisor-engine/src/models/divergence_detector.py +247 -0
  13. package/chronovisor-engine/src/models/drift_monitor.py +51 -0
  14. package/chronovisor-engine/src/models/intent_classifier.py +189 -0
  15. package/chronovisor-engine/src/models/lstm_predictor.py +143 -0
  16. package/chronovisor-engine/src/models/microstructure_specialist.py +65 -0
  17. package/chronovisor-engine/src/models/narrative_detector.py +418 -0
  18. package/chronovisor-engine/src/models/portfolio_optimizer.py +162 -0
  19. package/chronovisor-engine/src/models/project_risk_scorer.py +184 -0
  20. package/chronovisor-engine/src/models/pump_detector.py +344 -0
  21. package/chronovisor-engine/src/models/regime_detector.py +127 -0
  22. package/chronovisor-engine/src/models/rug_detector.py +197 -0
  23. package/chronovisor-engine/src/models/sentiment_analyzer.py +257 -0
  24. package/chronovisor-engine/src/models/signal_classifier.py +191 -0
  25. package/chronovisor-engine/src/models/stacking_meta.py +56 -0
  26. package/chronovisor-engine/src/models/strategy_bandit.py +191 -0
  27. package/chronovisor-engine/src/models/ta_interpreter.py +341 -0
  28. package/chronovisor-engine/src/models/target_quantile.py +96 -0
  29. package/chronovisor-engine/src/models/trend_scorer.py +107 -0
  30. package/chronovisor-engine/src/models/wallet_classifier.py +261 -0
  31. package/chronovisor-engine/src/server.py +1686 -0
  32. package/chronovisor-engine/src/training/__init__.py +0 -0
  33. package/chronovisor-engine/src/training/data_loader.py +635 -0
  34. package/chronovisor-engine/src/training/pipeline.py +130 -0
  35. package/chronovisor-engine/src/training/train_catalyst.py +169 -0
  36. package/chronovisor-engine/src/training/train_classifier.py +159 -0
  37. package/chronovisor-engine/src/training/train_conformal.py +106 -0
  38. package/chronovisor-engine/src/training/train_direction.py +215 -0
  39. package/chronovisor-engine/src/training/train_drift.py +57 -0
  40. package/chronovisor-engine/src/training/train_isotonic.py +58 -0
  41. package/chronovisor-engine/src/training/train_lstm.py +217 -0
  42. package/chronovisor-engine/src/training/train_microstructure.py +102 -0
  43. package/chronovisor-engine/src/training/train_narrative.py +168 -0
  44. package/chronovisor-engine/src/training/train_pump.py +109 -0
  45. package/chronovisor-engine/src/training/train_regime.py +116 -0
  46. package/chronovisor-engine/src/training/train_rug.py +58 -0
  47. package/chronovisor-engine/src/training/train_sentiment.py +63 -0
  48. package/chronovisor-engine/src/training/train_stacking_meta.py +74 -0
  49. package/chronovisor-engine/src/training/train_target_quantile.py +115 -0
  50. package/chronovisor-engine/src/training/train_trend.py +101 -0
  51. package/dist/index.js +19124 -11698
  52. package/dist/index.js.map +1 -1
  53. package/package.json +3 -1
@@ -0,0 +1,115 @@
1
+ """Target quantile trainer for bull/base/bear price-delta forecasts."""
2
+
3
+ import re
4
+ import time
5
+ from pathlib import Path
6
+
7
+ import joblib
8
+ import numpy as np
9
+ from sklearn.ensemble import GradientBoostingRegressor
10
+ from sklearn.metrics import mean_absolute_error
11
+
12
+ from .data_loader import load_target_outcomes
13
+ from .train_direction import ALL_FEATURE_KEYS
14
+
15
+
16
+ def _horizon_to_minutes(horizon: str) -> float:
17
+ total = 0.0
18
+ for amount, unit in re.findall(r"(\d+)(mo|y|w|d|h|m)", str(horizon or "").strip().lower()):
19
+ quantity = float(amount or 0)
20
+ if unit == "m":
21
+ total += quantity
22
+ elif unit == "h":
23
+ total += quantity * 60
24
+ elif unit == "d":
25
+ total += quantity * 1440
26
+ elif unit == "w":
27
+ total += quantity * 10080
28
+ elif unit == "mo":
29
+ total += quantity * 43200
30
+ elif unit == "y":
31
+ total += quantity * 525600
32
+ return total if total > 0 else 240.0
33
+
34
+
35
+ class TargetQuantileTrainer:
36
+ model_name = "target_xgb_quantile"
37
+ artifact_path = Path("models") / "target_xgb_quantile.joblib"
38
+
39
+ def run(self, days: int = 180) -> dict:
40
+ start = time.time()
41
+ outcomes = load_target_outcomes(days)
42
+ if len(outcomes) < 60:
43
+ return {
44
+ "model": self.model_name,
45
+ "status": "skipped",
46
+ "metrics": {"samples": len(outcomes)},
47
+ "duration_seconds": round(time.time() - start, 2),
48
+ "artifact_path": "",
49
+ "error": f"Need at least 60 samples, got {len(outcomes)}",
50
+ }
51
+
52
+ rows = []
53
+ for outcome in outcomes:
54
+ features = dict(outcome["features"])
55
+ features["probability_hint"] = float(outcome.get("probability", 0.5))
56
+ features["horizon_minutes"] = _horizon_to_minutes(str(outcome.get("horizon", "4h")))
57
+ rows.append(features)
58
+
59
+ feature_keys = ALL_FEATURE_KEYS + ["probability_hint", "horizon_minutes"]
60
+ X = np.array([[row.get(key, 0.0) for key in feature_keys] for row in rows], dtype=np.float32)
61
+ y = np.array([float(outcome["changePct"]) for outcome in outcomes], dtype=np.float32)
62
+
63
+ n = len(X)
64
+ train_end = int(n * 0.70)
65
+ val_end = int(n * 0.85)
66
+ X_train, X_val, X_test = X[:train_end], X[train_end:val_end], X[val_end:]
67
+ y_train, y_val, y_test = y[:train_end], y[train_end:val_end], y[val_end:]
68
+
69
+ models = {
70
+ "q10": GradientBoostingRegressor(
71
+ loss="quantile", alpha=0.10, n_estimators=250, max_depth=3, random_state=42
72
+ ),
73
+ "q50": GradientBoostingRegressor(
74
+ loss="absolute_error", n_estimators=250, max_depth=3, random_state=42
75
+ ),
76
+ "q90": GradientBoostingRegressor(
77
+ loss="quantile", alpha=0.90, n_estimators=250, max_depth=3, random_state=42
78
+ ),
79
+ }
80
+
81
+ for model in models.values():
82
+ model.fit(X_train, y_train)
83
+
84
+ low = models["q10"].predict(X_test)
85
+ base = models["q50"].predict(X_test)
86
+ high = models["q90"].predict(X_test)
87
+ coverage = float(np.mean((y_test >= low) & (y_test <= high)))
88
+ mae = float(mean_absolute_error(y_test, base))
89
+
90
+ self.artifact_path.parent.mkdir(parents=True, exist_ok=True)
91
+ joblib.dump(
92
+ {
93
+ "models": models,
94
+ "feature_keys": feature_keys,
95
+ "trained_at": str(int(time.time())),
96
+ "accuracy": 1.0 / (1.0 + mae),
97
+ "mae": mae,
98
+ "coverage": coverage,
99
+ },
100
+ self.artifact_path,
101
+ )
102
+
103
+ return {
104
+ "model": self.model_name,
105
+ "status": "success",
106
+ "metrics": {
107
+ "mae": mae,
108
+ "coverage": coverage,
109
+ "train_samples": len(X_train),
110
+ "val_samples": len(X_val),
111
+ "test_samples": len(X_test),
112
+ },
113
+ "duration_seconds": round(time.time() - start, 2),
114
+ "artifact_path": str(self.artifact_path),
115
+ }
@@ -0,0 +1,101 @@
1
+ """Trend scorer training on real historical OHLCV and snapshot-derived features."""
2
+
3
+ import logging
4
+ import time
5
+
6
+ import numpy as np
7
+
8
+ from .data_loader import load_trend_training_frame
9
+ from .pipeline import TrainingPipeline
10
+
11
+ logger = logging.getLogger(__name__)
12
+
13
+
14
+ class TrendTrainer(TrainingPipeline):
15
+ FEATURE_KEYS = [
16
+ "price_change_24h",
17
+ "price_change_7d",
18
+ "volume_24h",
19
+ "market_cap",
20
+ "volume_to_mcap_ratio",
21
+ "rank",
22
+ ]
23
+
24
+ def __init__(self):
25
+ super().__init__("trend_scorer")
26
+
27
+ def load_data(self):
28
+ logger.info("Loading real trend scoring data from OHLCV history...")
29
+ frame = load_trend_training_frame(days=240, timeframe="4h")
30
+ if frame.empty:
31
+ raise RuntimeError("No historical trend training data available")
32
+ return frame
33
+
34
+ def preprocess(self, data):
35
+ data = data.sort_index().reset_index(drop=True)
36
+ X = data[self.FEATURE_KEYS].fillna(0.0).astype(np.float32).values
37
+ y = data["y"].astype(np.float32).values
38
+
39
+ n = len(X)
40
+ train_end = int(n * 0.70)
41
+ val_end = int(n * 0.85)
42
+
43
+ return X[:train_end], X[train_end:val_end], X[val_end:], y[:train_end], y[train_end:val_end], y[val_end:]
44
+
45
+ def train(self, X_train, y_train, X_val, y_val):
46
+ try:
47
+ import xgboost as xgb
48
+
49
+ model = xgb.XGBRegressor(
50
+ n_estimators=300,
51
+ max_depth=4,
52
+ learning_rate=0.05,
53
+ subsample=0.85,
54
+ colsample_bytree=0.85,
55
+ reg_alpha=0.05,
56
+ reg_lambda=1.0,
57
+ objective="reg:squarederror",
58
+ eval_metric="rmse",
59
+ early_stopping_rounds=25,
60
+ random_state=42,
61
+ )
62
+ model.fit(X_train, y_train, eval_set=[(X_val, y_val)], verbose=False)
63
+ return model
64
+ except Exception:
65
+ from sklearn.ensemble import RandomForestRegressor
66
+
67
+ model = RandomForestRegressor(
68
+ n_estimators=250,
69
+ max_depth=10,
70
+ min_samples_leaf=5,
71
+ random_state=42,
72
+ n_jobs=-1,
73
+ )
74
+ model.fit(X_train, y_train)
75
+ return model
76
+
77
+ def evaluate(self, model, X_test, y_test):
78
+ from sklearn.metrics import mean_absolute_error, r2_score
79
+
80
+ preds = np.clip(model.predict(X_test), 0, 100)
81
+ return {
82
+ "r2": float(r2_score(y_test, preds)),
83
+ "mae": float(mean_absolute_error(y_test, preds)),
84
+ "test_samples": len(y_test),
85
+ }
86
+
87
+ def save(self, model, metrics):
88
+ import joblib
89
+
90
+ super().save(model, metrics)
91
+ artifact_path = self.artifact_dir.parent / "trend_scorer.joblib"
92
+ joblib.dump(
93
+ {
94
+ "model": model,
95
+ "trained_at": str(int(time.time())),
96
+ "accuracy": metrics.get("r2"),
97
+ "feature_keys": self.FEATURE_KEYS,
98
+ },
99
+ artifact_path,
100
+ )
101
+ return str(artifact_path)