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 = """
-| # | Sharpe | Return% | MaxDD% | WinRate | Trades | PF | Model |
|---|---|---|---|---|---|---|---|
| # | Cost Imp% | Signals | Frequency | R2 | Bottoms | Tops | Model |