mirror of
https://github.com/chrisnov-it/quantumbotx.git
synced 2026-07-27 18:57:47 +00:00
b1b92d363a
✨ CORE ENHANCEMENTS: • Beginner-friendly strategy system with educational framework • ATR-based dynamic risk management with market-adaptive position sizing • Multi-broker support with automatic symbol migration (XM Global optimized) • Advanced crypto trading strategies (SatoshiJakarta & QuantumCrypto bots) • Ultra-conservative XAUUSD protection system preventing account blowouts 🛡️ SAFETY & RISK MANAGEMENT: • Dynamic position sizing based on market volatility (ATR) • Emergency brake system for dangerous trades • Progressive learning path for beginners (Week 1-6 curriculum) • Strategy complexity ratings (2-12 scale) with difficulty-based recommendations • Special gold trading protection with fixed lot sizes 🎓 EDUCATIONAL FEATURES: • Strategy selector with automatic recommendations by experience level • Parameter validation with beginner-safe warnings • Educational explanations for every trading parameter • Market-specific strategy suggestions (FOREX vs GOLD vs CRYPTO) • Complete learning framework from beginner to expert 🔧 TECHNICAL IMPROVEMENTS: • Enhanced backtesting engine with comprehensive history tracking • Quiet logging system (user preference for clean terminal output) • Robust error handling and Windows compatibility fixes • Multi-timeframe analysis support across all strategies • Real-time market data integration with broker detection 📊 NEW STRATEGIES: • QuantumBotX Crypto: Bitcoin-optimized with weekend trading mode • Enhanced Hybrid: Auto-detects crypto vs forex for optimal parameters • Beginner-friendly MA Crossover with educational defaults • Advanced multi-indicator strategies (Mercy Edge, Pulse Sync) 🌐 PLATFORM EXPANSION: • Indonesian market integration planning (XM Indonesia support) • Multi-broker architecture foundation (cTrader, Interactive Brokers) • Comprehensive testing suite with 15+ validation scripts • Professional documentation and troubleshooting guides 📈 BETA READINESS: • Production-grade stability with 4 concurrent trading bots • Professional UI/UX with real-time performance tracking • Comprehensive error handling and user guidance • Windows-optimized deployment with MT5 integration Score: 10/10 Production Ready! 🏆
741 lines
28 KiB
HTML
741 lines
28 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>Backtesting Analyzer - Trading Bot Analysis</title>
|
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.9.1/chart.min.js"></script>
|
|
<style>
|
|
* {
|
|
margin: 0;
|
|
padding: 0;
|
|
box-sizing: border-box;
|
|
}
|
|
|
|
body {
|
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
background: linear-gradient(135deg, #1e3c72 0%, #2a5298 100%);
|
|
min-height: 100vh;
|
|
padding: 20px;
|
|
}
|
|
|
|
.container {
|
|
max-width: 1200px;
|
|
margin: 0 auto;
|
|
background: white;
|
|
border-radius: 20px;
|
|
box-shadow: 0 20px 40px rgba(0,0,0,0.1);
|
|
overflow: hidden;
|
|
}
|
|
|
|
.header {
|
|
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
color: white;
|
|
padding: 30px;
|
|
text-align: center;
|
|
}
|
|
|
|
.header h1 {
|
|
font-size: 2.5rem;
|
|
margin-bottom: 10px;
|
|
text-shadow: 0 2px 4px rgba(0,0,0,0.3);
|
|
}
|
|
|
|
.header p {
|
|
opacity: 0.9;
|
|
font-size: 1.1rem;
|
|
}
|
|
|
|
.controls {
|
|
padding: 30px;
|
|
background: #f8f9fa;
|
|
border-bottom: 1px solid #e9ecef;
|
|
}
|
|
|
|
.btn {
|
|
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
color: white;
|
|
border: none;
|
|
padding: 15px 30px;
|
|
border-radius: 50px;
|
|
cursor: pointer;
|
|
font-size: 1rem;
|
|
font-weight: 600;
|
|
transition: all 0.3s ease;
|
|
box-shadow: 0 4px 15px rgba(0,0,0,0.2);
|
|
}
|
|
|
|
.btn:hover {
|
|
transform: translateY(-2px);
|
|
box-shadow: 0 6px 20px rgba(0,0,0,0.3);
|
|
}
|
|
|
|
.btn:disabled {
|
|
opacity: 0.6;
|
|
cursor: not-allowed;
|
|
transform: none;
|
|
}
|
|
|
|
.results {
|
|
padding: 30px;
|
|
}
|
|
|
|
.issues-grid {
|
|
display: grid;
|
|
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
|
|
gap: 20px;
|
|
margin-bottom: 30px;
|
|
}
|
|
|
|
.issue-card {
|
|
border-radius: 15px;
|
|
padding: 20px;
|
|
box-shadow: 0 4px 15px rgba(0,0,0,0.1);
|
|
border-left: 5px solid;
|
|
}
|
|
|
|
.issue-critical {
|
|
background: #fff5f5;
|
|
border-color: #e53e3e;
|
|
color: #c53030;
|
|
}
|
|
|
|
.issue-error {
|
|
background: #fffaf0;
|
|
border-color: #dd6b20;
|
|
color: #c05621;
|
|
}
|
|
|
|
.issue-warning {
|
|
background: #fffff0;
|
|
border-color: #d69e2e;
|
|
color: #b7791f;
|
|
}
|
|
|
|
.issue-info {
|
|
background: #f0f9ff;
|
|
border-color: #3182ce;
|
|
color: #2c5282;
|
|
}
|
|
|
|
.issue-title {
|
|
font-weight: 700;
|
|
font-size: 1.1rem;
|
|
margin-bottom: 8px;
|
|
}
|
|
|
|
.issue-category {
|
|
background: rgba(0,0,0,0.1);
|
|
padding: 4px 8px;
|
|
border-radius: 20px;
|
|
font-size: 0.8rem;
|
|
display: inline-block;
|
|
margin-bottom: 10px;
|
|
}
|
|
|
|
.issue-description {
|
|
margin-bottom: 10px;
|
|
line-height: 1.5;
|
|
}
|
|
|
|
.issue-impact {
|
|
font-weight: 600;
|
|
margin-bottom: 8px;
|
|
}
|
|
|
|
.issue-solution {
|
|
background: rgba(255,255,255,0.8);
|
|
padding: 10px;
|
|
border-radius: 8px;
|
|
font-size: 0.9rem;
|
|
}
|
|
|
|
.atr-section {
|
|
background: #f8f9fa;
|
|
border-radius: 15px;
|
|
padding: 25px;
|
|
margin-top: 30px;
|
|
}
|
|
|
|
.atr-title {
|
|
font-size: 1.5rem;
|
|
font-weight: 700;
|
|
margin-bottom: 20px;
|
|
color: #2d3748;
|
|
}
|
|
|
|
.chart-container {
|
|
position: relative;
|
|
height: 400px;
|
|
margin-bottom: 20px;
|
|
}
|
|
|
|
.atr-stats {
|
|
display: grid;
|
|
grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
|
|
gap: 15px;
|
|
margin-top: 20px;
|
|
}
|
|
|
|
.stat-card {
|
|
background: white;
|
|
padding: 15px;
|
|
border-radius: 10px;
|
|
text-align: center;
|
|
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
|
|
}
|
|
|
|
.stat-value {
|
|
font-size: 1.5rem;
|
|
font-weight: 700;
|
|
color: #667eea;
|
|
}
|
|
|
|
.stat-label {
|
|
color: #6b7280;
|
|
font-size: 0.9rem;
|
|
}
|
|
|
|
.loading {
|
|
text-align: center;
|
|
padding: 40px;
|
|
}
|
|
|
|
.spinner {
|
|
border: 4px solid #f3f4f6;
|
|
border-top: 4px solid #667eea;
|
|
border-radius: 50%;
|
|
width: 40px;
|
|
height: 40px;
|
|
animation: spin 1s linear infinite;
|
|
margin: 0 auto 20px;
|
|
}
|
|
|
|
@keyframes spin {
|
|
0% { transform: rotate(0deg); }
|
|
100% { transform: rotate(360deg); }
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div class="container">
|
|
<div class="header">
|
|
<h1>🤖 Backtesting Analyzer</h1>
|
|
<p>Analisis sistem ATR-based trading bot untuk XAUUSD</p>
|
|
</div>
|
|
|
|
<div class="controls">
|
|
<button class="btn" onclick="runAnalysis()" id="analyzeBtn">
|
|
🔍 Mulai Analisis Sistem
|
|
</button>
|
|
</div>
|
|
|
|
<div class="results" id="results"></div>
|
|
</div>
|
|
|
|
<script>
|
|
let atrChart = null;
|
|
|
|
async function runAnalysis() {
|
|
const btn = document.getElementById('analyzeBtn');
|
|
const results = document.getElementById('results');
|
|
|
|
btn.disabled = true;
|
|
btn.textContent = '⏳ Menganalisis...';
|
|
|
|
results.innerHTML = `
|
|
<div class="loading">
|
|
<div class="spinner"></div>
|
|
<p>Sedang menganalisis sistem QuantumBotX...</p>
|
|
</div>
|
|
`;
|
|
|
|
try {
|
|
// Test file system access first
|
|
console.log('Testing file system access...');
|
|
|
|
// Check if window.fs is available
|
|
if (typeof window.fs === 'undefined') {
|
|
throw new Error('window.fs API tidak tersedia. File harus dibuka melalui Claude interface.');
|
|
}
|
|
|
|
// Test basic path access
|
|
console.log('Testing basic file access...');
|
|
|
|
// Real file analysis
|
|
const issues = await analyzeRealFiles();
|
|
const atrData = simulateATRCalculation();
|
|
|
|
displayResults(issues, atrData);
|
|
|
|
} catch (error) {
|
|
console.error('Analysis error:', error);
|
|
|
|
// Show fallback analysis with error info
|
|
results.innerHTML = `
|
|
<div style="background: #fee; border: 2px solid #faa; border-radius: 10px; padding: 20px; margin: 20px 0;">
|
|
<h3 style="color: #c53030; margin-bottom: 15px;">⚠️ File Access Error</h3>
|
|
<p><strong>Error:</strong> ${error.message}</p>
|
|
<p><strong>Reason:</strong> File HTML perlu dibuka melalui Claude interface untuk akses file system.</p>
|
|
|
|
<h4 style="margin: 20px 0 10px 0;">🔧 Solusi:</h4>
|
|
<ol style="margin-left: 20px; line-height: 1.6;">
|
|
<li>Upload file HTML ini ke chat Claude</li>
|
|
<li>Claude akan bisa akses file system</li>
|
|
<li>Atau gunakan manual analysis mode di bawah</li>
|
|
</ol>
|
|
</div>
|
|
|
|
<div style="text-align: center; margin: 30px 0;">
|
|
<button class="btn" onclick="showManualAnalysis()" style="background: #38a169;">
|
|
📋 Manual Analysis Mode
|
|
</button>
|
|
</div>
|
|
`;
|
|
}
|
|
|
|
btn.disabled = false;
|
|
btn.textContent = '🔍 Analisis Ulang';
|
|
}
|
|
|
|
function showManualAnalysis() {
|
|
const results = document.getElementById('results');
|
|
|
|
results.innerHTML = `
|
|
<div style="background: #f0f9ff; border-radius: 15px; padding: 25px; margin: 20px 0;">
|
|
<h3 style="color: #2c5282; margin-bottom: 20px;">📋 Manual Analysis Checklist</h3>
|
|
|
|
<p style="margin-bottom: 20px;">Cek manual file-file berikut di project <code>D:\\dev\\quantumbotx\\</code>:</p>
|
|
|
|
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 15px;">
|
|
<div style="background: white; padding: 15px; border-radius: 10px; border-left: 4px solid #e53e3e;">
|
|
<h4 style="color: #c53030; margin-bottom: 10px;">🔴 Critical Files</h4>
|
|
<ul style="margin-left: 20px; line-height: 1.6;">
|
|
<li><code>backtesting/engine.py</code></li>
|
|
<li><code>core/utils/risk_management.py</code></li>
|
|
</ul>
|
|
</div>
|
|
|
|
<div style="background: white; padding: 15px; border-radius: 10px; border-left: 4px solid #dd6b20;">
|
|
<h4 style="color: #c05621; margin-bottom: 10px;">🟠 Important Files</h4>
|
|
<ul style="margin-left: 20px; line-height: 1.6;">
|
|
<li><code>core/utils/atr_calculator.py</code></li>
|
|
<li><code>core/routes/api_history.py</code></li>
|
|
<li><code>core/mt5/trade.py</code></li>
|
|
</ul>
|
|
</div>
|
|
|
|
<div style="background: white; padding: 15px; border-radius: 10px; border-left: 4px solid #3182ce;">
|
|
<h4 style="color: #2c5282; margin-bottom: 10px;">🔵 Frontend Files</h4>
|
|
<ul style="margin-left: 20px; line-height: 1.6;">
|
|
<li><code>static/js/backtesting.js</code></li>
|
|
<li><code>static/js/history.js</code></li>
|
|
<li><code>templates/history.html</code></li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
|
|
<div style="background: #fffbeb; border-radius: 10px; padding: 20px; margin-top: 20px;">
|
|
<h4 style="color: #92400e; margin-bottom: 15px;">🔍 Yang Perlu Dicek:</h4>
|
|
<ol style="margin-left: 20px; line-height: 1.8;">
|
|
<li>File mana yang <strong>tidak ada</strong>?</li>
|
|
<li>Di <code>backtesting/engine.py</code> - apakah ada keyword <strong>"atr"</strong> atau <strong>"ATR"</strong>?</li>
|
|
<li>Di <code>backtesting/engine.py</code> - apakah ada handling untuk <strong>"XAUUSD"</strong>?</li>
|
|
<li>Di <code>core/routes/api_history.py</code> - apakah ada calculation <strong>"profit"</strong>?</li>
|
|
<li>Di frontend JS files - apakah ada chart atau ATR display?</li>
|
|
</ol>
|
|
</div>
|
|
</div>
|
|
`;
|
|
|
|
// Show simulated ATR data
|
|
const atrData = simulateATRCalculation();
|
|
displayATRSimulation(atrData);
|
|
}
|
|
|
|
function displayATRSimulation(atrData) {
|
|
const results = document.getElementById('results');
|
|
|
|
const avgATR = atrData.reduce((sum, item) => sum + item.atr, 0) / atrData.length;
|
|
const avgSL = atrData.reduce((sum, item) => sum + item.suggestedSL, 0) / atrData.length;
|
|
const avgTP = atrData.reduce((sum, item) => sum + item.suggestedTP, 0) / atrData.length;
|
|
|
|
results.innerHTML += `
|
|
<div class="atr-section">
|
|
<h3 class="atr-title">📈 Simulasi ATR Calculator (XAUUSD)</h3>
|
|
<div class="chart-container">
|
|
<canvas id="atrChart"></canvas>
|
|
</div>
|
|
|
|
<div class="atr-stats">
|
|
<div class="stat-card">
|
|
<div class="stat-value">${avgATR.toFixed(2)}</div>
|
|
<div class="stat-label">Avg ATR (14)</div>
|
|
</div>
|
|
<div class="stat-card">
|
|
<div class="stat-value">${avgSL.toFixed(2)}</div>
|
|
<div class="stat-label">Avg Stop Loss</div>
|
|
</div>
|
|
<div class="stat-card">
|
|
<div class="stat-value">${avgTP.toFixed(2)}</div>
|
|
<div class="stat-label">Avg Take Profit</div>
|
|
</div>
|
|
<div class="stat-card">
|
|
<div class="stat-value">1:1.5</div>
|
|
<div class="stat-label">Risk:Reward</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
`;
|
|
|
|
// Create ATR chart
|
|
createATRChart(atrData);
|
|
}
|
|
|
|
async function analyzeRealFiles() {
|
|
const issues = [];
|
|
const targetFiles = [
|
|
'backtesting/engine.py',
|
|
'core/utils/risk_management.py',
|
|
'core/utils/atr_calculator.py',
|
|
'core/mt5/trade.py',
|
|
'core/routes/api_history.py',
|
|
'static/js/backtesting.js',
|
|
'static/js/backtest.js',
|
|
'static/js/history.js',
|
|
'static/js/portfolio.js',
|
|
'templates/history.html',
|
|
'core/db/queries.py',
|
|
'core/db/models.py'
|
|
];
|
|
|
|
const fileContents = {};
|
|
let filesFound = 0;
|
|
|
|
// Try to read each target file
|
|
for (const filepath of targetFiles) {
|
|
try {
|
|
const fullPath = `D:/dev/quantumbotx/${filepath}`;
|
|
const content = await window.fs.readFile(fullPath, { encoding: 'utf8' });
|
|
fileContents[filepath] = content;
|
|
filesFound++;
|
|
} catch (error) {
|
|
console.warn(`File not found: ${filepath}`);
|
|
}
|
|
}
|
|
|
|
// Analyze findings
|
|
if (filesFound === 0) {
|
|
issues.push({
|
|
type: 'critical',
|
|
category: 'Setup',
|
|
title: 'Tidak Bisa Akses File Project',
|
|
description: `Path D:/dev/quantumbotx/ tidak bisa diakses atau file tidak ditemukan`,
|
|
impact: 'Tidak bisa menganalisis project',
|
|
solution: 'Pastikan file HTML ada di D:/dev/quantumbotx/ dan project structure benar'
|
|
});
|
|
return issues;
|
|
}
|
|
|
|
// Check backtesting engine
|
|
if (!fileContents['backtesting/engine.py']) {
|
|
issues.push({
|
|
type: 'critical',
|
|
category: 'Backtesting',
|
|
title: 'Missing Backtesting Engine',
|
|
description: 'File backtesting/engine.py tidak ditemukan',
|
|
impact: 'Backtesting tidak bisa berjalan',
|
|
solution: 'Buat backtesting engine yang compatible dengan ATR-based system'
|
|
});
|
|
} else {
|
|
const engine = fileContents['backtesting/engine.py'];
|
|
|
|
// Check ATR integration
|
|
if (!engine.toLowerCase().includes('atr')) {
|
|
issues.push({
|
|
type: 'error',
|
|
category: 'Risk Management',
|
|
title: 'ATR Not Integrated in Backtesting',
|
|
description: 'Backtesting engine belum menggunakan ATR calculations',
|
|
impact: 'Hasil backtest tidak accurate dengan risk management baru',
|
|
solution: 'Integrasikan ATR calculator dalam backtesting logic'
|
|
});
|
|
}
|
|
|
|
// Check XAUUSD handling
|
|
if (!engine.toLowerCase().includes('xauusd') && !engine.toLowerCase().includes('gold')) {
|
|
issues.push({
|
|
type: 'warning',
|
|
category: 'Symbol Handling',
|
|
title: 'No XAUUSD Specific Logic',
|
|
description: 'Tidak ada handling khusus untuk XAUUSD dalam backtesting',
|
|
impact: 'XAUUSD backtesting mungkin tidak accurate',
|
|
solution: 'Tambahkan XAUUSD specific pip calculation dan spread handling'
|
|
});
|
|
}
|
|
}
|
|
|
|
// Check ATR calculator
|
|
if (!fileContents['core/utils/atr_calculator.py']) {
|
|
issues.push({
|
|
type: 'error',
|
|
category: 'Technical Analysis',
|
|
title: 'Missing ATR Calculator',
|
|
description: 'ATR calculator module tidak ditemukan',
|
|
impact: 'Tidak bisa calculate dynamic SL/TP',
|
|
solution: 'Implement ATR calculation dengan pandas_ta atau custom logic'
|
|
});
|
|
}
|
|
|
|
// Check risk management
|
|
if (!fileContents['core/utils/risk_management.py']) {
|
|
issues.push({
|
|
type: 'critical',
|
|
category: 'Risk Management',
|
|
title: 'Missing Risk Management Module',
|
|
description: 'File risk_management.py tidak ditemukan',
|
|
impact: 'ATR-based risk tidak bisa dihitung',
|
|
solution: 'Buat risk management module dengan ATR integration'
|
|
});
|
|
}
|
|
|
|
// Check history API
|
|
if (!fileContents['core/routes/api_history.py']) {
|
|
issues.push({
|
|
type: 'error',
|
|
category: 'API',
|
|
title: 'Missing History API',
|
|
description: 'api_history.py tidak ditemukan',
|
|
impact: 'History page tidak bisa load data',
|
|
solution: 'Create history API endpoint dengan profit calculations'
|
|
});
|
|
} else {
|
|
const historyAPI = fileContents['core/routes/api_history.py'];
|
|
|
|
if (!historyAPI.includes('profit') || !historyAPI.includes('SUM')) {
|
|
issues.push({
|
|
type: 'error',
|
|
category: 'API',
|
|
title: 'No Profit Calculation in History API',
|
|
description: 'api_history.py tidak menghitung total profit',
|
|
impact: 'History page tidak show profit data',
|
|
solution: 'Tambahkan profit aggregation queries'
|
|
});
|
|
}
|
|
}
|
|
|
|
// Check frontend files
|
|
const frontendFiles = ['static/js/history.js', 'static/js/backtesting.js', 'static/js/backtest.js'];
|
|
const foundFrontend = frontendFiles.some(file => fileContents[file]);
|
|
|
|
if (!foundFrontend) {
|
|
issues.push({
|
|
type: 'error',
|
|
category: 'Frontend',
|
|
title: 'Missing Frontend JavaScript',
|
|
description: 'File history.js, backtesting.js, atau backtest.js tidak ditemukan',
|
|
impact: 'UI tidak interactive',
|
|
solution: 'Create frontend JavaScript untuk handle backtesting dan history'
|
|
});
|
|
}
|
|
|
|
// Success message if no critical issues
|
|
if (issues.length === 0 || !issues.some(i => i.type === 'critical')) {
|
|
issues.push({
|
|
type: 'info',
|
|
category: 'Status',
|
|
title: 'Project Structure OK',
|
|
description: `Berhasil menganalisis ${filesFound} dari ${targetFiles.length} file target`,
|
|
impact: 'Project structure dasar sudah ada',
|
|
solution: 'Lanjutkan dengan implementasi ATR integration'
|
|
});
|
|
}
|
|
|
|
return issues;
|
|
}
|
|
|
|
function simulateATRCalculation() {
|
|
const data = [];
|
|
let basePrice = 1950;
|
|
|
|
for (let i = 0; i < 30; i++) {
|
|
const high = basePrice + (Math.random() * 20);
|
|
const low = basePrice - (Math.random() * 20);
|
|
const close = low + (Math.random() * (high - low));
|
|
|
|
data.push({
|
|
date: new Date(Date.now() - (30-i) * 24 * 3600000).toISOString().split('T')[0],
|
|
price: parseFloat(close.toFixed(2)),
|
|
high: parseFloat(high.toFixed(2)),
|
|
low: parseFloat(low.toFixed(2))
|
|
});
|
|
|
|
basePrice = close + (Math.random() * 10 - 5);
|
|
}
|
|
|
|
// Calculate ATR
|
|
const atrData = [];
|
|
for (let i = 1; i < data.length; i++) {
|
|
const current = data[i];
|
|
const previous = data[i-1];
|
|
|
|
const tr1 = current.high - current.low;
|
|
const tr2 = Math.abs(current.high - previous.price);
|
|
const tr3 = Math.abs(current.low - previous.price);
|
|
const trueRange = Math.max(tr1, tr2, tr3);
|
|
|
|
atrData.push({
|
|
date: current.date,
|
|
price: current.price,
|
|
trueRange: parseFloat(trueRange.toFixed(2)),
|
|
atr: null
|
|
});
|
|
}
|
|
|
|
// Calculate ATR (14 period average)
|
|
const atrPeriod = 14;
|
|
for (let i = atrPeriod - 1; i < atrData.length; i++) {
|
|
const slice = atrData.slice(i - atrPeriod + 1, i + 1);
|
|
const avgTR = slice.reduce((sum, item) => sum + item.trueRange, 0) / atrPeriod;
|
|
atrData[i].atr = parseFloat(avgTR.toFixed(2));
|
|
|
|
const atrMultiplier = 2.0;
|
|
const stopLoss = atrData[i].atr * atrMultiplier;
|
|
const takeProfit = stopLoss * 1.5;
|
|
|
|
atrData[i].suggestedSL = parseFloat(stopLoss.toFixed(2));
|
|
atrData[i].suggestedTP = parseFloat(takeProfit.toFixed(2));
|
|
}
|
|
|
|
return atrData.filter(item => item.atr !== null);
|
|
}
|
|
|
|
function displayResults(issues, atrData) {
|
|
const results = document.getElementById('results');
|
|
|
|
const issuesHTML = issues.map(issue => `
|
|
<div class="issue-card issue-${issue.type}">
|
|
<div class="issue-category">${issue.category}</div>
|
|
<div class="issue-title">${issue.title}</div>
|
|
<div class="issue-description">${issue.description}</div>
|
|
<div class="issue-impact"><strong>Impact:</strong> ${issue.impact}</div>
|
|
<div class="issue-solution"><strong>Solution:</strong> ${issue.solution}</div>
|
|
</div>
|
|
`).join('');
|
|
|
|
const avgATR = atrData.reduce((sum, item) => sum + item.atr, 0) / atrData.length;
|
|
const avgSL = atrData.reduce((sum, item) => sum + item.suggestedSL, 0) / atrData.length;
|
|
const avgTP = atrData.reduce((sum, item) => sum + item.suggestedTP, 0) / atrData.length;
|
|
|
|
results.innerHTML = `
|
|
<h2 style="margin-bottom: 20px; color: #2d3748;">📊 Analisis Sistem Trading Bot</h2>
|
|
|
|
<div class="issues-grid">
|
|
${issuesHTML}
|
|
</div>
|
|
|
|
<div class="atr-section">
|
|
<h3 class="atr-title">📈 Simulasi ATR Calculator (XAUUSD)</h3>
|
|
<div class="chart-container">
|
|
<canvas id="atrChart"></canvas>
|
|
</div>
|
|
|
|
<div class="atr-stats">
|
|
<div class="stat-card">
|
|
<div class="stat-value">$${avgATR.toFixed(2)}</div>
|
|
<div class="stat-label">Avg ATR (14)</div>
|
|
</div>
|
|
<div class="stat-card">
|
|
<div class="stat-value">$${avgSL.toFixed(2)}</div>
|
|
<div class="stat-label">Avg Stop Loss</div>
|
|
</div>
|
|
<div class="stat-card">
|
|
<div class="stat-value">$${avgTP.toFixed(2)}</div>
|
|
<div class="stat-label">Avg Take Profit</div>
|
|
</div>
|
|
<div class="stat-card">
|
|
<div class="stat-value">1:1.5</div>
|
|
<div class="stat-label">Risk:Reward</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
`;
|
|
|
|
// Create ATR chart
|
|
createATRChart(atrData);
|
|
}
|
|
|
|
function createATRChart(atrData) {
|
|
const ctx = document.getElementById('atrChart').getContext('2d');
|
|
|
|
if (atrChart) {
|
|
atrChart.destroy();
|
|
}
|
|
|
|
atrChart = new Chart(ctx, {
|
|
type: 'line',
|
|
data: {
|
|
labels: atrData.map(item => item.date),
|
|
datasets: [
|
|
{
|
|
label: 'XAUUSD Price',
|
|
data: atrData.map(item => item.price),
|
|
borderColor: '#667eea',
|
|
backgroundColor: 'rgba(102, 126, 234, 0.1)',
|
|
yAxisID: 'y'
|
|
},
|
|
{
|
|
label: 'ATR',
|
|
data: atrData.map(item => item.atr),
|
|
borderColor: '#f56565',
|
|
backgroundColor: 'rgba(245, 101, 101, 0.1)',
|
|
yAxisID: 'y1'
|
|
}
|
|
]
|
|
},
|
|
options: {
|
|
responsive: true,
|
|
maintainAspectRatio: false,
|
|
interaction: {
|
|
mode: 'index',
|
|
intersect: false,
|
|
},
|
|
scales: {
|
|
y: {
|
|
type: 'linear',
|
|
display: true,
|
|
position: 'left',
|
|
title: {
|
|
display: true,
|
|
text: 'Price (USD)'
|
|
}
|
|
},
|
|
y1: {
|
|
type: 'linear',
|
|
display: true,
|
|
position: 'right',
|
|
title: {
|
|
display: true,
|
|
text: 'ATR'
|
|
},
|
|
grid: {
|
|
drawOnChartArea: false,
|
|
},
|
|
}
|
|
},
|
|
plugins: {
|
|
legend: {
|
|
position: 'top',
|
|
}
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
// Auto-run analysis on page load
|
|
window.addEventListener('load', () => {
|
|
setTimeout(runAnalysis, 1000);
|
|
});
|
|
</script>
|
|
</body>
|
|
</html> |