diff --git a/config/initial_config.json b/config/initial_config.json index ca3b3c4..a6c8f19 100644 --- a/config/initial_config.json +++ b/config/initial_config.json @@ -1,62 +1,53 @@ { "model_type": "hybrid", "features": { - "technical_indicators": ["RSI_14", "RSI_7", "MACD_line", "MACD_signal", "MACD_hist", "BB_upper", "BB_lower", "BB_width", "ATR_14", "SMA_20", "SMA_50", "EMA_10", "EMA_20", "OBV", "stoch_k", "stoch_d", "williams_r", "CCI_20", "ROC_10"], - "lookback_periods": [3, 5, 10, 20], - "use_volume_features": true, - "use_volatility_features": true, - "use_candle_patterns": false, - "use_lag_features": true, - "lag_periods": [1, 2, 3, 5], + "use_price_position": true, + "use_momentum": true, + "use_volatility": true, + "use_volume": true, + "use_cycle": true, "use_pca": true, "pca_variance": 0.95, "use_scaler": true }, "target": { - "type": "classification", - "direction": "both", - "horizon_candles": 8, - "threshold_pct": 1.5 + "type": "regression", + "forward_periods_1h": [168, 720, 2160], + "forward_periods_4h": [42, 180, 540], + "weights": [0.2, 0.3, 0.5], + "score_range": [0, 100] }, "hyperparameters": { - "learning_rate": 0.001, + "learning_rate": 0.01, "max_depth": 5, - "n_estimators": 300, + "n_estimators": 500, "subsample": 0.8, "colsample_bytree": 0.8, - "min_child_weight": 5, + "min_child_weight": 10, "gamma": 0.3, - "reg_alpha": 0.1, - "reg_lambda": 2.0, + "reg_alpha": 0.5, + "reg_lambda": 3.0, "lstm_hidden_size": 128, "lstm_num_layers": 2, "lstm_dropout": 0.3, "lstm_epochs": 100, "lstm_batch_size": 64, - "lstm_sequence_length": 20, + "lstm_sequence_length": 30, "lstm_patience": 10 }, "strategy": { - "entry_threshold": 0.60, - "exit_type": "trailing_stop", - "stop_loss_pct": 2.0, - "take_profit_pct": 4.0, - "trailing_stop_pct": 1.5, - "position_sizing": "confidence_scaled", - "max_position_pct": 100, - "min_confidence_to_trade": 0.55, - "dynamic_sl_tp": true, - "atr_sl_multiplier": 1.5, - "atr_tp_multiplier": 3.0 + "strong_buy_threshold": 80, + "good_buy_threshold": 70, + "poor_threshold": 30 }, "training": { + "rolling_window": true, + "rolling_train_size": 2500, + "rolling_test_size": 300, "walk_forward_windows": 5, "train_pct": 0.7, "validation_pct": 0.15, - "test_pct": 0.15, - "rolling_window": true, - "rolling_train_size": 2000, - "rolling_test_size": 200 + "test_pct": 0.15 }, "timeframe": "4h" -} +} \ No newline at end of file diff --git a/dashboard/server.py b/dashboard/server.py index 8b77f87..72aa0e8 100644 --- a/dashboard/server.py +++ b/dashboard/server.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 """ -BTC ML Trading Strategy Optimizer — Web Dashboard +BTC Accumulation Signal Optimizer -- Web Dashboard FastAPI server with inline HTML/CSS/JS dashboard. """ @@ -13,42 +13,35 @@ from fastapi import FastAPI from fastapi.responses import FileResponse, HTMLResponse, JSONResponse from pydantic import BaseModel -# Add project root to path BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) sys.path.insert(0, BASE_DIR) import orchestrator -app = FastAPI(title="BTC ML Optimizer Dashboard") +app = FastAPI(title="BTC Accumulation Signal Optimizer") CONFIG_DIR = os.path.join(BASE_DIR, "config") RESULTS_DIR = os.path.join(BASE_DIR, "results") ITERATIONS_LOG = os.path.join(RESULTS_DIR, "iterations.jsonl") -# Background thread reference -_opt_thread: threading.Thread | None = None +_opt_thread = None class ConfigUpdate(BaseModel): config: dict -# ── API Endpoints ────────────────────────────────────────────── - - @app.get("/api/status") def api_status(): - status = orchestrator.get_status() - return status + return orchestrator.get_status() @app.get("/api/iterations") def api_iterations(): iterations = orchestrator.load_iteration_history() - # Strip heavy config from list view slim = [] for it in iterations: - entry = {k: v for k, v in it.items() if k != "config"} + entry = {k: v for k, v in it.items() if k not in ("config", "results")} slim.append(entry) return slim @@ -94,11 +87,11 @@ def api_stop(): def api_best(): best_path = os.path.join(CONFIG_DIR, "best_config.json") if not os.path.exists(best_path): - return {"config": None, "sharpe": 0} + return {"config": None, "best_score": 0} with open(best_path) as f: config = json.load(f) iterations = orchestrator.load_iteration_history() - best_iter = max(iterations, key=lambda x: x.get("sharpe", 0)) if iterations else {} + best_iter = max(iterations, key=lambda x: x.get("cost_improvement", 0)) if iterations else {} return {"config": config, "best_iteration": best_iter} @@ -117,15 +110,12 @@ def api_download_best_config(): return JSONResponse({"error": "No best config yet"}, status_code=404) -# ── Dashboard HTML ───────────────────────────────────────────── - - DASHBOARD_HTML = """ -BTC ML Optimizer +BTC Accumulation Signal Optimizer @@ -138,7 +128,6 @@ h1{font-size:1.5rem;font-weight:700;display:flex;align-items:center;gap:10px} h1 .btc{color:var(--accent);font-size:1.8rem} h2{font-size:1rem;font-weight:600;color:var(--text-dim);margin-bottom:12px;text-transform:uppercase;letter-spacing:.05em;font-size:.8rem} -/* Header */ .header{display:flex;justify-content:space-between;align-items:center;padding:16px 0;border-bottom:1px solid var(--border);margin-bottom:16px;flex-wrap:wrap;gap:12px} .controls{display:flex;gap:8px;align-items:center} .btn{padding:8px 18px;border:none;border-radius:6px;font-family:inherit;font-weight:600;font-size:.85rem;cursor:pointer;transition:all .15s} @@ -147,7 +136,6 @@ h2{font-size:1rem;font-weight:600;color:var(--text-dim);margin-bottom:12px;text- .btn-secondary{background:var(--border);color:var(--text)}.btn-secondary:hover{background:var(--card-hover)} .btn:disabled{opacity:.4;cursor:not-allowed} -/* Status badge */ .status-badge{display:inline-flex;align-items:center;gap:6px;padding:4px 12px;border-radius:20px;font-size:.8rem;font-weight:600} .status-idle{background:#1e3a5f;color:#60a5fa} .status-running{background:#1a3a2a;color:var(--green)} @@ -156,19 +144,16 @@ h2{font-size:1rem;font-weight:600;color:var(--text-dim);margin-bottom:12px;text- .pulse{width:8px;height:8px;border-radius:50%;background:currentColor;animation:pulse 1.5s infinite} @keyframes pulse{0%,100%{opacity:1}50%{opacity:.3}} -/* Best Sharpe display */ -.best-sharpe{text-align:right} -.best-sharpe .label{font-size:.7rem;text-transform:uppercase;letter-spacing:.1em;color:var(--text-dim)} -.best-sharpe .value{font-size:2.2rem;font-weight:700;color:var(--accent);font-family:var(--mono)} +.best-score{text-align:right} +.best-score .label{font-size:.7rem;text-transform:uppercase;letter-spacing:.1em;color:var(--text-dim)} +.best-score .value{font-size:2.2rem;font-weight:700;color:var(--accent);font-family:var(--mono)} +.best-score .unit{font-size:1rem;color:var(--text-dim)} -/* Grid layout */ .grid{display:grid;grid-template-columns:1fr 360px;gap:16px} @media(max-width:900px){.grid{grid-template-columns:1fr}} -/* Cards */ .card{background:var(--card);border-radius:10px;padding:16px;border:1px solid var(--border)} -/* Iteration table */ .table-wrap{overflow-x:auto;max-height:400px;overflow-y:auto} table{width:100%;border-collapse:collapse;font-size:.82rem} th{position:sticky;top:0;background:var(--card);text-align:left;padding:8px 10px;color:var(--text-dim);font-weight:600;border-bottom:2px solid var(--border);font-size:.75rem;text-transform:uppercase;letter-spacing:.04em} @@ -177,15 +162,12 @@ tr.best-row{background:rgba(34,197,94,.1)} tr.best-row td:first-child{border-left:3px solid var(--green)} tr:hover{background:var(--card-hover)} -/* Chart */ .chart-container{position:relative;height:260px} -/* LLM panel */ .llm-panel{max-height:500px;overflow-y:auto} .llm-entry{padding:10px;border-bottom:1px solid var(--border);font-size:.82rem;line-height:1.5} .llm-entry .iter-label{font-weight:600;color:var(--accent);font-size:.75rem;margin-bottom:4px} -/* Config editor */ .config-section{margin-top:16px} .config-toggle{cursor:pointer;user-select:none;display:flex;align-items:center;gap:6px} .config-toggle .arrow{transition:transform .2s;font-size:.7rem} @@ -195,22 +177,19 @@ tr:hover{background:var(--card-hover)} textarea.config-editor{width:100%;height:300px;background:var(--bg);color:var(--text);border:1px solid var(--border);border-radius:6px;padding:12px;font-family:var(--mono);font-size:.8rem;resize:vertical} .config-actions{display:flex;gap:8px;margin-top:8px} -/* Downloads */ .downloads{display:flex;gap:8px;margin-top:16px;flex-wrap:wrap} .downloads a{color:var(--accent);text-decoration:none;font-size:.82rem;padding:6px 12px;border:1px solid var(--accent);border-radius:6px;transition:all .15s} .downloads a:hover{background:var(--accent);color:#000} -/* Footer */ .footer{text-align:center;color:var(--text-dim);font-size:.75rem;padding:20px 0;margin-top:16px;border-top:1px solid var(--border)}
-
-

ML Strategy Optimizer

+

Accumulation Signal Optimizer

Idle
@@ -220,47 +199,41 @@ textarea.config-editor{width:100%;height:300px;background:var(--bg);color:var(--
-
-
Best Sharpe Ratio
-
0.000
+
+
Best Cost Improvement
+
0.0%
-
-

Iterations

- +
#SharpeReturn%MaxDD%WinRateTradesPFModel
#Cost Imp%SignalsFrequencyR2BottomsTopsModel
-
-

Performance Over Iterations

+

Cost Improvement Over Iterations

- +
-

LLM Analysis

No suggestions yet.
- -

Downloads

@@ -271,7 +244,6 @@ textarea.config-editor{width:100%;height:300px;background:var(--bg);color:var(--
-
@@ -286,22 +258,21 @@ textarea.config-editor{width:100%;height:300px;background:var(--bg);color:var(--
- +