diff --git a/README.md b/README.md index 2329570..a0ba7c0 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,7 @@ Claude: [compile → clean cache → backtest → parse XML report → analyze 1 ### What it covers -28 MCP tools across the full EA development loop: +43 MCP tools across the full EA development loop: ``` list_set_files / describe_sweep / patch_set_file / set_from_optimization @@ -235,7 +235,7 @@ DISPLAY=:99 xdpyinfo | grep dimensions --- -## MCP Tools (28) +## MCP Tools (43) ### Core workflow @@ -247,6 +247,25 @@ DISPLAY=:99 xdpyinfo | grep dimensions | `analyze_report` | Read `analysis.json` from any report directory | | `compare_baseline` | Compare report vs baseline, return winner/loser verdict | | `compile_ea` | Compile MQL5 EA via MetaEditor | +| `list_experts` | List all EAs in MQL5/Experts directory | +| `list_indicators` | List all indicators in MQL5/Indicators directory | +| `list_scripts` | List all scripts in MQL5/Scripts directory | +| `healthcheck` | Quick server health check | + +### Granular Analytics (individual analysis) + +| Tool | Description | +|------|-------------| +| `analyze_monthly_pnl` | Monthly P/L breakdown only | +| `analyze_drawdown_events` | Drawdown events and causes only | +| `analyze_top_losses` | Worst losing deals only | +| `analyze_loss_sequences` | Consecutive loss patterns only | +| `analyze_position_pairs` | Position hold time and P/L pairs | +| `analyze_direction_bias` | Buy vs Sell performance | +| `analyze_streaks` | Win/loss streak analysis | +| `analyze_concurrent_peak` | Peak simultaneous positions | + +Use these for targeted analysis, or `analyze_report` to run all at once. ### Monitoring @@ -262,6 +281,8 @@ DISPLAY=:99 xdpyinfo | grep dimensions | Tool | Description | |------|-------------| | `list_reports` | Compact table of all runs with key metrics — no full analysis needed | +| `get_latest_report` | Get most recent report with optional equity chart | +| `search_reports` | Find reports by EA, symbol, date range, or profit criteria | | `tail_log` | Read last N lines of any log; `filter=errors` to see only failures | | `prune_reports` | Delete old report directories, keep last N (skips `_opt` dirs) | diff --git a/WINDSURF_SETUP.md b/WINDSURF_SETUP.md index 1f33307..0978a5b 100644 --- a/WINDSURF_SETUP.md +++ b/WINDSURF_SETUP.md @@ -41,9 +41,9 @@ In Windsurf chat, test with: Run verify_setup ``` -## Deployment ke Multiple Machines +## Deployment to Multiple Machines -### Build untuk Distribution +### Build for Distribution ```bash # Build release binary cargo build --release @@ -51,7 +51,7 @@ cargo build --release # Create tarball tar -czf mt5-quant-macos-arm64.tar.gz -C target/release mt5-quant -# Deploy ke remote server +# Deploy to remote server scp mt5-quant-macos-arm64.tar.gz user@server:~/ ssh user@server "tar -xzf mt5-quant-macos-arm64.tar.gz -C /opt/" ssh user@server "ln -s /opt/mt5-quant /usr/local/bin/" @@ -62,10 +62,10 @@ scp -r config/mt5-quant.yaml user@server:~/.config/mt5-quant/config/ ### Target Machine Requirements - MetaTrader 5 installed (via Wine/CrossOver) -- Config file di `~/.config/mt5-quant/config/mt5-quant.yaml` +- Config file at `~/.config/mt5-quant/config/mt5-quant.yaml` - **NO Python required!** -### Windsurf Config di Target Machine +### Windsurf Config on Target Machine ```yaml mcpServers: mt5-quant: @@ -80,7 +80,7 @@ mcpServers: 3. Test executable manually: `./target/release/mt5-quant --help` ### Config not found -Set `MT5_MCP_HOME` environment variable atau pastikan config di default location: +Set `MT5_MCP_HOME` environment variable or ensure config is at default location: - macOS: `~/.config/mt5-quant/config/mt5-quant.yaml` ### Permission denied diff --git a/docs/ARCHITECTURE.md b/docs/ARCHITECTURE.md index fe5c7b7..6c08192 100644 --- a/docs/ARCHITECTURE.md +++ b/docs/ARCHITECTURE.md @@ -33,8 +33,25 @@ MT5-Quant/ │ │ ├── backtest.rs # 5-stage pipeline (COMPILE→CLEAN→BACKTEST→EXTRACT→ANALYZE) │ │ └── stages.rs # Pipeline stage definitions │ └── tools/ # MCP tool definitions -│ ├── definitions.rs # 27 tool schemas -│ └── handlers.rs # Tool dispatch +│ ├── definitions/ # Tool schemas (9 domain modules, 43 tools) +│ │ ├── mod.rs +│ │ ├── analytics.rs # 9 analysis tools +│ │ ├── backtest.rs # 4 backtest tools +│ │ ├── baseline.rs # 1 baseline tool +│ │ ├── experts.rs # 4 EA/indicator/script tools +│ │ ├── optimization.rs # 4 optimization tools +│ │ ├── reports.rs # 11 report management tools +│ │ ├── setfiles.rs # 8 .set file tools +│ │ └── system.rs # 3 system tools +│ └── handlers/ # Tool dispatch (9 domain modules) +│ ├── mod.rs +│ ├── analysis.rs +│ ├── backtest.rs +│ ├── experts.rs +│ ├── optimization.rs +│ ├── reports.rs +│ ├── setfiles.rs +│ └── system.rs │ ├── scripts/ │ ├── setup.sh # Auto-detect Wine/MT5, write config, register MCP diff --git a/src/compile/mql_compiler.rs b/src/compile/mql_compiler.rs index a4351bb..412ab7f 100644 --- a/src/compile/mql_compiler.rs +++ b/src/compile/mql_compiler.rs @@ -56,17 +56,19 @@ impl MqlCompiler { sync.dest_mq5.display() ); - // MetaEditor always writes to MQL5/compile.log (ignores /log: arg). - // Clear it before compile so we only see output from this run. - let mql5_log = mt5_dir.join("MQL5").join("compile.log"); - let _ = fs::remove_file(&mql5_log); - let log_path = wine_prefix.join("drive_c").join("_mt5mcp_compile.log"); + let _ = fs::remove_file(&log_path); // clear stale log before compile + self.run_metaeditor(wine_exe, &wine_prefix, &metaeditor, &sync.dest_mq5, &log_path)?; - // Read from MQL5/compile.log (MetaEditor's actual output location). - let log_text = Self::read_log(&mql5_log); - let _ = fs::remove_file(&log_path); // clean up unused /log: output if any + // MetaEditor writes to the /log: path. Fallback: adjacent {ea_name}.log. + let log_text = if log_path.exists() { + Self::read_log(&log_path) + } else { + let adjacent = sync.dest_mq5.with_extension("log"); + Self::read_log(&adjacent) + }; + let _ = fs::remove_file(&log_path); tracing::info!("Compile log ({} chars):\n{}", log_text.len(), &log_text[..log_text.len().min(500)]); // Log format: "path : error: message" / "path : warning: message"