3930 lines
86 KiB
Markdown
3930 lines
86 KiB
Markdown
# MCP Tool Specification
|
||
|
||
Full input/output schemas for MT5-Quant tools.
|
||
|
||
> **Documentation Status:** All 90 tools are documented.
|
||
|
||
---
|
||
|
||
## `run_backtest`
|
||
|
||
Run a complete backtest pipeline: compile → clean cache → backtest → extract → analyze.
|
||
|
||
**When to call:** Any time you need fresh backtest results. Always runs the full pipeline unless `skip_*` flags are set.
|
||
|
||
### Input schema
|
||
|
||
```typescript
|
||
{
|
||
// Required
|
||
expert: string; // EA name without path or extension. e.g. "MyEA_v1.2"
|
||
|
||
// Date range — use either preset OR from+to
|
||
preset?: "last_month" | "last_3months" | "ytd" | "last_year";
|
||
from?: string; // "YYYY-MM-DD"
|
||
to?: string; // "YYYY-MM-DD"
|
||
|
||
// Optional overrides
|
||
symbol?: string; // Default from config. e.g. "XAUUSD"
|
||
timeframe?: "M1" | "M5" | "M15" | "M30" | "H1" | "H4" | "D1"; // Default: M5
|
||
deposit?: number; // Default from config. e.g. 10000
|
||
currency?: string; // Default: "USD"
|
||
model?: 0 | 1 | 2; // 0=every tick (default), 1=1min OHLC, 2=open price
|
||
set_file?: string; // Path to .set file. If omitted, uses EA defaults.
|
||
leverage?: number; // Default: 500
|
||
|
||
// Pipeline flags
|
||
skip_compile?: boolean; // Skip EA compilation (use existing .ex5)
|
||
skip_clean?: boolean; // Skip cache clean (faster but risks stale cache)
|
||
skip_analyze?: boolean; // Extract only, skip deal analysis
|
||
deep_analyze?: boolean; // Add hourly_pnl and volume_profile to analysis.json
|
||
strategy?: "grid" | "scalper" | "trend" | "hedge" | "generic";
|
||
// Analysis strategy profile (default: "grid").
|
||
// Controls depth tracking, exit keywords, and cycle grouping.
|
||
}
|
||
```
|
||
|
||
### Output schema
|
||
|
||
```typescript
|
||
{
|
||
success: boolean;
|
||
report_dir: string; // "reports/20250619_143022_MyEA_XAUUSD_M5"
|
||
duration_seconds: number;
|
||
|
||
// Inline summary from metrics.json (always present on success)
|
||
metrics: {
|
||
net_profit: number;
|
||
profit_factor: number;
|
||
max_dd_pct: number;
|
||
sharpe_ratio: number;
|
||
total_trades: number;
|
||
recovery_factor: number;
|
||
expected_payoff: number;
|
||
gross_profit: number;
|
||
gross_loss: number;
|
||
win_rate_pct: number;
|
||
avg_profit: number;
|
||
avg_loss: number;
|
||
};
|
||
|
||
// Deal analysis summary (present unless skip_analyze=true)
|
||
analysis_summary: {
|
||
green_months: number;
|
||
total_months: number;
|
||
worst_month: string; // "2025-10"
|
||
worst_month_pnl: number;
|
||
worst_dd_event_pct: number;
|
||
worst_dd_date: string;
|
||
max_grid_depth: number; // highest layer reached in any cycle
|
||
l5_plus_count: number; // cycles that reached L5+
|
||
};
|
||
|
||
// File paths for direct reading
|
||
files: {
|
||
metrics_json: string;
|
||
analysis_json: string;
|
||
// Note: deals are stored in SQLite DB, not on disk.
|
||
// Call export_deals_csv(report_id) to generate a CSV file on demand.
|
||
};
|
||
|
||
error?: string; // Present on failure
|
||
}
|
||
```
|
||
|
||
### Example
|
||
|
||
```json
|
||
// Input
|
||
{
|
||
"expert": "MyEA_v1.2",
|
||
"from": "2025-01-01",
|
||
"to": "2025-06-30",
|
||
"deposit": 10000,
|
||
"model": 0
|
||
}
|
||
|
||
// Output
|
||
{
|
||
"success": true,
|
||
"report_dir": "reports/20250619_143022_MyEA_XAUUSD_M5",
|
||
"duration_seconds": 287,
|
||
"metrics": {
|
||
"net_profit": 4832.10,
|
||
"profit_factor": 1.54,
|
||
"max_dd_pct": 12.3,
|
||
"sharpe_ratio": 1.18,
|
||
"total_trades": 891
|
||
},
|
||
"analysis_summary": {
|
||
"green_months": 5,
|
||
"total_months": 6,
|
||
"worst_month": "2025-03",
|
||
"worst_month_pnl": -412.80,
|
||
"worst_dd_event_pct": 12.3,
|
||
"worst_dd_date": "2025-03-14",
|
||
"max_grid_depth": 6,
|
||
"l5_plus_count": 8
|
||
},
|
||
"files": {
|
||
"metrics_json": "reports/20250619_143022_MyEA_XAUUSD_M5/metrics.json",
|
||
"analysis_json": "reports/20250619_143022_MyEA_XAUUSD_M5/analysis.json"
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## `run_backtest_quick`
|
||
|
||
Quick backtest using pre-compiled EA: clean cache → backtest → extract → analyze.
|
||
|
||
**When to call:** When EA code hasn't changed and you just want to test different parameters or date ranges. Faster than `run_backtest` because it skips compilation.
|
||
|
||
### Input schema
|
||
|
||
Same as `run_backtest`, but `skip_compile` is automatically set to `true`.
|
||
|
||
### Output schema
|
||
|
||
Same as `run_backtest`.
|
||
|
||
---
|
||
|
||
## `run_backtest_only`
|
||
|
||
Backtest only: clean cache → backtest → extract. No analysis phase.
|
||
|
||
**When to call:** When you just need raw trade data (stored in DB) and don't need analytics. Fastest option for batch processing. Use `export_deals_csv` afterwards if you need a CSV file.
|
||
|
||
### Input schema
|
||
|
||
Same as `run_backtest`, but `skip_compile` and `skip_analyze` are automatically set to `true`.
|
||
|
||
### Output schema
|
||
|
||
Same as `run_backtest` but without `analysis_summary`.
|
||
|
||
---
|
||
|
||
## `launch_backtest`
|
||
|
||
Fire-and-forget mode: compile → clean → launch MT5 backtest, return immediately with job info.
|
||
|
||
**When to call:** When you want to launch a backtest without waiting for completion. Use `get_backtest_status` to poll for completion.
|
||
|
||
### Input schema
|
||
|
||
```typescript
|
||
{
|
||
expert: string; // Required. EA name without path or extension
|
||
symbol?: string; // Trading symbol (default: from config or first available)
|
||
from_date?: string; // Start date YYYY.MM.DD (default: past complete month)
|
||
to_date?: string; // End date YYYY.MM.DD (default: past complete month)
|
||
timeframe?: string; // M1, M5, M15, M30, H1, H4, D1 (default: M5)
|
||
deposit?: number; // Initial deposit (default: 10000)
|
||
model?: 0 | 1 | 2; // Tick model (default: 0)
|
||
set_file?: string; // Path to .set parameter file
|
||
skip_compile?: boolean; // Skip compilation
|
||
skip_clean?: boolean; // Skip cache cleaning
|
||
timeout?: number; // Max time in seconds (default: 900)
|
||
gui?: boolean; // Enable MT5 visualization
|
||
shutdown?: boolean; // Shut down MT5 after test (default: true).
|
||
// NOTE: on Wine/macOS terminal64.exe may not exit naturally
|
||
// even with ShutdownTerminal=1. Use inactivity_kill_secs too.
|
||
inactivity_kill_secs?: number; // Kill MT5 if tester log hasn't grown for N seconds
|
||
// (default: disabled / not set). Recommended: 120.
|
||
// After silence, pipeline polls for HTML report for 30s,
|
||
// then kills MT5 unconditionally. If HTML present → extracted;
|
||
// otherwise falls back to journal extraction (no P&L data).
|
||
}
|
||
```
|
||
|
||
### Output schema
|
||
|
||
```typescript
|
||
{
|
||
success: true;
|
||
message: string; // "Backtest launched successfully..."
|
||
report_id: string; // e.g., "20250122_034455_MyEA_XAUUSD_M5"
|
||
report_dir: string; // Full path to report directory
|
||
expert: string;
|
||
symbol: string;
|
||
timeframe: string;
|
||
launched_at: string; // ISO8601 timestamp
|
||
timeout_seconds: number;
|
||
poll_hint: string; // "Call get_backtest_status with report_dir to check progress"
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## `run_rolling_backtest`
|
||
|
||
Run N consecutive weekly backtests sequentially and return aggregated results. Compiles once, then each week runs with `skip_compile`. Kills and restarts MT5 between weeks for a clean state.
|
||
|
||
**When to call:** When you want to test EA stability across multiple weeks to detect performance degradation, regime change sensitivity, or parameter drift.
|
||
|
||
### Input schema
|
||
|
||
```typescript
|
||
{
|
||
// Required
|
||
expert: string; // EA name without path or extension
|
||
|
||
// Date range — specify both or omit for auto-calculation (N weeks back to last Sunday)
|
||
from_date?: string; // "YYYY.MM.DD" (default: auto-calculate N weeks back)
|
||
to_date?: string; // "YYYY.MM.DD" (default: auto-calculate to last Sunday)
|
||
|
||
// Optional overrides
|
||
symbol?: string; // Trading symbol (default: from config or first available)
|
||
timeframe?: "M1" | "M5" | "M15" | "M30" | "H1" | "H4" | "D1"; // Default: M5
|
||
deposit?: number; // Initial deposit (default: 10000)
|
||
model?: 0 | 1 | 2; // Tick model: 0=Every tick, 1=OHLC, 2=Open prices
|
||
set_file?: string; // Path to .set parameter file for EA inputs
|
||
|
||
// Rolling options
|
||
weeks?: number; // Number of weekly backtests to run (default: 4, max: 52)
|
||
|
||
// Pipeline flags
|
||
skip_compile?: boolean; // Skip initial compilation (default: false — compiles on first week)
|
||
shutdown?: boolean; // Close MT5 after backtest completes (default: true)
|
||
kill_existing?: boolean; // Kill any running MT5 instance first (default: true)
|
||
timeout?: number; // Max wait time per week in seconds (default: 900)
|
||
gui?: boolean; // Enable MT5 visualization window (default: false)
|
||
startup_delay_secs?: number; // Seconds to wait for MT5 initialization (default: 10)
|
||
}
|
||
```
|
||
|
||
### Output schema
|
||
|
||
```typescript
|
||
{
|
||
success: true;
|
||
message: string; // "Rolling backtest launched with N weeks. Use get_backtest_status to poll for completion."
|
||
report_id: string; // "ROLLING_MyEA_2026.06.24_2026.07.01"
|
||
report_dir: string; // Full path to report directory
|
||
expert: string;
|
||
weeks: Array<{
|
||
label: string; // "Week 1", "Week 2", etc.
|
||
from_date: string; // "2026.06.24"
|
||
to_date: string; // "2026.06.30"
|
||
}>;
|
||
poll_hint: string; // "Call get_backtest_status with report_dir to check progress"
|
||
}
|
||
```
|
||
|
||
### Status polling
|
||
|
||
After launch, poll with `get_backtest_status(report_dir=<dir>)` to track progress. The rolling backtest runs all weeks in a background task — each week is a full backtest pipeline (clean → launch → poll → extract → analyze).
|
||
|
||
Once complete, the report directory contains:
|
||
- `rolling_results.json` — full summary with per-week metrics and totals
|
||
- `progress.log` — current week being processed
|
||
- `weeks.json` — the weekly schedule
|
||
|
||
### Example
|
||
|
||
```json
|
||
// Input
|
||
{
|
||
"expert": "MyEA",
|
||
"symbol": "XAUUSD",
|
||
"weeks": 4,
|
||
"deposit": 10000
|
||
}
|
||
|
||
// Output
|
||
{
|
||
"success": true,
|
||
"message": "Rolling backtest launched with 4 weeks. Use get_backtest_status to poll for completion.",
|
||
"report_id": "ROLLING_MyEA_2026.06.03_2026.07.01",
|
||
"report_dir": "reports/ROLLING_MyEA_2026.06.03_2026.07.01",
|
||
"expert": "MyEA",
|
||
"weeks": [
|
||
{ "label": "Jun 03 - Jun 07", "from_date": "2026.06.03", "to_date": "2026.06.07" },
|
||
{ "label": "Jun 10 - Jun 14", "from_date": "2026.06.10", "to_date": "2026.06.14" },
|
||
{ "label": "Jun 17 - Jun 21", "from_date": "2026.06.17", "to_date": "2026.06.21" },
|
||
{ "label": "Jun 24 - Jun 28", "from_date": "2026.06.24", "to_date": "2026.06.28" }
|
||
]
|
||
}
|
||
```
|
||
|
||
### Rolling results format (rolling_results.json)
|
||
|
||
```json
|
||
{
|
||
"success": true,
|
||
"weeks_run": 4,
|
||
"summary": {
|
||
"total_net_profit": 12450.50,
|
||
"max_drawdown_pct": 8.5,
|
||
"total_trades": 342
|
||
},
|
||
"weekly_results": [
|
||
{
|
||
"label": "Jun 03 - Jun 07",
|
||
"from_date": "2026.06.03",
|
||
"to_date": "2026.06.07",
|
||
"success": true,
|
||
"net_profit": 3200.00,
|
||
"max_dd_pct": 3.2,
|
||
"total_trades": 85,
|
||
"profit_factor": 1.45,
|
||
"report_dir": "reports/20260701_120000_MyEA_XAUUSD_M5"
|
||
},
|
||
{
|
||
"label": "Jun 10 - Jun 14",
|
||
"from_date": "2026.06.10",
|
||
"to_date": "2026.06.14",
|
||
"success": true,
|
||
"net_profit": -450.00,
|
||
"max_dd_pct": 8.5,
|
||
"total_trades": 92,
|
||
"profit_factor": 0.92,
|
||
"report_dir": "reports/20260701_123000_MyEA_XAUUSD_M5"
|
||
}
|
||
]
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## `get_backtest_status`
|
||
|
||
Check progress of a running backtest pipeline launched via `launch_backtest`.
|
||
|
||
**When to call:** Poll periodically after calling `launch_backtest` to check completion status.
|
||
|
||
### Input schema
|
||
|
||
```typescript
|
||
{
|
||
report_dir: string; // Report directory path from launch_backtest output
|
||
}
|
||
```
|
||
|
||
### Output schema
|
||
|
||
```typescript
|
||
{
|
||
success: true;
|
||
report_dir: string;
|
||
status: "completed" | "running" | "failed" | "in_progress" | "not_started";
|
||
stage: string; // Current pipeline stage: COMPILE, CLEAN, BACKTEST, EXTRACT, ANALYZE, DONE
|
||
is_complete: boolean; // True if backtest finished successfully
|
||
mt5_running: boolean; // Whether MT5 process is active
|
||
report_found: boolean; // Whether report file exists
|
||
metrics_extracted: boolean;
|
||
deals_extracted: boolean;
|
||
elapsed_seconds: number; // Time since launch
|
||
message: string; // Human-readable status message
|
||
job?: {
|
||
report_id: string;
|
||
expert: string;
|
||
symbol: string;
|
||
timeframe: string;
|
||
launched_at: string;
|
||
timeout_seconds: number;
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## `run_optimization`
|
||
|
||
Launch genetic parameter optimization as a detached background process.
|
||
|
||
**Important:** This tool returns immediately. MT5 runs for 2-6 hours. The AI agent must NOT poll for results — the user monitors MT5 and signals when done. Call `get_optimization_results` only after user confirmation.
|
||
|
||
**Uses Model=1 (1-min OHLC) for faster optimization.** Use a separate `run_backtest` with `model=0` to verify top optimization results — Model 1 optimization parameters may overfit grid/martingale EAs because intra-bar price movement is not simulated. The `get_optimization_status` tool now auto-parses results when optimization completes, returning top passes, best PF, and best profit.
|
||
|
||
### Input schema
|
||
|
||
```typescript
|
||
{
|
||
expert: string; // EA name
|
||
set_file: string; // Path to optimization .set file (with ||Y flags)
|
||
from: string; // "YYYY-MM-DD"
|
||
to: string; // "YYYY-MM-DD"
|
||
symbol?: string; // Default from config
|
||
deposit?: number; // Default from config
|
||
max_passes?: number; // Cap on genetic optimization passes (e.g. 5000 to run fewer)
|
||
currency?: string; // Default: "USD"
|
||
leverage?: number; // Default: 500
|
||
log_file?: string; // Where to write nohup output (default: /tmp/opt_<timestamp>.log)
|
||
}
|
||
```
|
||
|
||
### Output schema
|
||
|
||
```typescript
|
||
{
|
||
success: boolean;
|
||
job_id: string; // "opt_20250619_143022"
|
||
log_file: string; // "/tmp/opt_20250619_143022.log"
|
||
pid: number; // Process ID (for user monitoring if needed)
|
||
combinations: number; // Estimated from set_file analysis (product of all ||Y ranges)
|
||
message: string; // "Optimization launched. Signal me when MT5 completes."
|
||
}
|
||
```
|
||
|
||
### Optimization set file format
|
||
|
||
```ini
|
||
; param=current_value||start||step||stop||Y (Y = include in sweep)
|
||
; param=value||N (N = fixed, not swept)
|
||
|
||
Min_Entry_Confidence=0.610||0.580||0.010||0.650||Y ; 8 values
|
||
TP_Pips_Layer1=400||300||50||500||Y ; 5 values
|
||
Max_DD_Percent=15.0||N ; fixed
|
||
|
||
; Total combinations: 8 × 5 = 40
|
||
```
|
||
|
||
**MT5-Quant handles automatically:**
|
||
- UTF-16LE encoding with BOM
|
||
- `chmod 444` (read-only) before launch
|
||
- `OptMode=0` reset in `terminal.ini`
|
||
- `LastOptimization` line removal from `terminal.ini`
|
||
- `ExpertParameters` = filename only (not full path) in launch INI
|
||
|
||
---
|
||
|
||
## `get_optimization_results`
|
||
|
||
Parse completed optimization results. Handles both HTML (`.htm`) and SpreadsheetML XML (`.htm.xml`) formats transparently.
|
||
|
||
### Input schema
|
||
|
||
```typescript
|
||
{
|
||
job_id?: string; // From run_optimization response. If omitted, uses latest _opt/ dir.
|
||
report_dir?: string; // Explicit path to *_opt/ directory
|
||
top_n?: number; // How many top results to return (default: 20)
|
||
dd_threshold?: number; // Flag results above this DD% as high-risk (default: 20)
|
||
sort_by?: "profit" | "profit_factor" | "sharpe"; // Default: "profit"
|
||
}
|
||
```
|
||
|
||
### Output schema
|
||
|
||
```typescript
|
||
{
|
||
success: boolean;
|
||
total_passes: number;
|
||
converged: boolean; // True if passes stopped improving in last 10%
|
||
report_format: "html" | "xml";
|
||
|
||
results: Array<{
|
||
rank: number;
|
||
net_profit: number;
|
||
profit_factor: number;
|
||
max_dd_pct: number;
|
||
total_trades: number;
|
||
sharpe_ratio: number;
|
||
high_risk: boolean; // DD > dd_threshold
|
||
params: Record<string, number | boolean>; // All swept parameter values
|
||
}>;
|
||
|
||
convergence_analysis: {
|
||
top_10_agreement: Record<string, string>; // Params same across top 10 = strong signal
|
||
high_variance_params: string[]; // Params that vary in top 10 = uncertain
|
||
};
|
||
|
||
recommendation: {
|
||
best_params: Record<string, number | boolean>;
|
||
reasoning: string;
|
||
next_step: "verify_model0" | "auto_promote" | "investigate";
|
||
};
|
||
}
|
||
```
|
||
|
||
### Convergence analysis
|
||
|
||
A parameter that appears with the same value across all top-10 results is a strong optimization signal — the genetic algorithm converged on it. A parameter that varies across top-10 means the optimizer couldn't distinguish between values — either the parameter doesn't matter much, or more passes are needed.
|
||
|
||
---
|
||
|
||
## `verify_setup`
|
||
|
||
Check all required paths, Wine version, and EA/set file inventory. Run this first if `run_backtest` or `run_optimization` fails with path errors.
|
||
|
||
### Input schema
|
||
|
||
```typescript
|
||
{} // No parameters required
|
||
```
|
||
|
||
### Output schema
|
||
|
||
```typescript
|
||
{
|
||
success: boolean;
|
||
wine_path: string;
|
||
wine_version: string;
|
||
mt5_dir: string;
|
||
terminal_exe: string;
|
||
experts_dir: string;
|
||
display_mode: "gui" | "headless";
|
||
ea_count: number; // .ex5 files found in Experts/
|
||
set_count: number; // .set files found
|
||
missing: string[]; // List of paths/tools that couldn't be found
|
||
hints: string[]; // Actionable fix hints for each missing item
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## `get_backtest_status`
|
||
|
||
Check the current stage and elapsed time of a running backtest pipeline by reading its `progress.log`.
|
||
|
||
### Input schema
|
||
|
||
```typescript
|
||
{
|
||
report_dir: string; // Path to the report directory from run_backtest
|
||
}
|
||
```
|
||
|
||
### Output schema
|
||
|
||
```typescript
|
||
{
|
||
success: boolean;
|
||
report_dir: string;
|
||
stage: "COMPILE" | "CLEAN" | "BACKTEST" | "EXTRACT" | "ANALYZE" | "DONE";
|
||
elapsed_seconds: number;
|
||
finished: boolean;
|
||
log_lines: string[]; // Last 5 lines of progress.log
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## `get_optimization_status`
|
||
|
||
Check the live state of a background optimization job (started by `run_optimization`).
|
||
|
||
### Input schema
|
||
|
||
```typescript
|
||
{
|
||
job_id: string; // From run_optimization response
|
||
}
|
||
```
|
||
|
||
### Output schema
|
||
|
||
```typescript
|
||
{
|
||
success: boolean;
|
||
status: "running" | "stopped" | "completed";
|
||
job_id: string;
|
||
pid: number;
|
||
expert?: string;
|
||
symbol?: string;
|
||
from_date?: string;
|
||
to_date?: string;
|
||
started_at?: string;
|
||
// Present when status is "completed":
|
||
total_passes?: number;
|
||
top_10?: Array<{ pass: number; profit: number; profit_factor: number; drawdown_pct: number; }>;
|
||
best_pf?: { /* best pass by profit factor */ };
|
||
best_profit?: { /* best pass by profit */ };
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## `prune_reports`
|
||
|
||
Delete old report directories to reclaim disk space, keeping the most recent N runs. Optimization result directories (`*_opt/`) are always preserved.
|
||
|
||
### Input schema
|
||
|
||
```typescript
|
||
{
|
||
keep_last?: number; // How many recent reports to keep (default from config, usually 10)
|
||
dry_run?: boolean; // If true, list what would be deleted without deleting (default: false)
|
||
}
|
||
```
|
||
|
||
### Output schema
|
||
|
||
```typescript
|
||
{
|
||
success: boolean;
|
||
deleted: string[]; // Paths that were (or would be) deleted
|
||
kept: string[]; // Paths that were kept
|
||
freed_mb: number; // Approximate disk space freed
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## `analyze_report`
|
||
|
||
Read and summarize a completed backtest report without re-running MT5. Loads deals from the SQLite database.
|
||
|
||
### Input schema
|
||
|
||
```typescript
|
||
{
|
||
report_id?: string; // Preferred: report ID from list_reports
|
||
report_dir?: string; // Legacy: path to report directory (looks up DB entry)
|
||
// Omit both to use the latest report automatically
|
||
strategy?: "grid" | "scalper" | "trend" | "hedge" | "generic";
|
||
// Strategy profile that was used (default: "grid").
|
||
// Only affects interpretation of analysis.json fields —
|
||
// does not re-run analysis.
|
||
include_deals?: boolean; // Include top 20 deals in output (default: false)
|
||
include_monthly?: boolean; // Include full monthly P/L table (default: true)
|
||
include_dd_events?: boolean; // Include DD event reconstruction (default: true)
|
||
deep?: boolean; // Include hourly_pnl and volume_profile (default: false)
|
||
}
|
||
```
|
||
|
||
### Output schema
|
||
|
||
```typescript
|
||
{
|
||
success: boolean;
|
||
report_dir: string;
|
||
strategy: string; // Active profile: "grid" | "scalper" | "trend" | "hedge" | "generic"
|
||
|
||
metrics: { /* same as run_backtest metrics */ };
|
||
|
||
// ── Always present (strategy-agnostic) ─────────────────────────────────────
|
||
|
||
monthly_pnl: Array<{
|
||
month: string; // "2025-01"
|
||
pnl: number;
|
||
trades: number;
|
||
green: boolean;
|
||
}>;
|
||
|
||
dd_events: Array<{
|
||
peak_dd_pct: number;
|
||
start_date: string;
|
||
end_date: string;
|
||
duration_days: number;
|
||
recovery_date: string | null;
|
||
recovery_days: number | null;
|
||
cause: string; // Profile-driven: e.g. "locking_cascade" (grid) or "whipsaw" (trend)
|
||
// Falls back to "unknown" when no keyword matched
|
||
}>;
|
||
|
||
top_losses: Array<{
|
||
date: string;
|
||
loss_usd: number;
|
||
grid_depth_at_close: number; // 0 for non-grid strategies
|
||
volume: number;
|
||
comment: string;
|
||
}>;
|
||
|
||
loss_sequences: Array<{
|
||
length: number;
|
||
total_loss: number;
|
||
start: string;
|
||
end: string;
|
||
}>;
|
||
|
||
position_pairs: Array<{
|
||
time: string;
|
||
type: "buy" | "sell";
|
||
profit: number;
|
||
volume: number;
|
||
layer: number;
|
||
hold_minutes: number | null;
|
||
comment: string;
|
||
magic: string;
|
||
order: string;
|
||
}>;
|
||
|
||
// ── Strategy-driven (content varies by profile) ────────────────────────────
|
||
|
||
depth_histogram: Record<string, number>;
|
||
// grid: { L1: n, L2: n, …, "L8+": n }
|
||
// others: {} (empty — no depth_re in profile)
|
||
|
||
grid_depth_histogram: Record<string, number>;
|
||
// Backward-compat alias for depth_histogram (grid only)
|
||
|
||
cycle_stats: {
|
||
total_cycles: number;
|
||
win_rate: number; // percent
|
||
avg_profit: number;
|
||
win_rate_by_depth: Record<string, { total: number; win_rate: number }>;
|
||
// win_rate_by_depth populated for grid; keys = "L?" for non-depth profiles
|
||
};
|
||
|
||
exit_reason_breakdown: Record<
|
||
string, // Keys depend on strategy profile exit_keywords
|
||
// grid: "locking" | "cutloss" | "zombie" | "timeout" | "tp" | "sl"
|
||
// scalper: "manual" | "trailing" | "tp" | "sl"
|
||
// trend: "breakeven" | "trailing" | "partial" | "tp" | "sl"
|
||
// generic: "tp" | "sl"
|
||
{ count: number; total_pnl: number; avg_pnl: number }
|
||
>;
|
||
|
||
direction_bias: {
|
||
buy?: { trades: number; win_rate: number; total_pnl: number; avg_pnl: number };
|
||
sell?: { trades: number; win_rate: number; total_pnl: number; avg_pnl: number };
|
||
};
|
||
|
||
streak_analysis: {
|
||
max_win_streak: number;
|
||
max_win_start: string;
|
||
max_win_end: string;
|
||
max_loss_streak: number;
|
||
max_loss_start: string;
|
||
max_loss_end: string;
|
||
current_streak: number;
|
||
current_streak_type: "win" | "loss";
|
||
};
|
||
|
||
session_breakdown: Record<
|
||
"asian" | "london" | "london_ny_overlap" | "new_york" | "off_hours",
|
||
{ trades: number; win_rate: number; total_pnl: number }
|
||
>;
|
||
|
||
weekday_pnl: Array<{
|
||
day: string; // "Monday" … "Sunday"
|
||
pnl: number;
|
||
trades: number;
|
||
win_rate: number;
|
||
}>;
|
||
|
||
concurrent_peak: {
|
||
peak_open: number;
|
||
peak_time: string;
|
||
};
|
||
|
||
// ── Deep mode only (deep=true) ──────────────────────────────────────────────
|
||
|
||
hourly_pnl?: Array<{
|
||
hour: number; // 0–23
|
||
pnl: number;
|
||
trades: number;
|
||
win_rate: number;
|
||
}>;
|
||
|
||
volume_profile?: Array<{
|
||
lot_tier: string; // "0.01" | "0.02-0.04" | "0.05-0.09" | "0.10-0.49" | …
|
||
pnl: number;
|
||
trades: number;
|
||
win_rate: number;
|
||
}>;
|
||
|
||
// ── Optional raw deals ──────────────────────────────────────────────────────
|
||
|
||
deals?: Array<{ /* all 13 deal columns */ }>; // Only if include_deals=true
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## `compare_baseline`
|
||
|
||
Compare a report against a baseline and return a structured verdict.
|
||
|
||
### Input schema
|
||
|
||
```typescript
|
||
{
|
||
report_dir: string; // Report to evaluate
|
||
baseline: {
|
||
net_profit: number;
|
||
max_dd_pct: number;
|
||
total_trades?: number;
|
||
label?: string; // e.g. "v1.2 production"
|
||
};
|
||
promote_threshold?: {
|
||
profit_gt: number; // Auto-promote if profit > this (default: baseline profit)
|
||
dd_lt: number; // AND DD < this (default: 20)
|
||
};
|
||
}
|
||
```
|
||
|
||
### Output schema
|
||
|
||
```typescript
|
||
{
|
||
verdict: "winner" | "loser" | "marginal";
|
||
auto_promote: boolean;
|
||
|
||
delta: {
|
||
profit_usd: number; // positive = improvement
|
||
profit_pct: number; // relative to baseline
|
||
dd_pp: number; // positive = DD got worse
|
||
trades_delta: number;
|
||
};
|
||
|
||
summary: string; // Human-readable one-liner
|
||
|
||
details: {
|
||
candidate: { net_profit: number; max_dd_pct: number; total_trades: number; };
|
||
baseline: { net_profit: number; max_dd_pct: number; label: string; };
|
||
};
|
||
}
|
||
```
|
||
|
||
### Example
|
||
|
||
```json
|
||
// Input
|
||
{
|
||
"report_dir": "reports/20250619_143022_MyEA_v1.3_XAUUSD_M5",
|
||
"baseline": {
|
||
"net_profit": 8660,
|
||
"max_dd_pct": 15.66,
|
||
"label": "v1.2 production"
|
||
}
|
||
}
|
||
|
||
// Output
|
||
{
|
||
"verdict": "winner",
|
||
"auto_promote": true,
|
||
"delta": {
|
||
"profit_usd": 3186.32,
|
||
"profit_pct": 36.8,
|
||
"dd_pp": -7.27,
|
||
"trades_delta": -3
|
||
},
|
||
"summary": "+$3,186 (+37%) profit vs v1.2. DD dropped from 15.66% to 8.39%. Auto-promoting.",
|
||
"details": {
|
||
"candidate": { "net_profit": 11846.32, "max_dd_pct": 8.39, "total_trades": 1963 },
|
||
"baseline": { "net_profit": 8660.00, "max_dd_pct": 15.66, "label": "v1.2 production" }
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## `compile_ea`
|
||
|
||
Compile an MQL5 Expert Advisor via MetaEditor (Wine/CrossOver).
|
||
|
||
### Input schema
|
||
|
||
```typescript
|
||
{
|
||
expert_path: string; // e.g. "src/MyEA_v1.2.mq5"
|
||
include_dirs?: string[]; // Additional include search paths
|
||
}
|
||
```
|
||
|
||
### Output schema
|
||
|
||
```typescript
|
||
{
|
||
success: boolean;
|
||
binary_path: string; // Path where .ex5 was written
|
||
binary_size_bytes: number;
|
||
warnings: number;
|
||
errors: number;
|
||
error_list: Array<{
|
||
file: string;
|
||
line: number;
|
||
message: string;
|
||
}>;
|
||
compile_time_ms: number;
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## Error Handling
|
||
|
||
All tools return `success: false` with an `error` field on failure. Pipeline failures are non-fatal by default — the tool returns partial results if any stages completed.
|
||
|
||
```typescript
|
||
{
|
||
success: false,
|
||
error: "COMPILE_FAILED",
|
||
error_detail: "2 errors in src/MyEA_v1.2.mq5: line 847: undeclared identifier 'Max_New_Param'",
|
||
completed_stages: ["COMPILE"],
|
||
failed_stage: "COMPILE"
|
||
}
|
||
```
|
||
|
||
**Error codes:**
|
||
|
||
| Code | Stage | Cause |
|
||
|------|-------|-------|
|
||
| `COMPILE_FAILED` | COMPILE | MQL5 syntax errors |
|
||
| `WINE_NOT_FOUND` | Any | Wine/CrossOver not installed or wrong path |
|
||
| `MT5_TIMEOUT` | BACKTEST | MT5 didn't exit within timeout (default: 15min) |
|
||
| `REPORT_NOT_FOUND` | EXTRACT | MT5 produced no report (usually parameter error) |
|
||
| `EXTRACT_FAILED` | EXTRACT | Report parse error (format change?) |
|
||
| `NO_DEALS` | ANALYZE | Report has 0 trades (check date range, symbol) |
|
||
| `OPT_NOT_FINISHED` | get_opt_results | Optimization still running |
|
||
|
||
---
|
||
|
||
## `list_reports`
|
||
|
||
List all backtest report directories with compact key metrics. Use this to survey what runs exist before deciding which to analyze — much cheaper than calling `analyze_report` repeatedly.
|
||
|
||
### Input schema
|
||
|
||
```typescript
|
||
{
|
||
include_opt?: boolean; // Include _opt dirs (default: false)
|
||
limit?: number; // Max reports, newest first (default: 30)
|
||
}
|
||
```
|
||
|
||
### Output schema
|
||
|
||
```typescript
|
||
{
|
||
success: boolean;
|
||
count: number;
|
||
reports: Array<{
|
||
name: string; // "20250619_143022_MyEA_XAUUSD_M5"
|
||
is_opt: boolean;
|
||
net_profit?: number;
|
||
max_dd_pct?: number;
|
||
total_trades?: number;
|
||
symbol?: string;
|
||
timeframe?: string;
|
||
from_date?: string;
|
||
to_date?: string;
|
||
metrics?: "missing"; // Present only if metrics.json is absent
|
||
}>;
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## `tail_log`
|
||
|
||
Read the last N lines of a log file. Supports `filter=errors` to return only lines containing error/fail keywords — avoids streaming full logs into context.
|
||
|
||
### Input schema
|
||
|
||
```typescript
|
||
{
|
||
// Provide one of: report_dir, job_id, or log_file
|
||
report_dir?: string; // Reads progress.log from this dir (omit for latest)
|
||
job_id?: string; // Reads the nohup log for this optimization job
|
||
log_file?: string; // Absolute path to any log file
|
||
|
||
n?: number; // Lines to return (default: 50)
|
||
filter?: "all" | "errors" | "warnings"; // Default: "all"
|
||
}
|
||
```
|
||
|
||
### Output schema
|
||
|
||
```typescript
|
||
{
|
||
success: boolean;
|
||
log_file: string; // Resolved path of the file that was read
|
||
total_lines: number; // Lines matched after filter applied
|
||
lines: string[]; // Last n of the matched lines
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## `cache_status`
|
||
|
||
Show the MT5 tester cache directory size broken down by symbol. Use before `clean_cache` to see what's there.
|
||
|
||
### Input schema
|
||
|
||
```typescript
|
||
{} // No parameters
|
||
```
|
||
|
||
### Output schema
|
||
|
||
```typescript
|
||
{
|
||
success: boolean;
|
||
cache_dir: string;
|
||
total_size_mb: number;
|
||
symbols: Array<{
|
||
symbol: string; // Subdirectory name (broker symbol)
|
||
size_mb: number;
|
||
}>;
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## `clean_cache`
|
||
|
||
Delete MT5 tester cache files. Forces MT5 to regenerate tick data on the next backtest (slower first run after clean). Supports dry-run preview and per-symbol targeting.
|
||
|
||
### Input schema
|
||
|
||
```typescript
|
||
{
|
||
symbol?: string; // Delete only this symbol's cache. Omit to delete all.
|
||
dry_run?: boolean; // Report what would be deleted without deleting (default: false)
|
||
}
|
||
```
|
||
|
||
### Output schema
|
||
|
||
```typescript
|
||
{
|
||
success: boolean;
|
||
dry_run: boolean;
|
||
deleted_symbols: string[];
|
||
freed_mb: number;
|
||
hint: string; // Reminder that next backtest will be slower
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## `read_set_file`
|
||
|
||
Parse an MT5 `.set` parameter file (UTF-16LE or UTF-8) into structured JSON. Handles BOM detection automatically. Use this instead of reading raw `.set` files.
|
||
|
||
### Input schema
|
||
|
||
```typescript
|
||
{
|
||
path: string; // Path to .set file
|
||
}
|
||
```
|
||
|
||
### Output schema
|
||
|
||
```typescript
|
||
{
|
||
success: boolean;
|
||
path: string;
|
||
param_count: number;
|
||
comments: string[]; // Header comment lines (stripped of semicolons)
|
||
params: Record<string, {
|
||
value: string; // Current / default value
|
||
from?: string; // Sweep start (present for optimization params)
|
||
to?: string; // Sweep end
|
||
step?: string; // Sweep step
|
||
optimize?: boolean; // True if ||Y flag is set
|
||
}>;
|
||
}
|
||
```
|
||
|
||
### Example
|
||
|
||
```json
|
||
// Input
|
||
{ "path": "config/MyEA_opt.set" }
|
||
|
||
// Output
|
||
{
|
||
"success": true,
|
||
"path": "config/MyEA_opt.set",
|
||
"param_count": 5,
|
||
"comments": ["MyEA optimization set — XAUUSD M5"],
|
||
"params": {
|
||
"Min_Entry_Confidence": { "value": "0.610", "from": "0.580", "to": "0.650", "step": "0.010", "optimize": true },
|
||
"TP_Pips": { "value": "400", "from": "300", "to": "500", "step": "50", "optimize": true },
|
||
"Max_DD_Percent": { "value": "15.0" }
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## `write_set_file`
|
||
|
||
Write an MT5 `.set` parameter file with correct UTF-16LE encoding and `chmod 444`. Overwrites any existing file at the path.
|
||
|
||
### Input schema
|
||
|
||
```typescript
|
||
{
|
||
path: string; // Output path for .set file
|
||
|
||
params: Record<string,
|
||
| string | number // Simple fixed value
|
||
| {
|
||
value: string | number;
|
||
from?: string | number; // Include for optimization sweep
|
||
to?: string | number;
|
||
step?: string | number;
|
||
optimize?: boolean; // true → ||Y, false → ||N (default: false)
|
||
}
|
||
>;
|
||
}
|
||
```
|
||
|
||
### Output schema
|
||
|
||
```typescript
|
||
{
|
||
success: boolean;
|
||
path: string;
|
||
param_count: number;
|
||
encoding: "utf-16-le";
|
||
permissions: string; // "444 (read-only, required by MT5)"
|
||
}
|
||
```
|
||
|
||
### Example
|
||
|
||
```json
|
||
// Input
|
||
{
|
||
"path": "config/MyEA_opt.set",
|
||
"params": {
|
||
"Min_Entry_Confidence": { "value": 0.61, "from": 0.58, "to": 0.65, "step": 0.01, "optimize": true },
|
||
"TP_Pips": { "value": 400, "from": 300, "to": 500, "step": 50, "optimize": true },
|
||
"Max_DD_Percent": 15.0
|
||
}
|
||
}
|
||
|
||
// Output
|
||
{
|
||
"success": true,
|
||
"path": "config/MyEA_opt.set",
|
||
"param_count": 3,
|
||
"encoding": "utf-16-le",
|
||
"permissions": "444 (read-only, required by MT5)"
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## `list_jobs`
|
||
|
||
List all optimization jobs tracked in `.mt5mcp_jobs/` with compact status. Cheaper than calling `get_optimization_status` per job.
|
||
|
||
### Input schema
|
||
|
||
```typescript
|
||
{
|
||
include_done?: boolean; // Include completed/failed jobs (default: true)
|
||
}
|
||
```
|
||
|
||
### Output schema
|
||
|
||
```typescript
|
||
{
|
||
success: boolean;
|
||
count: number;
|
||
jobs: Array<{
|
||
job_id: string; // "opt_20250619_143022"
|
||
status: "running" | "done" | "failed";
|
||
elapsed_seconds: number | null;
|
||
expert: string;
|
||
started_at: string; // ISO timestamp
|
||
log_file: string;
|
||
}>;
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## `patch_set_file`
|
||
|
||
Modify specific parameters in an existing `.set` file in-place. Preserves all other params, comments, and sweep config untouched. Returns a diff of what changed. **Use instead of `read_set_file` → edit → `write_set_file`** — saves two round-trips.
|
||
|
||
### Input schema
|
||
|
||
```typescript
|
||
{
|
||
path: string; // .set file to modify (must exist)
|
||
patches: Record<string,
|
||
| string | number // scalar → only updates value, keeps existing sweep config
|
||
| {
|
||
value?: string | number;
|
||
from?: string | number;
|
||
to?: string | number;
|
||
step?: string | number;
|
||
optimize?: boolean;
|
||
}
|
||
>;
|
||
}
|
||
```
|
||
|
||
### Output schema
|
||
|
||
```typescript
|
||
{
|
||
success: boolean;
|
||
path: string;
|
||
changed_count: number;
|
||
param_count: number;
|
||
changed: Array<{ name: string; old: string; new: string; }>;
|
||
}
|
||
```
|
||
|
||
### Example
|
||
|
||
```json
|
||
// Input — change two params without touching the rest of the file
|
||
{
|
||
"path": "config/MyEA_opt.set",
|
||
"patches": {
|
||
"TP_Pips": 350,
|
||
"Min_Entry_Confidence": { "value": 0.62, "from": 0.60, "to": 0.65, "optimize": true }
|
||
}
|
||
}
|
||
|
||
// Output
|
||
{
|
||
"success": true,
|
||
"path": "config/MyEA_opt.set",
|
||
"changed_count": 2,
|
||
"param_count": 12,
|
||
"changed": [
|
||
{ "name": "TP_Pips", "old": "400", "new": "350" },
|
||
{ "name": "Min_Entry_Confidence", "old": "0.610", "new": "0.62" }
|
||
]
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## `clone_set_file`
|
||
|
||
Copy a `.set` file to a new path, applying optional param overrides. One call instead of read → modify → write. Preserves header comments.
|
||
|
||
### Input schema
|
||
|
||
```typescript
|
||
{
|
||
source: string; // Source .set file
|
||
destination: string; // Output path (created if needed)
|
||
overrides?: Record<string, string | number | { value; from?; to?; step?; optimize? }>;
|
||
}
|
||
```
|
||
|
||
### Output schema
|
||
|
||
```typescript
|
||
{
|
||
success: boolean;
|
||
source: string;
|
||
destination: string;
|
||
param_count: number;
|
||
overridden_count: number;
|
||
overridden: Array<{ name: string; old: string | null; new: string; }>;
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## `set_from_optimization`
|
||
|
||
Generate a clean backtest `.set` file directly from an optimization result's params dict. Strips all sweep flags (`||Y`) so the file is ready for `run_backtest`. Optionally fills params not in the optimization result from a template `.set`, and optionally re-adds sweep ranges to selected params for a narrowed follow-on optimization.
|
||
|
||
**Typical call**: immediately after `get_optimization_results`, use `results[0].params` as the `params` argument.
|
||
|
||
### Input schema
|
||
|
||
```typescript
|
||
{
|
||
path: string; // Output .set file path
|
||
|
||
params: Record<string, string | number>;
|
||
// Flat param→value dict from optimization result.
|
||
// e.g. { "TP_Pips": 400, "Min_Confidence": 0.61 }
|
||
|
||
template?: string; // Path to existing .set. Params NOT in 'params' are
|
||
// copied from here as fixed values.
|
||
|
||
sweep?: Record<string, { from: number; to: number; step: number; optimize?: boolean }>;
|
||
// Re-add sweep ranges to specific params after applying opt values.
|
||
// Used to create a narrowed follow-on optimization .set.
|
||
}
|
||
```
|
||
|
||
### Output schema
|
||
|
||
```typescript
|
||
{
|
||
success: boolean;
|
||
path: string;
|
||
param_count: number;
|
||
from_template: boolean;
|
||
opt_params_applied: number;
|
||
swept_params: number; // > 0 if sweep was provided
|
||
total_combinations: number; // 0 for pure backtest .set
|
||
}
|
||
```
|
||
|
||
### Example
|
||
|
||
```json
|
||
// After get_optimization_results returned:
|
||
// results[0].params = { "TP_Pips": 400, "Min_Entry_Confidence": 0.62, "Max_DD_Percent": 15.0 }
|
||
|
||
{
|
||
"path": "config/MyEA_v1.3.set",
|
||
"params": { "TP_Pips": 400, "Min_Entry_Confidence": 0.62, "Max_DD_Percent": 15.0 },
|
||
"template": "config/MyEA_base.set"
|
||
}
|
||
|
||
// Output
|
||
{
|
||
"success": true,
|
||
"path": "config/MyEA_v1.3.set",
|
||
"param_count": 12,
|
||
"from_template": true,
|
||
"opt_params_applied": 3,
|
||
"swept_params": 0,
|
||
"total_combinations": 0
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## `diff_set_files`
|
||
|
||
Compare two `.set` files and return only the differences. Use instead of reading both files and comparing manually.
|
||
|
||
### Input schema
|
||
|
||
```typescript
|
||
{
|
||
path_a: string; // Baseline / old file
|
||
path_b: string; // Candidate / new file
|
||
}
|
||
```
|
||
|
||
### Output schema
|
||
|
||
```typescript
|
||
{
|
||
success: boolean;
|
||
path_a: string;
|
||
path_b: string;
|
||
identical: boolean;
|
||
added_count: number; // Params in b but not a
|
||
removed_count: number; // Params in a but not b
|
||
changed_count: number; // Params in both but with different value or sweep flag
|
||
|
||
added: Array<{ name: string; value: string; }>;
|
||
removed: Array<{ name: string; value: string; }>;
|
||
changed: Array<{
|
||
name: string;
|
||
a: string; // value in path_a
|
||
b: string; // value in path_b
|
||
sweep_a?: boolean; // Present only if sweep flag differs
|
||
sweep_b?: boolean;
|
||
}>;
|
||
}
|
||
```
|
||
|
||
### Example
|
||
|
||
```json
|
||
{
|
||
"path_a": "config/MyEA_v1.2.set",
|
||
"path_b": "config/MyEA_v1.3.set"
|
||
}
|
||
|
||
// Output
|
||
{
|
||
"success": true,
|
||
"identical": false,
|
||
"added_count": 1,
|
||
"removed_count": 0,
|
||
"changed_count": 2,
|
||
"added": [{ "name": "Trailing_Activation", "value": "50" }],
|
||
"removed": [],
|
||
"changed": [
|
||
{ "name": "TP_Pips", "a": "400", "b": "350" },
|
||
{ "name": "Min_Entry_Confidence", "a": "0.610", "b": "0.620", "sweep_a": true, "sweep_b": false }
|
||
]
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## `describe_sweep`
|
||
|
||
Show a `.set` file's sweep configuration: which params are swept, their ranges, per-param value counts, and total combinations. Use before `run_optimization` to verify scope.
|
||
|
||
### Input schema
|
||
|
||
```typescript
|
||
{
|
||
path: string;
|
||
}
|
||
```
|
||
|
||
### Output schema
|
||
|
||
```typescript
|
||
{
|
||
success: boolean;
|
||
path: string;
|
||
total_params: number;
|
||
swept_count: number;
|
||
fixed_count: number;
|
||
total_combinations: number;
|
||
swept_params: Array<{
|
||
name: string;
|
||
from: string;
|
||
to: string;
|
||
step: string;
|
||
count: number; // Number of distinct values in this param's range
|
||
}>;
|
||
hint: string; // e.g. "240 combinations. Typical range: 1–8h depending on EA tick speed."
|
||
}
|
||
```
|
||
|
||
### Example
|
||
|
||
```json
|
||
// Input
|
||
{ "path": "config/MyEA_opt.set" }
|
||
|
||
// Output
|
||
{
|
||
"success": true,
|
||
"total_params": 12,
|
||
"swept_count": 3,
|
||
"fixed_count": 9,
|
||
"total_combinations": 240,
|
||
"swept_params": [
|
||
{ "name": "TP_Pips", "from": "300", "to": "500", "step": "50", "count": 5 },
|
||
{ "name": "Min_Entry_Confidence", "from": "0.58","to": "0.65","step": "0.01", "count": 8 },
|
||
{ "name": "Max_DD_Percent", "from": "12", "to": "20", "step": "2", "count": 5 }
|
||
],
|
||
"hint": "240 combinations. Typical range: 1–8h depending on EA tick speed."
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## `list_set_files`
|
||
|
||
List all `.set` files in the MT5 tester profiles directory with param counts, swept param counts, and total combinations per file. Use to find the right `.set` without reading each one.
|
||
|
||
### Input schema
|
||
|
||
```typescript
|
||
{
|
||
ea?: string; // Filter by EA name substring (case-insensitive)
|
||
}
|
||
```
|
||
|
||
### Output schema
|
||
|
||
```typescript
|
||
{
|
||
success: boolean;
|
||
profiles_dir: string;
|
||
count: number;
|
||
files: Array<{
|
||
name: string; // filename only
|
||
param_count: number;
|
||
swept_count: number;
|
||
total_combinations: number; // 0 for backtest-only .set files
|
||
modified: string; // "YYYY-MM-DD HH:MM"
|
||
error?: string; // Present only if file is unreadable
|
||
}>;
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## `get_active_account`
|
||
|
||
Get current MT5 account session information: login, server, and available symbols. This is essential for pre-flight checks to ensure symbol availability before backtesting.
|
||
|
||
### Input schema
|
||
|
||
```typescript
|
||
{} // No parameters
|
||
```
|
||
|
||
### Output schema
|
||
|
||
```typescript
|
||
{
|
||
success: boolean;
|
||
ready_for_backtest: boolean; // true if account exists and symbols available
|
||
account: {
|
||
login: string;
|
||
server: string;
|
||
} | null;
|
||
server: string; // Active server name
|
||
available_servers: string[]; // All servers with history data
|
||
symbols: string[]; // Symbols available for active server
|
||
symbol_count: number;
|
||
hint: string; // "Ready for backtesting" or instructions
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## `check_symbol_data_status`
|
||
|
||
Validate if a symbol has sufficient historical tick data for a specified date range before running backtest. Prevents failed backtests due to missing history data.
|
||
|
||
### Input schema
|
||
|
||
```typescript
|
||
{
|
||
symbol: string; // e.g., "XAUUSDc"
|
||
from_date: string; // "YYYY.MM.DD"
|
||
to_date: string; // "YYYY.MM.DD"
|
||
}
|
||
```
|
||
|
||
### Output schema
|
||
|
||
```typescript
|
||
{
|
||
success: boolean;
|
||
symbol: string;
|
||
server: string;
|
||
has_sufficient_data: boolean;
|
||
requested_range: { from: string; to: string };
|
||
data_range: string; // "YYYY.MM.DD - YYYY.MM.DD" or "unknown"
|
||
years_available: number; // Count of years with data
|
||
hcc_files_count: number; // Number of history cache files
|
||
warnings: string[] | null; // Data range issues
|
||
suggestion: string; // Action recommendation
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## `check_mt5_status`
|
||
|
||
Check if MT5 terminal is properly installed and configured. Returns comprehensive status of all required components.
|
||
|
||
### Input schema
|
||
|
||
```typescript
|
||
{} // No parameters
|
||
```
|
||
|
||
### Output schema
|
||
|
||
```typescript
|
||
{
|
||
success: boolean;
|
||
terminal_ready: boolean; // true if all components present
|
||
checks: {
|
||
mt5_dir_exists: boolean;
|
||
terminal64_exe: boolean;
|
||
metaeditor64_exe: boolean;
|
||
metatester64_exe: boolean;
|
||
wine_executable: boolean;
|
||
wine_path: string | null;
|
||
};
|
||
mt5_version: string | null;
|
||
current_account: {
|
||
login: string;
|
||
server: string;
|
||
} | null;
|
||
hint: string;
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## `get_backtest_history`
|
||
|
||
List all backtests previously run for a specific EA and/or symbol with summary metrics. Use for tracking performance over time.
|
||
|
||
### Input schema
|
||
|
||
```typescript
|
||
{
|
||
expert?: string; // Filter by EA name
|
||
symbol?: string; // Filter by symbol
|
||
limit?: number; // Max results (default: 10)
|
||
}
|
||
```
|
||
|
||
### Output schema
|
||
|
||
```typescript
|
||
{
|
||
success: boolean;
|
||
count: number;
|
||
total: number;
|
||
filters: {
|
||
expert: string | null;
|
||
symbol: string | null;
|
||
};
|
||
history: Array<{
|
||
report_dir: string;
|
||
date: string | null;
|
||
expert: string | null;
|
||
symbol: string | null;
|
||
period: string | null;
|
||
profit: number | null;
|
||
profit_factor: number | null;
|
||
expected_payoff: number | null;
|
||
drawdown_pct: number | null;
|
||
total_trades: number | null;
|
||
win_rate: number | null;
|
||
}>;
|
||
hint: string;
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## `compare_backtests`
|
||
|
||
Compare two or more backtest results side-by-side with key metrics analysis. Includes profit/drawdown differences and verdict on which performed better.
|
||
|
||
### Input schema
|
||
|
||
```typescript
|
||
{
|
||
report_dirs: string[]; // List of report directory paths to compare
|
||
}
|
||
```
|
||
|
||
### Output schema
|
||
|
||
```typescript
|
||
{
|
||
success: boolean;
|
||
count: number;
|
||
comparisons: Array<{
|
||
report_dir: string;
|
||
expert: string | null;
|
||
symbol: string | null;
|
||
net_profit: number | null;
|
||
profit_factor: number | null;
|
||
drawdown_pct: number | null;
|
||
total_trades: number | null;
|
||
win_rate: number | null;
|
||
expected_payoff: number | null;
|
||
recovery_factor: number | null;
|
||
sharpe_ratio: number | null;
|
||
}>;
|
||
analysis: Array<{
|
||
compare_to: string | null;
|
||
report: string | null;
|
||
profit_diff: number;
|
||
profit_pct_change: number;
|
||
drawdown_diff: number;
|
||
profit_factor_diff: number;
|
||
verdict: "better" | "worse" | "mixed";
|
||
}> | null;
|
||
verdict: string | null; // "Best: <report_dir>"
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## `init_project`
|
||
|
||
Create a new MQL5 project with standard directory structure and template files. Supports scalper, swing, grid, and basic templates.
|
||
|
||
### Input schema
|
||
|
||
```typescript
|
||
{
|
||
name: string; // Project name (used for EA filename)
|
||
template?: "scalper" | "swing" | "grid" | "basic"; // Default: "basic"
|
||
}
|
||
```
|
||
|
||
### Output schema
|
||
|
||
```typescript
|
||
{
|
||
success: boolean;
|
||
project_name: string;
|
||
template: string;
|
||
created_files: string[]; // Paths to created files
|
||
hint: string;
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## `validate_ea_syntax`
|
||
|
||
Perform pre-compile syntax check on MQL5 source file without running full compilation. Detects common issues before expensive MetaEditor compilation.
|
||
|
||
### Input schema
|
||
|
||
```typescript
|
||
{
|
||
path: string; // Path to .mq5 source file
|
||
}
|
||
```
|
||
|
||
### Output schema
|
||
|
||
```typescript
|
||
{
|
||
success: boolean;
|
||
valid: boolean;
|
||
path: string;
|
||
checks: {
|
||
has_on_init: boolean;
|
||
has_on_tick: boolean;
|
||
has_on_deinit: boolean;
|
||
lines: number;
|
||
};
|
||
errors: Array<{
|
||
line: number;
|
||
message: string;
|
||
severity: "error";
|
||
}> | null;
|
||
warnings: Array<{
|
||
line: number;
|
||
message: string;
|
||
severity: "warning";
|
||
}> | null;
|
||
hint: string;
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## `create_set_template`
|
||
|
||
Generate a .set parameter file template based on an EA's input variables. Automatically parses input declarations from source code.
|
||
|
||
### Input schema
|
||
|
||
```typescript
|
||
{
|
||
ea: string; // EA name or path to .mq5/.ex5 file
|
||
output_path?: string; // Optional custom output path
|
||
}
|
||
```
|
||
|
||
### Output schema
|
||
|
||
```typescript
|
||
{
|
||
success: boolean;
|
||
ea: string;
|
||
inputs_found: number;
|
||
inputs: Array<{
|
||
name: string;
|
||
type: string;
|
||
default: string;
|
||
description: string | null;
|
||
}>;
|
||
set_file: string; // Path to generated file
|
||
hint: string;
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## `export_report`
|
||
|
||
Export backtest report to various formats (CSV, JSON, Markdown) for external analysis or sharing.
|
||
|
||
### Input schema
|
||
|
||
```typescript
|
||
{
|
||
report_dir: string; // Path to backtest report directory
|
||
format?: "csv" | "json" | "md"; // Default: "csv"
|
||
output_path?: string; // Optional custom output file path
|
||
}
|
||
```
|
||
|
||
### Output schema
|
||
|
||
```typescript
|
||
{
|
||
success: boolean;
|
||
format: string;
|
||
output_file: string;
|
||
source: string;
|
||
hint: string;
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## `archive_report`
|
||
|
||
Convert a backtest report directory into a compact JSON entry appended to `config/backtest_history.json`. Idempotent — re-archiving the same report is a no-op. Optionally deletes the source directory to reclaim disk space.
|
||
|
||
### Input schema
|
||
|
||
```typescript
|
||
{
|
||
report_dir?: string; // Directory to archive. Omit for latest.
|
||
delete_after?: boolean; // Delete source dir after archiving (default: false)
|
||
verdict?: "winner" | "loser" | "marginal" | "reference";
|
||
notes?: string; // Free-text notes for the entry
|
||
tags?: string[]; // Tags e.g. ["tight-sl", "new-filter"]
|
||
}
|
||
```
|
||
|
||
### Output schema
|
||
|
||
```typescript
|
||
{
|
||
success: boolean;
|
||
id: string; // Report dir basename used as history entry id
|
||
already_existed: boolean;
|
||
deleted_source: boolean;
|
||
history_file: string; // Absolute path to backtest_history.json
|
||
entry_summary: {
|
||
ea: string;
|
||
symbol: string;
|
||
metrics: { net_profit: number; profit_factor: number; max_dd_pct: number; sharpe_ratio: number; total_trades: number; };
|
||
verdict: string | null;
|
||
};
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## `archive_all_reports`
|
||
|
||
Bulk-archive all backtest report directories into `config/backtest_history.json`. Entries already in history are skipped. Use `delete_after=true` to reclaim disk space while preserving all results as JSON. Optimization dirs (`_opt` suffix) are never deleted.
|
||
|
||
### Input schema
|
||
|
||
```typescript
|
||
{
|
||
delete_after?: boolean; // Delete source dirs after archiving (default: false)
|
||
keep_last?: number; // Protect newest N dirs from deletion even with delete_after=true (default: 5)
|
||
dry_run?: boolean; // Preview without making changes (default: false)
|
||
}
|
||
```
|
||
|
||
### Output schema
|
||
|
||
```typescript
|
||
{
|
||
success: boolean;
|
||
dry_run: boolean;
|
||
archived_count: number;
|
||
skipped_count: number; // Already in history
|
||
deleted_count: number;
|
||
failed_count: number; // Dirs with no parseable metrics
|
||
archived: string[];
|
||
skipped: string[];
|
||
deleted: string[];
|
||
failed: string[];
|
||
history_file: string;
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## `get_history`
|
||
|
||
Query `config/backtest_history.json` with filters and sorting. Strips `monthly_pnl` arrays by default — set `include_monthly=true` when you need the full breakdown.
|
||
|
||
### Input schema
|
||
|
||
```typescript
|
||
{
|
||
ea?: string; // Substring match on EA name
|
||
symbol?: string; // Exact match (uppercase)
|
||
verdict?: "winner" | "loser" | "marginal" | "reference";
|
||
tag?: string; // Entry must contain this tag
|
||
min_profit?: number; // net_profit >= this
|
||
max_dd_pct?: number; // max_dd_pct <= this
|
||
sort_by?: "date" | "profit" | "dd" | "sharpe"; // Default: date, newest first
|
||
limit?: number; // Default: 20
|
||
include_monthly?: boolean; // Include monthly_pnl arrays (default: false)
|
||
}
|
||
```
|
||
|
||
### Output schema
|
||
|
||
```typescript
|
||
{
|
||
success: boolean;
|
||
count: number;
|
||
entries: Array<{
|
||
id: string; // Report dir basename
|
||
archived_at: string; // ISO timestamp
|
||
report_dir_deleted: boolean;
|
||
ea: string;
|
||
symbol: string;
|
||
timeframe: string;
|
||
from_date: string;
|
||
to_date: string;
|
||
metrics: {
|
||
net_profit: number;
|
||
profit_factor: number;
|
||
max_dd_pct: number;
|
||
sharpe_ratio: number;
|
||
total_trades: number;
|
||
recovery_factor: number;
|
||
win_rate_pct: number;
|
||
expected_payoff: number;
|
||
};
|
||
summary?: {
|
||
green_months: number;
|
||
total_months: number;
|
||
worst_month: string;
|
||
worst_month_pnl: number;
|
||
dominant_exit?: string;
|
||
max_win_streak?: number;
|
||
max_loss_streak?: number;
|
||
};
|
||
worst_dd_event?: {
|
||
peak_dd_pct: number;
|
||
start_date: string;
|
||
end_date: string;
|
||
duration_days: number;
|
||
cause: string;
|
||
};
|
||
monthly_pnl?: Array<{ month: string; pnl: number; trades: number; green: boolean; }>;
|
||
verdict: string | null;
|
||
notes: string;
|
||
tags: string[];
|
||
promoted_to_baseline: boolean;
|
||
}>;
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## `promote_to_baseline`
|
||
|
||
Write a backtest result to `config/baseline.json` — the production reference used by `compare_baseline` and the Claude Code baseline hook. Also marks the source history entry as `promoted_to_baseline: true`.
|
||
|
||
### Input schema
|
||
|
||
```typescript
|
||
{
|
||
// Provide one: history_id, report_dir, or neither (uses latest report)
|
||
history_id?: string; // Entry id from get_history
|
||
report_dir?: string; // Direct path to report directory
|
||
notes?: string; // Written to baseline.json notes field
|
||
}
|
||
```
|
||
|
||
### Output schema
|
||
|
||
```typescript
|
||
{
|
||
success: boolean;
|
||
baseline_file: string;
|
||
baseline: {
|
||
ea: string;
|
||
symbol: string;
|
||
period: string; // "YYYY-MM-DD/YYYY-MM-DD"
|
||
net_profit: number;
|
||
profit_factor: number;
|
||
max_drawdown_pct: number;
|
||
sharpe_ratio: number;
|
||
total_trades: number;
|
||
recovery_factor: number;
|
||
promoted_from: string; // History entry id
|
||
promoted_at: string; // Date promoted (YYYY-MM-DD)
|
||
notes: string;
|
||
};
|
||
}
|
||
```
|
||
|
||
### Example
|
||
|
||
```json
|
||
// Input
|
||
{ "history_id": "20250619_143022_MyEA_XAUUSD_M5", "notes": "v1.3 after walk-forward validation" }
|
||
|
||
// Output
|
||
{
|
||
"success": true,
|
||
"baseline_file": "/path/to/config/baseline.json",
|
||
"baseline": {
|
||
"ea": "MyEA",
|
||
"symbol": "XAUUSD",
|
||
"period": "2025-01-01/2025-06-30",
|
||
"net_profit": 4832.10,
|
||
"profit_factor": 1.54,
|
||
"max_drawdown_pct": 12.3,
|
||
"sharpe_ratio": 1.18,
|
||
"total_trades": 891,
|
||
"recovery_from": "20250619_143022_MyEA_XAUUSD_M5",
|
||
"promoted_at": "2025-06-20",
|
||
"notes": "v1.3 after walk-forward validation"
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## `annotate_history`
|
||
|
||
Update the verdict, notes, or tags on an existing history entry. Use this after `compare_baseline` to record the decision, or to tag runs for later retrieval.
|
||
|
||
### Input schema
|
||
|
||
```typescript
|
||
{
|
||
history_id: string; // Required — entry id to update
|
||
verdict?: "winner" | "loser" | "marginal" | "reference";
|
||
notes?: string; // Replaces existing notes
|
||
tags?: string[]; // Replaces existing tags
|
||
add_tags?: string[]; // Appends to existing tags without overwriting
|
||
}
|
||
```
|
||
|
||
### Output schema
|
||
|
||
```typescript
|
||
{
|
||
success: boolean;
|
||
id: string;
|
||
verdict: string | null;
|
||
notes: string;
|
||
tags: string[];
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## Token-efficient usage patterns
|
||
|
||
### Surveying past runs
|
||
|
||
```
|
||
list_reports(limit=10) → see what's there (live dirs)
|
||
get_history(ea="MyEA", limit=10) → see what's been archived
|
||
analyze_report(report_dir=X) → drill into one specific run
|
||
```
|
||
|
||
Never call `analyze_report` on multiple directories to find the best run — use `list_reports` or `get_history` first.
|
||
|
||
### Checking logs without noise
|
||
|
||
```
|
||
tail_log(job_id=X, filter=errors) → only failures
|
||
tail_log(report_dir=X, n=20) → last 20 lines of backtest progress
|
||
```
|
||
|
||
### Managing disk space
|
||
|
||
```
|
||
archive_all_reports(dry_run=true) → preview what would be archived
|
||
archive_all_reports(delete_after=true, keep_last=3) → archive all, delete old, keep 3 newest
|
||
get_history(sort_by=profit, limit=5) → find best archived runs
|
||
```
|
||
|
||
### Labelling experiments
|
||
|
||
```
|
||
annotate_history(history_id=X, verdict="loser", notes="SL too tight, reversed at L3")
|
||
annotate_history(history_id=X, add_tags=["walk-forward-fail"])
|
||
get_history(verdict="winner") → all winners across all sessions
|
||
```
|
||
|
||
### Promoting a new production config
|
||
|
||
```
|
||
run_backtest(...)
|
||
compare_baseline(...) → get verdict
|
||
archive_report(delete_after=true, verdict="winner")
|
||
promote_to_baseline(notes="v1.4 after WF") → update baseline.json
|
||
```
|
||
|
||
### Managing cache
|
||
|
||
```
|
||
cache_status() → see symbol breakdown and total size
|
||
clean_cache(symbol=XAUUSD, dry_run=true) → preview
|
||
clean_cache(symbol=XAUUSD) → execute
|
||
```
|
||
|
||
### Pre-flight validation
|
||
|
||
```
|
||
get_active_account() → current login, server, available symbols
|
||
check_symbol_data_status(symbol=XAUUSD, from=2025.01.01, to=2025.03.31)
|
||
→ verify data availability before backtest
|
||
check_mt5_status() → verify MT5 installation and readiness
|
||
validate_ea_syntax(path=MyEA.mq5) → pre-compile syntax check
|
||
```
|
||
|
||
### Project management
|
||
|
||
```
|
||
init_project(name=MyStrategy, template=scalper) → scaffold new EA with template
|
||
create_set_template(ea=MyEA) → generate .set from EA inputs
|
||
export_report(report_dir=..., format=csv) → export to CSV/JSON/Markdown
|
||
```
|
||
|
||
### History and comparison
|
||
|
||
```
|
||
get_backtest_history(expert=MyEA, limit=10) → list past backtests with metrics
|
||
compare_backtests(report_dirs=["dir1", "dir2"]) → side-by-side comparison
|
||
```
|
||
|
||
### Working with set files
|
||
|
||
```
|
||
# Inspect
|
||
list_set_files(ea="MyEA") → all variants, swept param counts, combinations
|
||
describe_sweep(path=MyEA_opt.set) → verify 240 combinations before launching opt
|
||
diff_set_files(a=v1.2.set, b=v1.3.set) → only changed params, not full file content
|
||
|
||
# Edit (never read+write manually)
|
||
patch_set_file(path, {TP_Pips: 350}) → change one param, keep everything else intact
|
||
clone_set_file(src, dest, overrides) → create variant from base in one call
|
||
|
||
# Generate after optimization
|
||
set_from_optimization( → map results[0].params → clean backtest .set
|
||
path=MyEA_v1.3.set,
|
||
params=results[0].params,
|
||
template=MyEA_base.set → fills non-swept params from existing file
|
||
)
|
||
```
|
||
|
||
---
|
||
|
||
## `list_symbols`
|
||
|
||
List all available symbols in the MT5 terminal.
|
||
|
||
**When to call:** To verify a symbol is available before running backtests, or to discover available symbols.
|
||
|
||
### Input schema
|
||
|
||
```typescript
|
||
{
|
||
// No inputs required
|
||
}
|
||
```
|
||
|
||
### Output schema
|
||
|
||
```typescript
|
||
{
|
||
success: boolean;
|
||
symbols: Array<{
|
||
name: string; // e.g. "XAUUSD", "EURUSD"
|
||
description?: string; // Symbol description
|
||
visible: boolean; // Whether symbol is visible in Market Watch
|
||
}>;
|
||
error?: string;
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## `check_update`
|
||
|
||
Check if a newer version of MT5-Quant is available on GitHub.
|
||
|
||
**When to call:** Periodically to stay up to date with the latest features and fixes.
|
||
|
||
### Input schema
|
||
|
||
```typescript
|
||
{
|
||
// No inputs required
|
||
}
|
||
```
|
||
|
||
### Output schema
|
||
|
||
```typescript
|
||
{
|
||
success: boolean;
|
||
current_version: string; // Current version, e.g. "1.31.5"
|
||
latest_version: string; // Latest version from GitHub releases
|
||
update_available: boolean;
|
||
download_url?: string; // URL to latest release if update available
|
||
release_notes?: string; // Release notes from latest version
|
||
error?: string;
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## `update`
|
||
|
||
Update MT5-Quant to the latest version from GitHub releases.
|
||
|
||
**When to call:** After `check_update` indicates a newer version is available.
|
||
|
||
### Input schema
|
||
|
||
```typescript
|
||
{
|
||
// No inputs required
|
||
}
|
||
```
|
||
|
||
### Output schema
|
||
|
||
```typescript
|
||
{
|
||
success: boolean;
|
||
message: string; // Update status message
|
||
new_version: string; // Version installed
|
||
error?: string;
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## `healthcheck`
|
||
|
||
Quick server health check to verify the MCP server is running.
|
||
|
||
**When to call:** To verify the server is responsive after installation or configuration changes.
|
||
|
||
### Input schema
|
||
|
||
```typescript
|
||
{
|
||
// No inputs required
|
||
}
|
||
```
|
||
|
||
### Output schema
|
||
|
||
```typescript
|
||
{
|
||
success: boolean;
|
||
version: string; // MT5-Quant version
|
||
status: "healthy" | "unhealthy";
|
||
uptime_seconds: number;
|
||
error?: string;
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## `list_experts`
|
||
|
||
List all Expert Advisors (EAs) in the MQL5/Experts directory.
|
||
|
||
**When to call:** To discover available EAs before running backtests.
|
||
|
||
### Input schema
|
||
|
||
```typescript
|
||
{
|
||
// No inputs required
|
||
}
|
||
```
|
||
|
||
### Output schema
|
||
|
||
```typescript
|
||
{
|
||
success: boolean;
|
||
experts: Array<{
|
||
name: string; // EA name without extension
|
||
path: string; // Full path to .mq5 file
|
||
has_ex5: boolean; // Whether compiled .ex5 exists
|
||
modified: string; // Last modified timestamp
|
||
}>;
|
||
error?: string;
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## `list_indicators`
|
||
|
||
List all indicators in the MQL5/Indicators directory.
|
||
|
||
**When to call:** To discover available indicators for use in projects.
|
||
|
||
### Input schema
|
||
|
||
```typescript
|
||
{
|
||
// No inputs required
|
||
}
|
||
```
|
||
|
||
### Output schema
|
||
|
||
```typescript
|
||
{
|
||
success: boolean;
|
||
indicators: Array<{
|
||
name: string; // Indicator name without extension
|
||
path: string; // Full path to .mq5 file
|
||
has_ex5: boolean; // Whether compiled .ex5 exists
|
||
modified: string; // Last modified timestamp
|
||
}>;
|
||
error?: string;
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## `list_scripts`
|
||
|
||
List all scripts in the MQL5/Scripts directory.
|
||
|
||
**When to call:** To discover available scripts for one-time execution.
|
||
|
||
### Input schema
|
||
|
||
```typescript
|
||
{
|
||
// No inputs required
|
||
}
|
||
```
|
||
|
||
### Output schema
|
||
|
||
```typescript
|
||
{
|
||
success: boolean;
|
||
scripts: Array<{
|
||
name: string; // Script name without extension
|
||
path: string; // Full path to .mq5 file
|
||
has_ex5: boolean; // Whether compiled .ex5 exists
|
||
modified: string; // Last modified timestamp
|
||
}>;
|
||
error?: string;
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## `search_experts`
|
||
|
||
Search EAs by name pattern across all directories.
|
||
|
||
**When to call:** To find EAs matching a specific pattern when the exact name is unknown.
|
||
|
||
### Input schema
|
||
|
||
```typescript
|
||
{
|
||
pattern: string; // Search pattern, e.g. "Grid" or "v1."
|
||
}
|
||
```
|
||
|
||
### Output schema
|
||
|
||
```typescript
|
||
{
|
||
success: boolean;
|
||
matches: Array<{
|
||
name: string; // EA name without extension
|
||
path: string; // Full path to .mq5 file
|
||
has_ex5: boolean; // Whether compiled .ex5 exists
|
||
modified: string; // Last modified timestamp
|
||
}>;
|
||
error?: string;
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## `search_indicators`
|
||
|
||
Search indicators by name pattern.
|
||
|
||
**When to call:** To find indicators matching a specific pattern.
|
||
|
||
### Input schema
|
||
|
||
```typescript
|
||
{
|
||
pattern: string; // Search pattern
|
||
}
|
||
```
|
||
|
||
### Output schema
|
||
|
||
```typescript
|
||
{
|
||
success: boolean;
|
||
matches: Array<{
|
||
name: string; // Indicator name without extension
|
||
path: string; // Full path to .mq5 file
|
||
has_ex5: boolean; // Whether compiled .ex5 exists
|
||
modified: string; // Last modified timestamp
|
||
}>;
|
||
error?: string;
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## `search_scripts`
|
||
|
||
Search scripts by name pattern.
|
||
|
||
**When to call:** To find scripts matching a specific pattern.
|
||
|
||
### Input schema
|
||
|
||
```typescript
|
||
{
|
||
pattern: string; // Search pattern
|
||
}
|
||
```
|
||
|
||
### Output schema
|
||
|
||
```typescript
|
||
{
|
||
success: boolean;
|
||
matches: Array<{
|
||
name: string; // Script name without extension
|
||
path: string; // Full path to .mq5 file
|
||
has_ex5: boolean; // Whether compiled .ex5 exists
|
||
modified: string; // Last modified timestamp
|
||
}>;
|
||
error?: string;
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## `copy_indicator_to_project`
|
||
|
||
Copy indicator to project directory.
|
||
|
||
**When to call:** To include an indicator in your EA project.
|
||
|
||
### Input schema
|
||
|
||
```typescript
|
||
{
|
||
indicator_name: string; // Name of indicator to copy
|
||
project_dir: string; // Target project directory path
|
||
}
|
||
```
|
||
|
||
### Output schema
|
||
|
||
```typescript
|
||
{
|
||
success: boolean;
|
||
source_path: string; // Original indicator path
|
||
target_path: string; // Copied indicator path
|
||
error?: string;
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## `copy_script_to_project`
|
||
|
||
Copy script to project directory.
|
||
|
||
**When to call:** To include a script in your EA project.
|
||
|
||
### Input schema
|
||
|
||
```typescript
|
||
{
|
||
script_name: string; // Name of script to copy
|
||
project_dir: string; // Target project directory path
|
||
}
|
||
```
|
||
|
||
### Output schema
|
||
|
||
```typescript
|
||
{
|
||
success: boolean;
|
||
source_path: string; // Original script path
|
||
target_path: string; // Copied script path
|
||
error?: string;
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## `diagnose_wine`
|
||
|
||
Check Wine installation, version, and prefix health.
|
||
|
||
**When to call:** When experiencing Wine-related issues or to verify Wine setup.
|
||
|
||
### Input schema
|
||
|
||
```typescript
|
||
{
|
||
// No inputs required
|
||
}
|
||
```
|
||
|
||
### Output schema
|
||
|
||
```typescript
|
||
{
|
||
success: boolean;
|
||
wine_found: boolean;
|
||
wine_path?: string;
|
||
wine_version?: string;
|
||
prefix_path?: string;
|
||
prefix_health: "healthy" | "corrupted" | "missing";
|
||
error?: string;
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## `get_mt5_logs`
|
||
|
||
Get MT5 terminal, tester, or MetaEditor logs with filtering.
|
||
|
||
**When to call:** To diagnose backtest failures or compile errors.
|
||
|
||
### Input schema
|
||
|
||
```typescript
|
||
{
|
||
log_type: "terminal" | "tester" | "metaeditor";
|
||
lines?: number; // Number of lines to retrieve (default: 100)
|
||
filter?: "all" | "errors" | "warnings"; // Default: "all"
|
||
}
|
||
```
|
||
|
||
### Output schema
|
||
|
||
```typescript
|
||
{
|
||
success: boolean;
|
||
log_path: string;
|
||
lines: Array<{
|
||
timestamp: string;
|
||
level: "info" | "warning" | "error";
|
||
message: string;
|
||
}>;
|
||
error?: string;
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## `search_mt5_errors`
|
||
|
||
Search logs for error patterns (crash, exception, access violation).
|
||
|
||
**When to call:** To quickly find crash causes in logs.
|
||
|
||
### Input schema
|
||
|
||
```typescript
|
||
{
|
||
log_type: "terminal" | "tester" | "metaeditor" | "all";
|
||
patterns?: string[]; // Custom error patterns (default: common MT5 errors)
|
||
max_results?: number; // Maximum error entries to return (default: 50)
|
||
}
|
||
```
|
||
|
||
### Output schema
|
||
|
||
```typescript
|
||
{
|
||
success: boolean;
|
||
errors: Array<{
|
||
timestamp: string;
|
||
log_type: string;
|
||
message: string;
|
||
context?: string; // Surrounding lines for context
|
||
}>;
|
||
total_found: number;
|
||
error?: string;
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## `check_mt5_process`
|
||
|
||
Check if MT5 processes are running, get PID, CPU, memory usage.
|
||
|
||
**When to call:** To verify MT5 is running or to check for stuck processes.
|
||
|
||
### Input schema
|
||
|
||
```typescript
|
||
{
|
||
// No inputs required
|
||
}
|
||
```
|
||
|
||
### Output schema
|
||
|
||
```typescript
|
||
{
|
||
success: boolean;
|
||
processes: Array<{
|
||
pid: number;
|
||
name: string; // "terminal64.exe" or "metatester64.exe"
|
||
cpu_percent: number;
|
||
memory_mb: number;
|
||
uptime_seconds: number;
|
||
status: "running" | "zombie" | "stopped";
|
||
}>;
|
||
error?: string;
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## `kill_mt5_process`
|
||
|
||
Kill stuck MT5 processes.
|
||
|
||
**When to call:** When MT5 is stuck or hung and needs to be terminated.
|
||
|
||
### Input schema
|
||
|
||
```typescript
|
||
{
|
||
pid?: number; // Specific PID to kill (optional, kills all if omitted)
|
||
force?: boolean; // Force kill wineserver too (default: false)
|
||
}
|
||
```
|
||
|
||
### Output schema
|
||
|
||
```typescript
|
||
{
|
||
success: boolean;
|
||
killed_pids: number[];
|
||
message: string;
|
||
error?: string;
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## `check_system_resources`
|
||
|
||
Check disk space, memory, CPU availability.
|
||
|
||
**When to call:** Before running long optimizations to ensure sufficient resources.
|
||
|
||
### Input schema
|
||
|
||
```typescript
|
||
{
|
||
// No inputs required
|
||
}
|
||
```
|
||
|
||
### Output schema
|
||
|
||
```typescript
|
||
{
|
||
success: boolean;
|
||
disk: {
|
||
path: string;
|
||
total_gb: number;
|
||
free_gb: number;
|
||
used_percent: number;
|
||
};
|
||
memory: {
|
||
total_mb: number;
|
||
free_mb: number;
|
||
used_percent: number;
|
||
};
|
||
cpu: {
|
||
cores: number;
|
||
usage_percent: number;
|
||
};
|
||
error?: string;
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## `validate_mt5_config`
|
||
|
||
Validate terminal.ini and tester configuration files.
|
||
|
||
**When to call:** When experiencing configuration-related backtest failures.
|
||
|
||
### Input schema
|
||
|
||
```typescript
|
||
{
|
||
// No inputs required (auto-detects config paths)
|
||
}
|
||
```
|
||
|
||
### Output schema
|
||
|
||
```typescript
|
||
{
|
||
success: boolean;
|
||
terminal_ini: {
|
||
path: string;
|
||
valid: boolean;
|
||
issues?: string[];
|
||
};
|
||
tester_ini?: {
|
||
path: string;
|
||
valid: boolean;
|
||
issues?: string[];
|
||
};
|
||
error?: string;
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## `get_wine_prefix_info`
|
||
|
||
Get Wine prefix details: Windows version, installed programs, registry.
|
||
|
||
**When to call:** To diagnose Wine prefix issues or verify Wine setup.
|
||
|
||
### Input schema
|
||
|
||
```typescript
|
||
{
|
||
// No inputs required
|
||
}
|
||
```
|
||
|
||
### Output schema
|
||
|
||
```typescript
|
||
{
|
||
success: boolean;
|
||
prefix_path: string;
|
||
windows_version: string;
|
||
installed_programs: string[];
|
||
registry_keys?: Array<{
|
||
key: string;
|
||
value: string;
|
||
}>;
|
||
error?: string;
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## `get_backtest_crash_info`
|
||
|
||
Investigate backtest failures: incomplete markers, missing metrics.json, Wine/MT5 errors.
|
||
|
||
**When to call:** When a backtest fails unexpectedly.
|
||
|
||
### Input schema
|
||
|
||
```typescript
|
||
{
|
||
report_dir: string; // Path to the failed backtest report directory
|
||
}
|
||
```
|
||
|
||
### Output schema
|
||
|
||
```typescript
|
||
{
|
||
success: boolean;
|
||
status: "complete" | "incomplete" | "crashed" | "missing";
|
||
issues: Array<{
|
||
type: string;
|
||
message: string;
|
||
severity: "error" | "warning";
|
||
}>;
|
||
error_log?: string;
|
||
error?: string;
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## `get_latest_report`
|
||
|
||
Get most recent report with optional equity chart.
|
||
|
||
**When to call:** To quickly access the latest backtest results.
|
||
|
||
### Input schema
|
||
|
||
```typescript
|
||
{
|
||
include_chart?: boolean; // Include equity chart data (default: false)
|
||
}
|
||
```
|
||
|
||
### Output schema
|
||
|
||
```typescript
|
||
{
|
||
success: boolean;
|
||
report: {
|
||
id: string;
|
||
report_dir: string;
|
||
ea: string;
|
||
symbol: string;
|
||
timeframe: string;
|
||
from_date: string;
|
||
to_date: string;
|
||
metrics: {
|
||
net_profit: number;
|
||
profit_factor: number;
|
||
max_dd_pct: number;
|
||
total_trades: number;
|
||
};
|
||
equity_chart?: Array<{date: string; equity: number}>;
|
||
};
|
||
error?: string;
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## `search_reports`
|
||
|
||
Find reports by EA, symbol, date range, or profit criteria.
|
||
|
||
**When to call:** To find specific reports matching criteria.
|
||
|
||
### Input schema
|
||
|
||
```typescript
|
||
{
|
||
ea?: string;
|
||
symbol?: string;
|
||
from_date?: string; // "YYYY-MM-DD"
|
||
to_date?: string; // "YYYY-MM-DD"
|
||
min_profit?: number;
|
||
max_profit?: number;
|
||
min_profit_factor?: number;
|
||
max_dd_pct?: number;
|
||
limit?: number; // Max results (default: 50)
|
||
}
|
||
```
|
||
|
||
### Output schema
|
||
|
||
```typescript
|
||
{
|
||
success: boolean;
|
||
reports: Array<{
|
||
id: string;
|
||
report_dir: string;
|
||
ea: string;
|
||
symbol: string;
|
||
timeframe: string;
|
||
from_date: string;
|
||
to_date: string;
|
||
metrics: {
|
||
net_profit: number;
|
||
profit_factor: number;
|
||
max_dd_pct: number;
|
||
total_trades: number;
|
||
};
|
||
}>;
|
||
total: number;
|
||
error?: string;
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## `get_report_by_id`
|
||
|
||
Get specific report by ID with equity chart.
|
||
|
||
**When to call:** To retrieve a specific report's full details.
|
||
|
||
### Input schema
|
||
|
||
```typescript
|
||
{
|
||
report_id: string; // Report directory basename
|
||
include_chart?: boolean; // Include equity chart data (default: false)
|
||
}
|
||
```
|
||
|
||
### Output schema
|
||
|
||
```typescript
|
||
{
|
||
success: boolean;
|
||
report: {
|
||
id: string;
|
||
report_dir: string;
|
||
ea: string;
|
||
symbol: string;
|
||
timeframe: string;
|
||
from_date: string;
|
||
to_date: string;
|
||
metrics: {
|
||
net_profit: number;
|
||
profit_factor: number;
|
||
max_dd_pct: number;
|
||
total_trades: number;
|
||
sharpe_ratio: number;
|
||
recovery_factor: number;
|
||
win_rate_pct: number;
|
||
};
|
||
equity_chart?: Array<{date: string; equity: number}>;
|
||
};
|
||
error?: string;
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## `get_reports_summary`
|
||
|
||
Aggregate stats: counts, averages, pass rates.
|
||
|
||
**When to call:** To get overview statistics across all reports.
|
||
|
||
### Input schema
|
||
|
||
```typescript
|
||
{
|
||
ea?: string; // Filter by EA
|
||
symbol?: string; // Filter by symbol
|
||
from_date?: string; // Filter by date range
|
||
to_date?: string;
|
||
}
|
||
```
|
||
|
||
### Output schema
|
||
|
||
```typescript
|
||
{
|
||
success: boolean;
|
||
summary: {
|
||
total_reports: number;
|
||
avg_profit: number;
|
||
avg_profit_factor: number;
|
||
avg_dd_pct: number;
|
||
profitable_count: number;
|
||
pass_rate_pct: number;
|
||
};
|
||
error?: string;
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## `get_best_reports`
|
||
|
||
Top N reports sorted by any metric (profit factor, drawdown, etc.).
|
||
|
||
**When to call:** To find the best performing reports.
|
||
|
||
### Input schema
|
||
|
||
```typescript
|
||
{
|
||
sort_by: "net_profit" | "profit_factor" | "sharpe_ratio" | "recovery_factor" | "win_rate_pct";
|
||
order: "desc" | "asc"; // Default: "desc"
|
||
limit?: number; // Max results (default: 10)
|
||
ea?: string;
|
||
symbol?: string;
|
||
}
|
||
```
|
||
|
||
### Output schema
|
||
|
||
```typescript
|
||
{
|
||
success: boolean;
|
||
reports: Array<{
|
||
id: string;
|
||
report_dir: string;
|
||
ea: string;
|
||
symbol: string;
|
||
metrics: {
|
||
net_profit: number;
|
||
profit_factor: number;
|
||
max_dd_pct: number;
|
||
sharpe_ratio: number;
|
||
recovery_factor: number;
|
||
win_rate_pct: number;
|
||
};
|
||
}>;
|
||
error?: string;
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## `search_reports_by_tags`
|
||
|
||
Find reports by tags.
|
||
|
||
**When to call:** To find reports tagged with specific keywords.
|
||
|
||
### Input schema
|
||
|
||
```typescript
|
||
{
|
||
tags: string[]; // Tags to search for
|
||
match_all?: boolean; // Require all tags (default: false)
|
||
limit?: number;
|
||
}
|
||
```
|
||
|
||
### Output schema
|
||
|
||
```typescript
|
||
{
|
||
success: boolean;
|
||
reports: Array<{
|
||
id: string;
|
||
report_dir: string;
|
||
tags: string[];
|
||
metrics: {
|
||
net_profit: number;
|
||
profit_factor: number;
|
||
max_dd_pct: number;
|
||
};
|
||
}>;
|
||
error?: string;
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## `search_reports_by_date_range`
|
||
|
||
Query by backtest date range.
|
||
|
||
**When to call:** To find reports from a specific time period.
|
||
|
||
### Input schema
|
||
|
||
```typescript
|
||
{
|
||
from_date: string; // "YYYY-MM-DD"
|
||
to_date: string; // "YYYY-MM-DD"
|
||
limit?: number;
|
||
}
|
||
```
|
||
|
||
### Output schema
|
||
|
||
```typescript
|
||
{
|
||
success: boolean;
|
||
reports: Array<{
|
||
id: string;
|
||
report_dir: string;
|
||
timestamp: string;
|
||
metrics: {
|
||
net_profit: number;
|
||
profit_factor: number;
|
||
max_dd_pct: number;
|
||
};
|
||
}>;
|
||
error?: string;
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## `search_reports_by_notes`
|
||
|
||
Full-text search in report notes.
|
||
|
||
**When to call:** To find reports with specific notes.
|
||
|
||
### Input schema
|
||
|
||
```typescript
|
||
{
|
||
query: string; // Search query
|
||
limit?: number;
|
||
}
|
||
```
|
||
|
||
### Output schema
|
||
|
||
```typescript
|
||
{
|
||
success: boolean;
|
||
reports: Array<{
|
||
id: string;
|
||
report_dir: string;
|
||
notes: string;
|
||
metrics: {
|
||
net_profit: number;
|
||
profit_factor: number;
|
||
max_dd_pct: number;
|
||
};
|
||
}>;
|
||
error?: string;
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## `get_reports_by_set_file`
|
||
|
||
Find all reports using a specific .set file.
|
||
|
||
**When to call:** To see all backtests run with a specific parameter set.
|
||
|
||
### Input schema
|
||
|
||
```typescript
|
||
{
|
||
set_file: string; // .set file name (without path)
|
||
}
|
||
```
|
||
|
||
### Output schema
|
||
|
||
```typescript
|
||
{
|
||
success: boolean;
|
||
reports: Array<{
|
||
id: string;
|
||
report_dir: string;
|
||
set_file: string;
|
||
metrics: {
|
||
net_profit: number;
|
||
profit_factor: number;
|
||
max_dd_pct: number;
|
||
};
|
||
}>;
|
||
error?: string;
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## `get_comparable_reports`
|
||
|
||
Find comparable reports (same EA/symbol/timeframe).
|
||
|
||
**When to call:** To find reports for comparison/analysis.
|
||
|
||
### Input schema
|
||
|
||
```typescript
|
||
{
|
||
ea: string;
|
||
symbol: string;
|
||
timeframe?: string; // Optional, uses default if omitted
|
||
}
|
||
```
|
||
|
||
### Output schema
|
||
|
||
```typescript
|
||
{
|
||
success: boolean;
|
||
reports: Array<{
|
||
id: string;
|
||
report_dir: string;
|
||
from_date: string;
|
||
to_date: string;
|
||
metrics: {
|
||
net_profit: number;
|
||
profit_factor: number;
|
||
max_dd_pct: number;
|
||
total_trades: number;
|
||
};
|
||
}>;
|
||
error?: string;
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## `export_deals_csv`
|
||
|
||
Export deals for a report to a CSV file on demand. Deals are stored in the database — use this when you need a CSV file for external tools (Excel, pandas, etc.).
|
||
|
||
**When to call:** When you need a `deals.csv` file. CSV is not written automatically after backtests anymore.
|
||
|
||
### Input schema
|
||
|
||
```typescript
|
||
{
|
||
report_id?: string; // Report ID to export (default: latest report)
|
||
output_path?: string; // File path for CSV output (default: <report_dir>/deals.csv)
|
||
}
|
||
```
|
||
|
||
### Output schema
|
||
|
||
```typescript
|
||
{
|
||
success: boolean;
|
||
report_id: string;
|
||
deals_count: number;
|
||
output_path: string; // Absolute path to the written CSV file
|
||
}
|
||
```
|
||
|
||
### Example
|
||
|
||
```json
|
||
// Input — export latest report to default path
|
||
{}
|
||
|
||
// Input — export specific report to custom path
|
||
{
|
||
"report_id": "20260422_051041_DPS21_XAUUSDc_M5_1",
|
||
"output_path": "/tmp/dps21_deals.csv"
|
||
}
|
||
|
||
// Output
|
||
{
|
||
"success": true,
|
||
"report_id": "20260422_051041_DPS21_XAUUSDc_M5_1",
|
||
"deals_count": 891,
|
||
"output_path": "/Users/…/reports/20260422_051041_DPS21_XAUUSDc_M5_1/deals.csv"
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## Granular Analytics — Common Input Pattern
|
||
|
||
All granular analytics tools below (`analyze_monthly_pnl` through `analyze_efficiency`, plus `list_deals` and `search_deals_*`) share the same report resolution logic:
|
||
|
||
```typescript
|
||
{
|
||
report_id?: string; // Preferred: ID from list_reports
|
||
report_dir?: string; // Legacy: filesystem path (looks up DB entry)
|
||
// Omit both → uses the latest report automatically
|
||
}
|
||
```
|
||
|
||
Deals are loaded from **SQLite DB**, not from CSV files. The `report_dir` parameter is kept for backward compatibility — if your report is in the DB, passing `report_dir` will resolve to its `report_id` automatically.
|
||
|
||
---
|
||
|
||
## `analyze_monthly_pnl`
|
||
|
||
Monthly P/L breakdown only.
|
||
|
||
**When to call:** To analyze performance by month without full analysis.
|
||
|
||
### Input schema
|
||
|
||
```typescript
|
||
{
|
||
report_id?: string; // Preferred: from list_reports
|
||
report_dir?: string; // Legacy: path to report directory
|
||
}
|
||
// Omit all args to use the latest report
|
||
```
|
||
|
||
### Output schema
|
||
|
||
```typescript
|
||
{
|
||
success: boolean;
|
||
monthly_data: Array<{
|
||
month: string; // "2025-01"
|
||
profit: number;
|
||
trades: number;
|
||
win_rate: number;
|
||
}>;
|
||
green_months: number;
|
||
total_months: number;
|
||
error?: string;
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## `analyze_drawdown_events`
|
||
|
||
Drawdown events and causes only.
|
||
|
||
**When to call:** To identify and analyze drawdown periods.
|
||
|
||
### Input schema
|
||
|
||
```typescript
|
||
{
|
||
report_dir: string;
|
||
}
|
||
```
|
||
|
||
### Output schema
|
||
|
||
```typescript
|
||
{
|
||
success: boolean;
|
||
drawdowns: Array<{
|
||
start_date: string;
|
||
end_date: string;
|
||
depth_pct: number;
|
||
duration_days: number;
|
||
recovery_days: number;
|
||
cause?: string;
|
||
}>;
|
||
worst_dd_event: {
|
||
depth_pct: number;
|
||
date: string;
|
||
};
|
||
error?: string;
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## `analyze_top_losses`
|
||
|
||
Worst losing deals only.
|
||
|
||
**When to call:** To identify the biggest losing trades for analysis.
|
||
|
||
### Input schema
|
||
|
||
```typescript
|
||
{
|
||
report_dir: string;
|
||
top_n?: number; // Number of worst deals to return (default: 10)
|
||
}
|
||
```
|
||
|
||
### Output schema
|
||
|
||
```typescript
|
||
{
|
||
success: boolean;
|
||
worst_deals: Array<{
|
||
entry_time: string;
|
||
exit_time: string;
|
||
profit: number;
|
||
profit_pct: number;
|
||
volume: number;
|
||
comment?: string;
|
||
}>;
|
||
error?: string;
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## `analyze_loss_sequences`
|
||
|
||
Consecutive loss patterns only.
|
||
|
||
**When to call:** To analyze losing streak patterns.
|
||
|
||
### Input schema
|
||
|
||
```typescript
|
||
{
|
||
report_dir: string;
|
||
}
|
||
```
|
||
|
||
### Output schema
|
||
|
||
```typescript
|
||
{
|
||
success: boolean;
|
||
loss_streaks: Array<{
|
||
start_index: number;
|
||
end_index: number;
|
||
length: number;
|
||
total_loss: number;
|
||
avg_loss: number;
|
||
}>;
|
||
max_loss_streak: {
|
||
length: number;
|
||
total_loss: number;
|
||
};
|
||
error?: string;
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## `analyze_position_pairs`
|
||
|
||
Position hold time and P/L pairs.
|
||
|
||
**When to call:** To analyze relationship between hold time and profit.
|
||
|
||
### Input schema
|
||
|
||
```typescript
|
||
{
|
||
report_dir: string;
|
||
}
|
||
```
|
||
|
||
### Output schema
|
||
|
||
```typescript
|
||
{
|
||
success: boolean;
|
||
pairs: Array<{
|
||
hold_time_minutes: number;
|
||
profit: number;
|
||
profit_pct: number;
|
||
count: number;
|
||
}>;
|
||
correlation: number;
|
||
error?: string;
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## `analyze_direction_bias`
|
||
|
||
Buy vs Sell performance.
|
||
|
||
**When to call:** To analyze directional bias in trading.
|
||
|
||
### Input schema
|
||
|
||
```typescript
|
||
{
|
||
report_dir: string;
|
||
}
|
||
```
|
||
|
||
### Output schema
|
||
|
||
```typescript
|
||
{
|
||
success: boolean;
|
||
buy_trades: {
|
||
count: number;
|
||
profit: number;
|
||
win_rate: number;
|
||
};
|
||
sell_trades: {
|
||
count: number;
|
||
profit: number;
|
||
win_rate: number;
|
||
};
|
||
bias: "buy" | "sell" | "neutral";
|
||
error?: string;
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## `analyze_streaks`
|
||
|
||
Win/loss streak analysis.
|
||
|
||
**When to call:** To analyze winning and losing streak patterns.
|
||
|
||
### Input schema
|
||
|
||
```typescript
|
||
{
|
||
report_dir: string;
|
||
}
|
||
```
|
||
|
||
### Output schema
|
||
|
||
```typescript
|
||
{
|
||
success: boolean;
|
||
win_streaks: Array<{
|
||
length: number;
|
||
total_profit: number;
|
||
}>;
|
||
loss_streaks: Array<{
|
||
length: number;
|
||
total_loss: number;
|
||
}>;
|
||
max_win_streak: number;
|
||
max_loss_streak: number;
|
||
error?: string;
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## `analyze_concurrent_peak`
|
||
|
||
Peak simultaneous positions.
|
||
|
||
**When to call:** To analyze maximum position concurrency.
|
||
|
||
### Input schema
|
||
|
||
```typescript
|
||
{
|
||
report_dir: string;
|
||
}
|
||
```
|
||
|
||
### Output schema
|
||
|
||
```typescript
|
||
{
|
||
success: boolean;
|
||
max_concurrent: number;
|
||
avg_concurrent: number;
|
||
distribution: Array<{
|
||
concurrent_count: number;
|
||
occurrences: number;
|
||
}>;
|
||
error?: string;
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## `list_deals`
|
||
|
||
List individual deals with filters (type, profit range, volume, dates). Loads from SQLite DB.
|
||
|
||
**When to call:** To query individual trades with specific criteria.
|
||
|
||
### Input schema
|
||
|
||
```typescript
|
||
{
|
||
report_id?: string; // Preferred: from list_reports
|
||
report_dir?: string; // Legacy: path to report directory
|
||
// Omit all to use latest report
|
||
deal_type?: "buy" | "sell" | "all";
|
||
min_profit?: number;
|
||
max_profit?: number;
|
||
min_volume?: number;
|
||
max_volume?: number;
|
||
from_date?: string; // "YYYY-MM-DD"
|
||
to_date?: string; // "YYYY-MM-DD"
|
||
limit?: number;
|
||
}
|
||
```
|
||
|
||
### Output schema
|
||
|
||
```typescript
|
||
{
|
||
success: boolean;
|
||
deals: Array<{
|
||
entry_time: string;
|
||
exit_time: string;
|
||
type: "buy" | "sell";
|
||
profit: number;
|
||
profit_pct: number;
|
||
volume: number;
|
||
comment?: string;
|
||
magic?: number;
|
||
}>;
|
||
total: number;
|
||
error?: string;
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## `search_deals_by_comment`
|
||
|
||
Full-text search in deal comments (e.g., "Layer #3"). Loads from SQLite DB.
|
||
|
||
**When to call:** To find deals with specific comment patterns.
|
||
|
||
### Input schema
|
||
|
||
```typescript
|
||
{
|
||
report_id?: string; // Preferred: from list_reports
|
||
report_dir?: string; // Legacy: path to report directory
|
||
query: string; // Search pattern in comment field (required)
|
||
limit?: number;
|
||
}
|
||
```
|
||
|
||
### Output schema
|
||
|
||
```typescript
|
||
{
|
||
success: boolean;
|
||
deals: Array<{
|
||
entry_time: string;
|
||
exit_time: string;
|
||
type: "buy" | "sell";
|
||
profit: number;
|
||
profit_pct: number;
|
||
volume: number;
|
||
comment: string;
|
||
magic?: number;
|
||
}>;
|
||
total: number;
|
||
error?: string;
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## `search_deals_by_magic`
|
||
|
||
Filter deals by EA magic number.
|
||
|
||
**When to call:** To find trades from a specific EA (by magic number).
|
||
|
||
### Input schema
|
||
|
||
```typescript
|
||
{
|
||
report_dir: string;
|
||
magic: number; // EA magic number to filter by
|
||
limit?: number;
|
||
}
|
||
```
|
||
|
||
### Output schema
|
||
|
||
```typescript
|
||
{
|
||
success: boolean;
|
||
deals: Array<{
|
||
entry_time: string;
|
||
exit_time: string;
|
||
type: "buy" | "sell";
|
||
profit: number;
|
||
profit_pct: number;
|
||
volume: number;
|
||
comment?: string;
|
||
magic: number;
|
||
}>;
|
||
total: number;
|
||
error?: string;
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## `analyze_profit_distribution`
|
||
|
||
Profit histogram: small/medium/large wins and losses.
|
||
|
||
**When to call:** To understand profit distribution across trade sizes.
|
||
|
||
### Input schema
|
||
|
||
```typescript
|
||
{
|
||
report_dir: string;
|
||
}
|
||
```
|
||
|
||
### Output schema
|
||
|
||
```typescript
|
||
{
|
||
success: boolean;
|
||
distribution: {
|
||
small_wins: {count: number; avg_profit: number};
|
||
medium_wins: {count: number; avg_profit: number};
|
||
large_wins: {count: number; avg_profit: number};
|
||
small_losses: {count: number; avg_loss: number};
|
||
medium_losses: {count: number; avg_loss: number};
|
||
large_losses: {count: number; avg_loss: number};
|
||
};
|
||
error?: string;
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## `analyze_time_performance`
|
||
|
||
Performance by hour of day and day of week.
|
||
|
||
**When to call:** To identify best/worst trading times.
|
||
|
||
### Input schema
|
||
|
||
```typescript
|
||
{
|
||
report_dir: string;
|
||
}
|
||
```
|
||
|
||
### Output schema
|
||
|
||
```typescript
|
||
{
|
||
success: boolean;
|
||
hourly_performance: Array<{
|
||
hour: number;
|
||
profit: number;
|
||
trades: number;
|
||
win_rate: number;
|
||
}>;
|
||
daily_performance: Array<{
|
||
day: "Mon" | "Tue" | "Wed" | "Thu" | "Fri";
|
||
profit: number;
|
||
trades: number;
|
||
win_rate: number;
|
||
}>;
|
||
error?: string;
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## `analyze_hold_time_distribution`
|
||
|
||
Hold time buckets + correlation with profit.
|
||
|
||
**When to call:** To analyze relationship between position duration and profit.
|
||
|
||
### Input schema
|
||
|
||
```typescript
|
||
{
|
||
report_dir: string;
|
||
}
|
||
```
|
||
|
||
### Output schema
|
||
|
||
```typescript
|
||
{
|
||
success: boolean;
|
||
buckets: Array<{
|
||
label: string; // e.g. "<5m", "5-15m", "15-60m", ">1h"
|
||
min_minutes: number;
|
||
max_minutes: number;
|
||
count: number;
|
||
avg_profit: number;
|
||
win_rate: number;
|
||
}>;
|
||
correlation: number;
|
||
error?: string;
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## `analyze_layer_performance`
|
||
|
||
Grid/martingale layer analysis from comments.
|
||
|
||
**When to call:** To analyze performance by grid layer (for grid/martingale strategies).
|
||
|
||
### Input schema
|
||
|
||
```typescript
|
||
{
|
||
report_dir: string;
|
||
}
|
||
```
|
||
|
||
### Output schema
|
||
|
||
```typescript
|
||
{
|
||
success: boolean;
|
||
layers: Array<{
|
||
layer: number; // e.g. "L1", "L2", "L3"
|
||
count: number;
|
||
profit: number;
|
||
win_rate: number;
|
||
avg_profit: number;
|
||
}>;
|
||
max_layer: number;
|
||
l5_plus_count: number;
|
||
error?: string;
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## `analyze_volume_vs_profit`
|
||
|
||
Volume correlation + performance by lot size.
|
||
|
||
**When to call:** To analyze relationship between position size and profit.
|
||
|
||
### Input schema
|
||
|
||
```typescript
|
||
{
|
||
report_dir: string;
|
||
}
|
||
```
|
||
|
||
### Output schema
|
||
|
||
```typescript
|
||
{
|
||
success: boolean;
|
||
by_volume: Array<{
|
||
volume: number;
|
||
count: number;
|
||
avg_profit: number;
|
||
win_rate: number;
|
||
}>;
|
||
correlation: number;
|
||
optimal_volume: number;
|
||
error?: string;
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## `analyze_costs`
|
||
|
||
Commission and swap impact on profitability.
|
||
|
||
**When to call:** To understand the impact of trading costs.
|
||
|
||
### Input schema
|
||
|
||
```typescript
|
||
{
|
||
report_dir: string;
|
||
}
|
||
```
|
||
|
||
### Output schema
|
||
|
||
```typescript
|
||
{
|
||
success: boolean;
|
||
costs: {
|
||
total_commission: number;
|
||
total_swap: number;
|
||
total_spread: number;
|
||
avg_commission_per_trade: number;
|
||
avg_swap_per_trade: number;
|
||
};
|
||
cost_impact_pct: number; // Costs as % of gross profit
|
||
error?: string;
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## `analyze_efficiency`
|
||
|
||
Profit per hour/day, annualized return, trade frequency.
|
||
|
||
**When to call:** To measure overall trading efficiency.
|
||
|
||
### Input schema
|
||
|
||
```typescript
|
||
{
|
||
report_dir: string;
|
||
}
|
||
```
|
||
|
||
### Output schema
|
||
|
||
```typescript
|
||
{
|
||
success: boolean;
|
||
efficiency: {
|
||
profit_per_hour: number;
|
||
profit_per_day: number;
|
||
profit_per_trade: number;
|
||
trades_per_day: number;
|
||
annualized_return_pct: number;
|
||
};
|
||
error?: string;
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## Autonomous Loop Pattern
|
||
|
||
The tools are designed to support a fully autonomous experiment → evaluate → promote → optimize loop:
|
||
|
||
```
|
||
1. run_backtest(new_params)
|
||
2. compare_baseline(result, current_production)
|
||
3a. if winner:
|
||
- archive_report(delete_after=true, verdict="winner")
|
||
- promote_to_baseline(notes="...")
|
||
- write_set_file(new_production.set)
|
||
- run_optimization(new_production_set)
|
||
- [wait for user signal]
|
||
- get_optimization_results()
|
||
- set_from_optimization(path=verify.set, params=results[0].params, template=prod.set)
|
||
- verify top result: run_backtest(expert, set_file=verify.set, skip_compile=true)
|
||
- if still beats baseline → goto step 1
|
||
3b. if loser:
|
||
- archive_report(delete_after=true, verdict="loser", notes="root cause")
|
||
- analyze_report(result) → find root cause
|
||
- read_set_file() → inspect current params
|
||
- propose parameter or code change → goto step 1
|
||
```
|
||
|
||
No user confirmation needed between steps 1→2→3. The AI agent drives the full loop; the user monitors and signals when optimization completes (since that runs for hours). Every run is archived before the directory is deleted, so nothing is lost.
|