Add files via upload

This commit is contained in:
FxPouya
2025-12-26 17:20:46 +03:30
committed by GitHub
parent 185ec2ed5d
commit f48570f64c
7 changed files with 1426 additions and 8 deletions
+165 -6
View File
@@ -11,11 +11,12 @@
3. [Exporting Data from MT4/MT5](#exporting-data)
4. [Uploading Data](#uploading-data)
5. [Configuring Strategy Generation](#configuration)
6. [Generating Strategies](#generation)
7. [Viewing Results](#results)
8. [Downloading Strategies](#downloading)
9. [Troubleshooting](#troubleshooting)
10. [Contact Support](#support)
6. [Understanding Monte Carlo Results](#understanding-monte-carlo-results)
7. [Generating Strategies](#generation)
8. [Viewing Results](#results)
9. [Downloading Strategies](#downloading)
10. [Troubleshooting](#troubleshooting)
11. [Contact Support](#support)
---
@@ -154,8 +155,161 @@ Time,Open,High,Low,Close,Tick_Volume,Spread,Real_Volume
- Min Profit Factor: 2.0
- Min Win Rate: 55%
### Monte Carlo Simulation
**What is Monte Carlo Simulation?**
Monte Carlo simulation is a powerful risk analysis tool that tests strategy robustness by randomly shuffling the order of trades thousands of times. This reveals whether your strategy's performance is due to genuine edge or just lucky trade sequencing.
**Why Use Monte Carlo?**
- **Risk Assessment**: Understand the range of possible outcomes
- **Robustness Testing**: Verify strategy works under different conditions
- **Confidence Intervals**: Know the probability of different results
- **Risk of Ruin**: Calculate probability of catastrophic losses
**Settings:**
| Parameter | Default | Range | Description |
|-----------|---------|-------|-------------|
| **Enable Monte Carlo** | Off | On/Off | Activate Monte Carlo analysis |
| **Iterations** | 1,000 | 100-10,000 | Number of random shuffles |
| **Risk of Ruin Threshold** | 20% | 10-50% | Loss threshold for RoR calculation |
**Recommended Settings:**
- **Quick Analysis**: 1,000 iterations (1-2 seconds)
- **Standard Analysis**: 5,000 iterations (3-4 seconds)
- **Thorough Analysis**: 10,000 iterations (6-8 seconds)
**Requirements:**
- Minimum 20 trades for meaningful results
- More trades = more accurate analysis
- Enable before generating strategies
**How to Use:**
1. **Enable Monte Carlo** in configuration section
2. **Set iterations** (1,000 recommended for start)
3. **Generate strategies** as normal
4. **Click "🎲 MC" button** on any strategy card
5. **View professional modal** with:
- Equity distribution histogram
- Risk assessment
- Percentile analysis
- Confidence intervals
---
## 📊 Understanding Monte Carlo Results
### Risk Assessment Banner
The modal displays a color-coded risk assessment:
- **✅ LOW RISK (< 5% RoR)**: Excellent robustness, safe to trade
- **⚠️ MODERATE RISK (5-15% RoR)**: Acceptable, monitor closely
- **❌ HIGH RISK (> 15% RoR)**: High variance, reduce position size
### Key Metrics Explained
**Expected Return**
- Average outcome across all simulations
- More reliable than single backtest result
- Positive value indicates profitable strategy
**Risk of Ruin (RoR)**
- Probability of losing threshold % of capital
- Lower is better (< 5% is excellent)
- Accounts for worst-case scenarios
**Standard Deviation**
- Measure of result variability
- Lower = more consistent
- Higher = more unpredictable
**Percentiles**
| Percentile | Meaning | Use Case |
|------------|---------|----------|
| **5th** | Worst 5% of outcomes | Downside risk assessment |
| **25th** | Below average | Pessimistic scenario |
| **50th (Median)** | Typical outcome | Most likely result |
| **75th** | Above average | Optimistic scenario |
| **95th** | Best 5% of outcomes | Upside potential |
**Confidence Intervals**
- **90% Range**: 90% of outcomes fall within this range
- **50% Range**: 50% of outcomes fall within this range
- Narrower range = more predictable strategy
### Equity Distribution Histogram
The histogram shows the distribution of final equity across all simulations:
**Color Coding:**
- **Red bars**: Worst 5% of outcomes (below 5th percentile)
- **Orange bars**: Below average (5th-25th percentile)
- **Green bars**: Typical range (25th-75th percentile)
- **Teal bars**: Best outcomes (above 75th percentile)
**What to Look For:**
- **Normal distribution**: Bell curve shape is ideal
- **Skewed right**: More upside potential
- **Skewed left**: More downside risk
- **Wide spread**: High variability (risky)
- **Narrow spread**: Consistent results (safer)
### Interpreting Results
**Excellent Strategy:**
- Risk of Ruin < 5%
- 5th percentile is positive
- Narrow confidence intervals
- Normal distribution shape
**Good Strategy:**
- Risk of Ruin 5-10%
- 5th percentile near breakeven
- Moderate confidence intervals
- Slight positive skew
**Risky Strategy:**
- Risk of Ruin > 15%
- 5th percentile is negative
- Wide confidence intervals
- High standard deviation
**Warning Signs:**
- Very wide distribution
- Negative 25th percentile
- High risk of ruin (> 20%)
- Bimodal distribution (two peaks)
### Best Practices
**Before Trading:**
1. Run Monte Carlo on all strategies
2. Only trade strategies with RoR < 10%
3. Check 5th percentile is acceptable
4. Verify normal distribution
**Position Sizing:**
- Low Risk (< 5% RoR): Standard position size
- Moderate Risk (5-15% RoR): Reduce position by 50%
- High Risk (> 15% RoR): Avoid or use micro lots
**Ongoing Monitoring:**
- Re-run Monte Carlo monthly
- Compare live results to MC predictions
- Stop trading if results fall below 5th percentile
- Adjust position size based on actual variance
---
## 🎯 Generating Strategies
### Step 1: Start Generation
@@ -342,6 +496,11 @@ Click "View Details" to see:
- Community support
- Updates and announcements
**Telegram Group**: https://t.me/FxMathQuant
- Community discussions
- Share strategies and results
- Get help from other users
**Website**: https://fxmath.com
- Documentation
- Video tutorials
@@ -438,6 +597,6 @@ Please provide:
**Happy Trading! 🎯**
For support: fxmathsolution@gmail.com | https://t.me/FxMath
For support: fxmathsolution@gmail.com | https://t.me/FxMath | https://t.me/FxMathQuant
© 2025 FxMath Solution. All rights reserved.
+393 -1
View File
@@ -985,4 +985,396 @@ tbody tr:hover {
flex-direction: column;
align-items: stretch;
}
}
}
/* ===================================
Monte Carlo Simulation Styles
=================================== */
/* Monte Carlo Summary Cards */
.mc-summary {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 20px;
margin-bottom: 30px;
}
.mc-stat-card {
background: var(--card-bg);
padding: 20px;
border-radius: 12px;
text-align: center;
border: 1px solid var(--border-color);
transition: transform 0.2s, box-shadow 0.2s;
}
.mc-stat-card:hover {
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}
.mc-stat-card h4 {
font-size: 14px;
color: var(--text-secondary);
margin-bottom: 10px;
text-transform: uppercase;
letter-spacing: 0.5px;
}
.mc-value {
font-size: 2em;
font-weight: 700;
color: var(--accent-color);
margin: 0;
}
/* Risk level colors */
.mc-value.good { color: var(--accent-success); }
.mc-value.warning { color: var(--accent-warning); }
.mc-value.bad { color: var(--accent-danger); }
/* Monte Carlo Histogram */
#mc-histogram {
width: 100%;
height: 300px;
margin: 20px 0;
border-radius: 8px;
}
/* Monte Carlo Statistics Table */
.mc-stats-table {
width: 100%;
border-collapse: collapse;
margin-top: 20px;
background: var(--card-bg);
border-radius: 8px;
overflow: hidden;
}
.mc-stats-table th,
.mc-stats-table td {
padding: 12px 16px;
text-align: left;
border-bottom: 1px solid var(--border-color);
}
.mc-stats-table th {
background: rgba(102, 126, 234, 0.1);
color: var(--text-primary);
font-weight: 600;
font-size: 13px;
text-transform: uppercase;
letter-spacing: 0.5px;
}
.mc-stats-table td {
font-size: 14px;
color: var(--text-secondary);
}
.mc-stats-table tr:last-child td { border-bottom: none; }
.mc-stats-table tr:hover { background: rgba(102, 126, 234, 0.05); }
/* Monte Carlo Tab Content */
#montecarlo-tab { padding: 20px; }
/* Monte Carlo Settings */
#montecarlo-settings { margin-top: 15px; }
#montecarlo-settings label {
display: block;
margin-bottom: 8px;
font-weight: 500;
}
#montecarlo-settings input[type="range"] {
width: 100%;
margin-bottom: 15px;
}
#montecarlo-settings small {
display: block;
margin-top: -10px;
margin-bottom: 15px;
color: var(--text-secondary);
font-size: 12px;
}
/* Responsive Monte Carlo */
@media (max-width: 768px) {
.mc-summary { grid-template-columns: 1fr; }
.mc-value { font-size: 1.5em; }
#mc-histogram { height: 250px; }
}
/* Monte Carlo Button Style */
.btn-info {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
border: none;
padding: 10px 16px;
border-radius: 6px;
cursor: pointer;
font-weight: 600;
font-size: 14px;
transition: all 0.3s ease;
box-shadow: 0 2px 4px rgba(102, 126, 234, 0.3);
}
.btn-info:hover {
transform: translateY(-2px);
box-shadow: 0 4px 8px rgba(102, 126, 234, 0.4);
}
.btn-info:active {
transform: translateY(0);
}
/* ===== MONTE CARLO MODAL STYLES ===== */
/* Monte Carlo Strategy Info */
.mc-strategy-info {
text-align: center;
margin-bottom: 20px;
padding-bottom: 20px;
border-bottom: 1px solid var(--border-color);
}
.mc-strategy-info h3 {
margin: 0 0 5px 0;
color: var(--text-primary);
}
.mc-strategy-info p {
margin: 0;
color: var(--text-secondary);
}
/* Risk Assessment Banner */
.mc-risk-banner {
display: flex;
align-items: center;
gap: 20px;
padding: 20px;
border-radius: 12px;
margin-bottom: 30px;
border: 2px solid;
}
.mc-risk-banner.mc-good {
background: rgba(72, 187, 120, 0.1);
border-color: var(--accent-success);
}
.mc-risk-banner.mc-warning {
background: rgba(237, 137, 54, 0.1);
border-color: var(--accent-warning);
}
.mc-risk-banner.mc-bad {
background: rgba(245, 101, 101, 0.1);
border-color: var(--accent-danger);
}
.mc-risk-icon {
font-size: 48px;
line-height: 1;
}
.mc-risk-content h3 {
margin: 0 0 10px 0;
font-size: 20px;
}
.mc-risk-content p {
margin: 0;
color: var(--text-secondary);
line-height: 1.6;
}
/* Summary Statistics Cards */
.mc-summary {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 20px;
margin-bottom: 30px;
}
.mc-stat-card {
background: var(--card-bg);
padding: 20px;
border-radius: 12px;
text-align: center;
border: 1px solid var(--border-color);
transition: transform 0.2s, box-shadow 0.2s;
}
.mc-stat-card:hover {
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
}
.mc-label {
font-size: 12px;
text-transform: uppercase;
letter-spacing: 0.5px;
color: var(--text-secondary);
margin-bottom: 8px;
}
.mc-value {
font-size: 28px;
font-weight: 700;
margin-bottom: 5px;
color: var(--text-primary);
}
.mc-value.positive {
color: var(--accent-success);
}
.mc-value.negative {
color: var(--accent-danger);
}
.mc-value.mc-good {
color: var(--accent-success);
}
.mc-value.mc-warning {
color: var(--accent-warning);
}
.mc-value.mc-bad {
color: var(--accent-danger);
}
.mc-sublabel {
font-size: 11px;
color: var(--text-muted);
}
/* Percentile Table */
.mc-percentiles {
margin: 30px 0;
}
.mc-percentiles h3 {
margin-bottom: 15px;
}
.mc-percentile-table {
width: 100%;
border-collapse: collapse;
background: var(--card-bg);
border-radius: 8px;
overflow: hidden;
}
.mc-percentile-table thead {
background: rgba(102, 126, 234, 0.1);
}
.mc-percentile-table th,
.mc-percentile-table td {
padding: 12px 15px;
text-align: left;
border-bottom: 1px solid var(--border-color);
}
.mc-percentile-table th {
font-weight: 600;
color: var(--text-primary);
font-size: 13px;
text-transform: uppercase;
letter-spacing: 0.5px;
}
.mc-percentile-table td {
color: var(--text-secondary);
}
.mc-percentile-table tr.highlight-row {
background: rgba(102, 126, 234, 0.05);
}
.mc-percentile-table tr:last-child td {
border-bottom: none;
}
/* Confidence Intervals */
.mc-confidence {
margin: 30px 0;
}
.mc-confidence h3 {
margin-bottom: 15px;
}
.mc-confidence-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 20px;
}
.mc-confidence-card {
background: var(--card-bg);
padding: 20px;
border-radius: 12px;
border: 1px solid var(--border-color);
text-align: center;
}
.mc-confidence-label {
font-size: 13px;
text-transform: uppercase;
letter-spacing: 0.5px;
color: var(--text-secondary);
margin-bottom: 10px;
}
.mc-confidence-value {
font-size: 20px;
font-weight: 700;
color: var(--accent-primary);
margin-bottom: 8px;
}
.mc-confidence-sublabel {
font-size: 12px;
color: var(--text-muted);
}
/* Explanation Box */
.mc-explanation {
background: rgba(102, 126, 234, 0.05);
border-left: 4px solid var(--accent-primary);
padding: 20px;
border-radius: 8px;
margin-top: 30px;
}
.mc-explanation h4 {
margin: 0 0 10px 0;
color: var(--text-primary);
}
.mc-explanation p {
margin: 0;
color: var(--text-secondary);
line-height: 1.6;
}
/* Responsive Design */
@media (max-width: 768px) {
.mc-summary {
grid-template-columns: repeat(2, 1fr);
}
.mc-confidence-grid {
grid-template-columns: 1fr;
}
.mc-risk-banner {
flex-direction: column;
text-align: center;
}
}
+27 -1
View File
@@ -234,6 +234,30 @@
<small>Higher ratio = more data for training, less for validation</small>
</div>
</div>
<!-- Monte Carlo Simulation -->
<div class="config-card">
<h3>🎲 Monte Carlo Simulation</h3>
<div class="form-group">
<label>
<input type="checkbox" id="enable-montecarlo" onchange="toggleMonteCarloSettings()">
Enable Monte Carlo Analysis
</label>
<small>Analyze strategy robustness through trade randomization</small>
</div>
<div class="form-group hidden" id="montecarlo-settings">
<label>Iterations: <span id="mc-iterations-value">1000</span></label>
<input type="range" id="mc-iterations" min="100" max="10000" step="100" value="1000"
oninput="updateMonteCarloSettings()">
<small>Higher iterations = more accurate results (slower)</small>
<label style="margin-top: 15px;">Risk of Ruin Threshold: <span
id="ror-threshold-value">20</span>%</label>
<input type="range" id="ror-threshold" min="10" max="50" step="5" value="20"
oninput="updateMonteCarloSettings()">
<small>Probability of losing this % of capital</small>
</div>
</div>
</div>
<div class="action-buttons">
@@ -323,6 +347,8 @@
<script src="js/strategy.js?v=2.2"></script>
<script src="js/backtester.js"></script>
<script src="js/walk-forward.js"></script>
<script src="js/monte-carlo.js?v=2.7"></script>
<script src="js/monte-carlo-modal.js?v=2.7"></script>
<script src="js/ga-engine.js?v=2.2"></script>
<script src="js/rule-parser.js?v=2.1"></script>
<script src="js/mq4-converter.js?v=2.1"></script>
@@ -335,7 +361,7 @@
<script src="js/strategy-details.js?v=2.1"></script>
<script src="js/html-report-generator.js?v=2.1"></script>
<script src="js/ui-controller.js?v=2.1"></script>
<script src="js/main.js?v=2.1"></script>
<script src="js/main.js?v=2.7"></script>
</body>
</html>
+69
View File
@@ -520,6 +520,7 @@ function createStrategyCard(strategy, number) {
</div>
<div class="strategy-actions">
<button class="btn-secondary" onclick="viewStrategyDetails(${number - 1})">View Details</button>
<button class="btn-info" onclick="runMonteCarloForStrategy(${number - 1})" title="Run Monte Carlo Simulation">🎲 MC</button>
<button class="btn-primary" onclick="downloadStrategy(${number - 1}, 'mq4')">MQ4</button>
<button class="btn-primary" onclick="downloadStrategy(${number - 1}, 'mq5')">MQ5</button>
<button class="btn-success" onclick="downloadStrategy(${number - 1}, 'report')">Report</button>
@@ -803,6 +804,71 @@ function toggleWalkForwardSettings() {
}
}
/**
* Update Monte Carlo settings display
*/
function updateMonteCarloSettings() {
const iterations = parseInt(document.getElementById('mc-iterations').value);
const threshold = parseInt(document.getElementById('ror-threshold').value);
document.getElementById('mc-iterations-value').textContent = iterations.toLocaleString();
document.getElementById('ror-threshold-value').textContent = threshold;
}
/**
* Toggle Monte Carlo settings visibility
*/
function toggleMonteCarloSettings() {
const enabled = document.getElementById('enable-montecarlo').checked;
const settings = document.getElementById('montecarlo-settings');
if (settings) {
settings.classList.toggle('hidden', !enabled);
}
}
/**
* Run Monte Carlo analysis for a specific strategy
*/
function runMonteCarloForStrategy(index) {
const strategy = appData.foundStrategies[index];
if (!strategy) {
alert('Strategy not found!');
return;
}
const mcEnabled = document.getElementById('enable-montecarlo')?.checked;
if (!mcEnabled) {
alert('Monte Carlo is not enabled!\\n\\nPlease enable it in the settings before generating strategies.');
return;
}
const m = strategy.metrics;
if (!m.trades || m.trades.length < 20) {
alert(`Monte Carlo requires at least 20 trades.\\nThis strategy has ${m.trades?.length || 0} trades.`);
return;
}
try {
const iterations = parseInt(document.getElementById('mc-iterations').value) || 1000;
const rorThreshold = parseInt(document.getElementById('ror-threshold').value) / 100 || 0.2;
console.log(`🎲 Running Monte Carlo analysis (${iterations} iterations)...`);
const trades = MonteCarloSimulation.extractTrades(strategy);
const mc = new MonteCarloSimulation(trades, iterations, rorThreshold);
const results = mc.run();
strategy.monteCarlo = results;
// Display results in professional modal with Chart.js visualization
displayMonteCarloModal(strategy, index, results);
} catch (error) {
console.error('Monte Carlo error:', error);
alert(`Monte Carlo analysis failed: ${error.message}`);
}
}
// Explicitly expose functions to global scope for inline onclick handlers
window.downloadStrategy = downloadStrategy;
window.downloadAllStrategies = downloadAllStrategies;
@@ -810,5 +876,8 @@ window.toggleStrategySelection = toggleStrategySelection;
window.showComparison = showComparison;
window.updateTrainingSplit = updateTrainingSplit;
window.toggleWalkForwardSettings = toggleWalkForwardSettings;
window.updateMonteCarloSettings = updateMonteCarloSettings;
window.toggleMonteCarloSettings = toggleMonteCarloSettings;
window.runMonteCarloForStrategy = runMonteCarloForStrategy;
window.hideComparison = hideComparison;
window.toggleCustomBarsInput = toggleCustomBarsInput;
+338
View File
@@ -0,0 +1,338 @@
/**
* Display Monte Carlo results in a professional modal with Chart.js visualization
*/
function displayMonteCarloModal(strategy, index, results) {
const m = strategy.metrics;
const stats = results.statistics.equity;
const expectedReturn = ((stats.mean - 10000) / 10000 * 100);
// Determine risk level
let riskLevel, riskClass, riskEmoji, riskMessage;
if (results.riskOfRuin < 5) {
riskLevel = 'LOW RISK';
riskClass = 'good';
riskEmoji = '✅';
riskMessage = 'Excellent robustness. This strategy shows consistent performance across different trade sequences. Safe to trade!';
} else if (results.riskOfRuin < 15) {
riskLevel = 'MODERATE RISK';
riskClass = 'warning';
riskEmoji = '⚠️';
riskMessage = 'Acceptable but monitor closely. Strategy has some variability. Consider reducing position size or using tighter risk management.';
} else {
riskLevel = 'HIGH RISK';
riskClass = 'bad';
riskEmoji = '❌';
riskMessage = 'High variance. Strategy shows significant variability in outcomes. Consider avoiding or significantly reducing position size.';
}
// Create modal if it doesn't exist
let modal = document.getElementById('montecarlo-modal');
if (!modal) {
modal = document.createElement('div');
modal.id = 'montecarlo-modal';
modal.className = 'modal';
document.body.appendChild(modal);
}
modal.innerHTML = `
<div class="modal-content" style="max-width: 1200px;">
<div class="modal-header">
<h2>🎲 Monte Carlo Simulation Results</h2>
<button class="modal-close" onclick="closeMonteCarloModal()">&times;</button>
</div>
<div class="modal-body">
<!-- Strategy Info -->
<div class="mc-strategy-info">
<h3>Strategy #${index + 1}</h3>
<p>PF: ${m.profitFactor.toFixed(2)} | WR: ${m.winRate.toFixed(1)}% | Trades: ${m.totalTrades}</p>
</div>
<!-- Risk Assessment Banner -->
<div class="mc-risk-banner mc-${riskClass}">
<div class="mc-risk-icon">${riskEmoji}</div>
<div class="mc-risk-content">
<h3>${riskLevel}</h3>
<p>${riskMessage}</p>
</div>
</div>
<!-- Summary Statistics -->
<div class="mc-summary">
<div class="mc-stat-card">
<div class="mc-label">Expected Return</div>
<div class="mc-value ${expectedReturn >= 0 ? 'positive' : 'negative'}">
${expectedReturn > 0 ? '+' : ''}${expectedReturn.toFixed(2)}%
</div>
<div class="mc-sublabel">Mean final equity</div>
</div>
<div class="mc-stat-card">
<div class="mc-label">Risk of Ruin</div>
<div class="mc-value mc-${riskClass}">${results.riskOfRuin.toFixed(2)}%</div>
<div class="mc-sublabel">Probability of ${(results.rorThreshold * 100).toFixed(0)}% loss</div>
</div>
<div class="mc-stat-card">
<div class="mc-label">Iterations</div>
<div class="mc-value">${results.iterations.toLocaleString()}</div>
<div class="mc-sublabel">Completed in ${results.executionTime.toFixed(0)}ms</div>
</div>
<div class="mc-stat-card">
<div class="mc-label">Std Deviation</div>
<div class="mc-value">$${stats.stdDev.toFixed(2)}</div>
<div class="mc-sublabel">Variability measure</div>
</div>
</div>
<!-- Equity Distribution Histogram -->
<div class="chart-section">
<h3>Equity Distribution</h3>
<p style="color: #a0aec0; margin-bottom: 15px;">
Distribution of final equity across ${results.iterations.toLocaleString()} randomized trade sequences
</p>
<canvas id="mc-histogram" style="max-height: 300px;"></canvas>
</div>
<!-- Percentile Statistics -->
<div class="mc-percentiles">
<h3>Percentile Analysis</h3>
<table class="mc-percentile-table">
<thead>
<tr>
<th>Percentile</th>
<th>Final Equity</th>
<th>Return</th>
<th>Interpretation</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>5th (Worst 5%)</strong></td>
<td>$${stats.percentile5.toFixed(2)}</td>
<td class="${((stats.percentile5 - 10000) / 10000 * 100) >= 0 ? 'positive' : 'negative'}">
${((stats.percentile5 - 10000) / 10000 * 100) > 0 ? '+' : ''}${((stats.percentile5 - 10000) / 10000 * 100).toFixed(2)}%
</td>
<td>Downside risk scenario</td>
</tr>
<tr>
<td><strong>25th</strong></td>
<td>$${stats.percentile25.toFixed(2)}</td>
<td class="${((stats.percentile25 - 10000) / 10000 * 100) >= 0 ? 'positive' : 'negative'}">
${((stats.percentile25 - 10000) / 10000 * 100) > 0 ? '+' : ''}${((stats.percentile25 - 10000) / 10000 * 100).toFixed(2)}%
</td>
<td>Below average outcome</td>
</tr>
<tr class="highlight-row">
<td><strong>50th (Median)</strong></td>
<td>$${stats.percentile50.toFixed(2)}</td>
<td class="${((stats.percentile50 - 10000) / 10000 * 100) >= 0 ? 'positive' : 'negative'}">
${((stats.percentile50 - 10000) / 10000 * 100) > 0 ? '+' : ''}${((stats.percentile50 - 10000) / 10000 * 100).toFixed(2)}%
</td>
<td>Typical outcome</td>
</tr>
<tr>
<td><strong>75th</strong></td>
<td>$${stats.percentile75.toFixed(2)}</td>
<td class="${((stats.percentile75 - 10000) / 10000 * 100) >= 0 ? 'positive' : 'negative'}">
${((stats.percentile75 - 10000) / 10000 * 100) > 0 ? '+' : ''}${((stats.percentile75 - 10000) / 10000 * 100).toFixed(2)}%
</td>
<td>Above average outcome</td>
</tr>
<tr>
<td><strong>95th (Best 5%)</strong></td>
<td>$${stats.percentile95.toFixed(2)}</td>
<td class="${((stats.percentile95 - 10000) / 10000 * 100) >= 0 ? 'positive' : 'negative'}">
${((stats.percentile95 - 10000) / 10000 * 100) > 0 ? '+' : ''}${((stats.percentile95 - 10000) / 10000 * 100).toFixed(2)}%
</td>
<td>Upside potential</td>
</tr>
</tbody>
</table>
</div>
<!-- Confidence Intervals -->
<div class="mc-confidence">
<h3>Confidence Intervals</h3>
<div class="mc-confidence-grid">
<div class="mc-confidence-card">
<div class="mc-confidence-label">90% Confidence Range</div>
<div class="mc-confidence-value">
$${results.confidence.range90.lower.toFixed(2)} - $${results.confidence.range90.upper.toFixed(2)}
</div>
<div class="mc-confidence-sublabel">90% of outcomes fall within this range</div>
</div>
<div class="mc-confidence-card">
<div class="mc-confidence-label">50% Confidence Range</div>
<div class="mc-confidence-value">
$${results.confidence.range50.lower.toFixed(2)} - $${results.confidence.range50.upper.toFixed(2)}
</div>
<div class="mc-confidence-sublabel">50% of outcomes fall within this range</div>
</div>
</div>
</div>
<!-- Explanation -->
<div class="mc-explanation">
<h4>📖 What is Monte Carlo Simulation?</h4>
<p>
Monte Carlo simulation tests strategy robustness by randomly shuffling the order of trades
${results.iterations.toLocaleString()} times. This shows how the strategy would perform under
different market conditions and helps identify if good results are due to luck or genuine edge.
</p>
<p style="margin-top: 10px;">
<strong>Key Insight:</strong> A robust strategy should show consistent positive returns across
most simulations, with low risk of ruin and tight confidence intervals.
</p>
</div>
</div>
</div>
`;
modal.style.display = 'flex';
// Draw histogram after modal is visible
setTimeout(() => {
drawMonteCarloHistogram(results, stats);
}, 100);
}
/**
* Draw Monte Carlo histogram using Chart.js
*/
function drawMonteCarloHistogram(results, stats) {
const canvas = document.getElementById('mc-histogram');
if (!canvas) return;
const ctx = canvas.getContext('2d');
// Create histogram bins
const numBins = 30;
const min = Math.min(...results.distribution);
const max = Math.max(...results.distribution);
const binWidth = (max - min) / numBins;
const bins = new Array(numBins).fill(0);
const binLabels = [];
for (let i = 0; i < numBins; i++) {
binLabels.push((min + i * binWidth).toFixed(0));
}
// Fill bins
results.distribution.forEach(value => {
const binIndex = Math.min(Math.floor((value - min) / binWidth), numBins - 1);
bins[binIndex]++;
});
// Create gradient colors based on value
const backgroundColors = bins.map((_, i) => {
const value = min + (i + 0.5) * binWidth;
if (value < stats.percentile5) return 'rgba(245, 101, 101, 0.7)'; // Red for worst 5%
if (value < stats.percentile25) return 'rgba(237, 137, 54, 0.7)'; // Orange
if (value < stats.percentile75) return 'rgba(72, 187, 120, 0.7)'; // Green
return 'rgba(56, 178, 172, 0.7)'; // Teal for best 25%
});
new Chart(ctx, {
type: 'bar',
data: {
labels: binLabels,
datasets: [{
label: 'Frequency',
data: bins,
backgroundColor: backgroundColors,
borderColor: backgroundColors.map(c => c.replace('0.7', '1')),
borderWidth: 1
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: { display: false },
tooltip: {
backgroundColor: '#1a1f3a',
titleColor: '#fff',
bodyColor: '#a0aec0',
borderColor: '#2d3748',
borderWidth: 1,
callbacks: {
title: function (context) {
const binStart = parseFloat(context[0].label);
const binEnd = binStart + binWidth;
return `$${binStart.toFixed(0)} - $${binEnd.toFixed(0)}`;
},
label: function (context) {
const percentage = (context.parsed.y / results.iterations * 100).toFixed(1);
return `${context.parsed.y} outcomes (${percentage}%)`;
}
}
},
annotation: {
annotations: {
meanLine: {
type: 'line',
xMin: ((stats.mean - min) / binWidth),
xMax: ((stats.mean - min) / binWidth),
borderColor: '#667eea',
borderWidth: 2,
borderDash: [5, 5],
label: {
content: 'Mean',
enabled: true,
position: 'top'
}
}
}
}
},
scales: {
y: {
beginAtZero: true,
grid: { color: '#2d3748' },
ticks: { color: '#a0aec0' },
title: {
display: true,
text: 'Frequency',
color: '#a0aec0'
}
},
x: {
grid: { display: false },
ticks: {
color: '#a0aec0',
maxRotation: 45,
minRotation: 45,
autoSkip: true,
maxTicksLimit: 10
},
title: {
display: true,
text: 'Final Equity ($)',
color: '#a0aec0'
}
}
}
}
});
}
/**
* Close Monte Carlo modal
*/
function closeMonteCarloModal() {
const modal = document.getElementById('montecarlo-modal');
if (modal) {
modal.style.display = 'none';
}
}
// Close modal when clicking outside
window.addEventListener('click', function (event) {
const modal = document.getElementById('montecarlo-modal');
if (event.target === modal) {
closeMonteCarloModal();
}
});
// Expose functions globally
window.displayMonteCarloModal = displayMonteCarloModal;
window.closeMonteCarloModal = closeMonteCarloModal;
+275
View File
@@ -0,0 +1,275 @@
/**
* Monte Carlo Simulation - Analyzes strategy robustness through trade randomization
*
* This module shuffles trade sequences thousands of times to calculate:
* - Distribution of possible outcomes
* - Confidence intervals (5th-95th percentile)
* - Risk of ruin probability
* - Expected vs worst-case scenarios
*/
class MonteCarloSimulation {
constructor(trades, iterations = 1000, rorThreshold = 0.2) {
this.trades = trades; // Array of trade objects with profit/loss
this.iterations = iterations;
this.rorThreshold = rorThreshold; // Risk of ruin threshold (default 20%)
this.startingEquity = 10000;
}
/**
* Run the full Monte Carlo simulation
* @returns {Object} Statistical results
*/
run() {
console.log(`🎲 Running Monte Carlo simulation (${this.iterations} iterations)...`);
const startTime = performance.now();
const results = [];
for (let i = 0; i < this.iterations; i++) {
const shuffled = this.shuffleTrades();
const equity = this.calculateEquityCurve(shuffled);
results.push({
finalEquity: equity[equity.length - 1],
maxEquity: Math.max(...equity),
minEquity: Math.min(...equity),
maxDrawdown: this.calculateMaxDrawdown(equity),
equityCurve: equity
});
}
const statistics = this.calculateStatistics(results);
const endTime = performance.now();
console.log(`✅ Monte Carlo complete in ${(endTime - startTime).toFixed(0)}ms`);
return {
iterations: this.iterations,
statistics,
distribution: results.map(r => r.finalEquity),
drawdownDistribution: results.map(r => r.maxDrawdown),
riskOfRuin: this.calculateRiskOfRuin(results),
confidence: this.calculateConfidenceIntervals(results),
executionTime: endTime - startTime
};
}
/**
* Shuffle trades using Fisher-Yates algorithm
* @returns {Array} Shuffled copy of trades
*/
shuffleTrades() {
const shuffled = [...this.trades];
for (let i = shuffled.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[shuffled[i], shuffled[j]] = [shuffled[j], shuffled[i]];
}
return shuffled;
}
/**
* Calculate equity curve for a sequence of trades
* @param {Array} trades - Ordered array of trades
* @returns {Array} Equity values over time
*/
calculateEquityCurve(trades) {
const equity = [this.startingEquity];
let currentEquity = this.startingEquity;
for (const trade of trades) {
currentEquity += trade.profit;
equity.push(currentEquity);
}
return equity;
}
/**
* Calculate maximum drawdown from equity curve
* @param {Array} equity - Equity curve
* @returns {Number} Max drawdown percentage
*/
calculateMaxDrawdown(equity) {
let maxEquity = equity[0];
let maxDD = 0;
for (const value of equity) {
if (value > maxEquity) {
maxEquity = value;
}
const drawdown = ((maxEquity - value) / maxEquity) * 100;
if (drawdown > maxDD) {
maxDD = drawdown;
}
}
return maxDD;
}
/**
* Calculate comprehensive statistics from results
* @param {Array} results - Array of simulation results
* @returns {Object} Statistical measures
*/
calculateStatistics(results) {
const finalEquities = results.map(r => r.finalEquity);
const drawdowns = results.map(r => r.maxDrawdown);
return {
equity: {
mean: this.mean(finalEquities),
median: this.median(finalEquities),
stdDev: this.standardDeviation(finalEquities),
min: Math.min(...finalEquities),
max: Math.max(...finalEquities),
percentile5: this.getPercentile(finalEquities, 5),
percentile25: this.getPercentile(finalEquities, 25),
percentile50: this.getPercentile(finalEquities, 50),
percentile75: this.getPercentile(finalEquities, 75),
percentile95: this.getPercentile(finalEquities, 95)
},
drawdown: {
mean: this.mean(drawdowns),
median: this.median(drawdowns),
stdDev: this.standardDeviation(drawdowns),
min: Math.min(...drawdowns),
max: Math.max(...drawdowns),
percentile5: this.getPercentile(drawdowns, 5),
percentile95: this.getPercentile(drawdowns, 95)
}
};
}
/**
* Calculate risk of ruin (probability of losing X% of capital)
* @param {Array} results - Simulation results
* @returns {Number} Risk of ruin percentage
*/
calculateRiskOfRuin(results) {
const ruinEquity = this.startingEquity * (1 - this.rorThreshold);
const ruinCount = results.filter(r => r.minEquity <= ruinEquity).length;
return (ruinCount / results.length) * 100;
}
/**
* Calculate confidence intervals
* @param {Array} results - Simulation results
* @returns {Object} Confidence interval data
*/
calculateConfidenceIntervals(results) {
const finalEquities = results.map(r => r.finalEquity);
return {
range90: {
lower: this.getPercentile(finalEquities, 5),
upper: this.getPercentile(finalEquities, 95)
},
range50: {
lower: this.getPercentile(finalEquities, 25),
upper: this.getPercentile(finalEquities, 75)
}
};
}
/**
* Calculate mean (average)
* @param {Array} data - Numeric array
* @returns {Number} Mean value
*/
mean(data) {
return data.reduce((sum, val) => sum + val, 0) / data.length;
}
/**
* Calculate median (50th percentile)
* @param {Array} data - Numeric array
* @returns {Number} Median value
*/
median(data) {
return this.getPercentile(data, 50);
}
/**
* Calculate standard deviation
* @param {Array} data - Numeric array
* @returns {Number} Standard deviation
*/
standardDeviation(data) {
const avg = this.mean(data);
const squareDiffs = data.map(value => Math.pow(value - avg, 2));
const avgSquareDiff = this.mean(squareDiffs);
return Math.sqrt(avgSquareDiff);
}
/**
* Calculate percentile value
* @param {Array} data - Numeric array
* @param {Number} percentile - Percentile to calculate (0-100)
* @returns {Number} Percentile value
*/
getPercentile(data, percentile) {
const sorted = [...data].sort((a, b) => a - b);
const index = (percentile / 100) * (sorted.length - 1);
const lower = Math.floor(index);
const upper = Math.ceil(index);
const weight = index - lower;
if (lower === upper) {
return sorted[lower];
}
return sorted[lower] * (1 - weight) + sorted[upper] * weight;
}
/**
* Generate summary text for results
* @param {Object} results - Monte Carlo results
* @returns {String} Human-readable summary
*/
static generateSummary(results) {
const { statistics, riskOfRuin, confidence } = results;
const expectedReturn = ((statistics.equity.mean - 10000) / 10000 * 100).toFixed(2);
let summary = `Monte Carlo Analysis (${results.iterations} iterations):\n\n`;
summary += `Expected Return: ${expectedReturn}%\n`;
summary += `90% Confidence Range: $${confidence.range90.lower.toFixed(2)} - $${confidence.range90.upper.toFixed(2)}\n`;
summary += `Risk of Ruin (${(results.rorThreshold * 100)}%): ${riskOfRuin.toFixed(2)}%\n\n`;
if (riskOfRuin < 5) {
summary += `✅ Low risk - Strategy shows good robustness`;
} else if (riskOfRuin < 15) {
summary += `⚠️ Moderate risk - Acceptable but monitor closely`;
} else {
summary += `❌ High risk - Consider reducing position size or avoiding`;
}
return summary;
}
/**
* Extract trades from strategy backtest results
* @param {Object} strategy - Strategy with metrics
* @returns {Array} Array of trade objects
*/
static extractTrades(strategy) {
if (!strategy.metrics || !strategy.metrics.trades) {
throw new Error('Strategy must have backtest results with trades');
}
return strategy.metrics.trades.map(trade => ({
profit: trade.profit,
type: trade.type,
entry: trade.entry,
exit: trade.exit
}));
}
}
// Export for use in other modules
if (typeof module !== 'undefined' && module.exports) {
module.exports = MonteCarloSimulation;
}
+159
View File
@@ -192,6 +192,7 @@
<li><a href="#upload">Uploading Data</a></li>
<li><a href="#config">Configuring Strategy Generation</a></li>
<li><a href="#walkforward">Walk-Forward Analysis</a></li>
<li><a href="#montecarlo">Monte Carlo Simulation</a></li>
<li><a href="#generate">Generating Strategies</a></li>
<li><a href="#results">Viewing Results</a></li>
<li><a href="#download">Downloading Strategies</a></li>
@@ -435,6 +436,162 @@
<li><strong>Result:</strong> GA naturally evolves toward robust, non-overfitted strategies</li>
</ul>
<h3 id="montecarlo">🎲 Monte Carlo Simulation</h3>
<p>Monte Carlo simulation is a powerful risk analysis tool that tests strategy robustness by randomly shuffling
the order of trades thousands of times.</p>
<div class="alert alert-info">
<strong>Why Use Monte Carlo?</strong> It reveals whether your strategy's performance is due to genuine edge
or just lucky trade sequencing. A robust strategy should show consistent positive returns across most
simulations.
</div>
<h4>How It Works</h4>
<ol>
<li><strong>Trade Extraction:</strong> All trades from the backtest are collected</li>
<li><strong>Random Shuffling:</strong> Trades are randomly reordered (Fisher-Yates algorithm)</li>
<li><strong>Equity Calculation:</strong> Account balance is recalculated for each shuffle</li>
<li><strong>Statistical Analysis:</strong> Results are analyzed across thousands of iterations</li>
<li><strong>Risk Assessment:</strong> Probability distributions and risk metrics are calculated</li>
</ol>
<h4>Configuration</h4>
<table>
<thead>
<tr>
<th>Parameter</th>
<th>Default</th>
<th>Range</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>Enable Monte Carlo</td>
<td>Off</td>
<td>On/Off</td>
<td>Activate Monte Carlo analysis</td>
</tr>
<tr>
<td>Iterations</td>
<td>1,000</td>
<td>100-10,000</td>
<td>Number of random shuffles</td>
</tr>
<tr>
<td>Risk of Ruin Threshold</td>
<td>20%</td>
<td>10-50%</td>
<td>Loss threshold for RoR calculation</td>
</tr>
</tbody>
</table>
<h4>Recommended Settings</h4>
<ul>
<li><strong>Quick Analysis:</strong> 1,000 iterations (1-2 seconds)</li>
<li><strong>Standard Analysis:</strong> 5,000 iterations (3-4 seconds)</li>
<li><strong>Thorough Analysis:</strong> 10,000 iterations (6-8 seconds)</li>
</ul>
<h4>Requirements</h4>
<ul>
<li>Minimum 20 trades for meaningful results</li>
<li>More trades = more accurate analysis</li>
<li>Enable before generating strategies</li>
</ul>
<h4>Understanding the Results</h4>
<p>When you click the "🎲 MC" button on a strategy card, a professional modal displays:</p>
<h5>Risk Assessment Banner</h5>
<table>
<thead>
<tr>
<th>Risk Level</th>
<th>RoR Range</th>
<th>Meaning</th>
<th>Recommendation</th>
</tr>
</thead>
<tbody>
<tr>
<td>✅ LOW RISK</td>
<td>&lt; 5%</td>
<td>Excellent robustness</td>
<td>Safe to trade</td>
</tr>
<tr>
<td>⚠️ MODERATE RISK</td>
<td>5-15%</td>
<td>Acceptable variability</td>
<td>Monitor closely</td>
</tr>
<tr>
<td>❌ HIGH RISK</td>
<td>&gt; 15%</td>
<td>High variance</td>
<td>Reduce position size</td>
</tr>
</tbody>
</table>
<h5>Key Metrics</h5>
<ul>
<li><strong>Expected Return:</strong> Average outcome across all simulations (more reliable than single
backtest)</li>
<li><strong>Risk of Ruin:</strong> Probability of losing threshold % of capital (lower is better)</li>
<li><strong>Standard Deviation:</strong> Measure of result variability (lower = more consistent)</li>
<li><strong>Percentiles:</strong> Distribution of outcomes (5th, 25th, 50th, 75th, 95th)</li>
<li><strong>Confidence Intervals:</strong> Range where 90% or 50% of outcomes fall</li>
</ul>
<h5>Equity Distribution Histogram</h5>
<p>The histogram shows the distribution of final equity with color-coded bars:</p>
<ul>
<li><strong style="color: #f56565;">Red bars:</strong> Worst 5% of outcomes (below 5th percentile)</li>
<li><strong style="color: #ed8936;">Orange bars:</strong> Below average (5th-25th percentile)</li>
<li><strong style="color: #48bb78;">Green bars:</strong> Typical range (25th-75th percentile)</li>
<li><strong style="color: #38b2ac;">Teal bars:</strong> Best outcomes (above 75th percentile)</li>
</ul>
<h5>What to Look For</h5>
<ul>
<li><strong>Normal distribution:</strong> Bell curve shape is ideal</li>
<li><strong>Narrow spread:</strong> Consistent results (safer)</li>
<li><strong>Positive 5th percentile:</strong> Even worst case is profitable</li>
<li><strong>Low RoR:</strong> Less than 10% is good, less than 5% is excellent</li>
</ul>
<div class="alert alert-warning">
<strong>Warning Signs:</strong> Very wide distribution, negative 25th percentile, high risk of ruin (&gt;
20%), or bimodal distribution (two peaks) indicate a risky strategy.
</div>
<h4>Best Practices</h4>
<h5>Before Trading:</h5>
<ul>
<li>Run Monte Carlo on all strategies</li>
<li>Only trade strategies with RoR &lt; 10%</li>
<li>Check 5th percentile is acceptable</li>
<li>Verify normal distribution shape</li>
</ul>
<h5>Position Sizing:</h5>
<ul>
<li><strong>Low Risk (&lt; 5% RoR):</strong> Standard position size</li>
<li><strong>Moderate Risk (5-15% RoR):</strong> Reduce position by 50%</li>
<li><strong>High Risk (&gt; 15% RoR):</strong> Avoid or use micro lots</li>
</ul>
<h5>Ongoing Monitoring:</h5>
<ul>
<li>Re-run Monte Carlo monthly with fresh data</li>
<li>Compare live results to MC predictions</li>
<li>Stop trading if results fall below 5th percentile</li>
<li>Adjust position size based on actual variance</li>
</ul>
<h2 id="generate">🎯 Generating Strategies</h2>
<ol>
<li>Review your settings</li>
@@ -500,6 +657,8 @@
<h3>Get Help</h3>
<p><strong>📧 Email:</strong> <a href="mailto:fxmathsolution@gmail.com">fxmathsolution@gmail.com</a></p>
<p><strong>💬 Telegram:</strong> <a href="https://t.me/FxMath" target="_blank">https://t.me/FxMath</a></p>
<p><strong>👥 Telegram Group:</strong> <a href="https://t.me/FxMathQuant"
target="_blank">https://t.me/FxMathQuant</a></p>
<p style="margin-top: 15px; font-size: 0.9em;">Response time: 24-48 hours via email, faster on Telegram</p>
</div>