elliott-wave-analisis / index.html
Albian2025's picture
Add 2 files
cfce8da verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Elliott Wave Analyzer</title>
<script src="https://cdn.tailwindcss.com"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script src="https://cdn.jsdelivr.net/npm/fabric@5.3.1/dist/fabric.min.js"></script>
<style>
.dropzone {
border: 2px dashed #3b82f6;
border-radius: 0.5rem;
transition: all 0.3s ease;
}
.dropzone.active {
border-color: #10b981;
background-color: #f0f9ff;
}
.wave-tooltip {
position: absolute;
background: rgba(0, 0, 0, 0.7);
color: white;
padding: 5px 10px;
border-radius: 4px;
font-size: 12px;
pointer-events: none;
z-index: 100;
transform: translate(-50%, -100%);
white-space: nowrap;
}
.canvas-container {
position: relative;
margin: 0 auto;
}
.probability-meter {
height: 8px;
border-radius: 4px;
background: linear-gradient(to right, #ef4444, #f59e0b, #10b981);
}
</style>
</head>
<body class="bg-gray-50 min-h-screen">
<div class="container mx-auto px-4 py-8">
<header class="text-center mb-8">
<h1 class="text-3xl font-bold text-blue-600 mb-2">Elliott Wave Analyzer</h1>
<p class="text-gray-600">Upload your market chart and get automated Elliott Wave analysis with probability indicators</p>
</header>
<div class="max-w-4xl mx-auto bg-white rounded-xl shadow-md overflow-hidden p-6 mb-8">
<div class="grid md:grid-cols-2 gap-8">
<div>
<h2 class="text-xl font-semibold text-gray-800 mb-4">Upload Chart</h2>
<div id="dropzone" class="dropzone p-8 text-center cursor-pointer mb-4">
<i class="fas fa-cloud-upload-alt text-4xl text-blue-500 mb-3"></i>
<p class="text-gray-600 mb-2">Drag & drop your chart image here</p>
<p class="text-sm text-gray-500">or click to browse files</p>
<input type="file" id="fileInput" class="hidden" accept="image/*">
</div>
<div class="bg-blue-50 p-4 rounded-lg mb-4">
<h3 class="font-medium text-blue-800 mb-2">Chart Requirements</h3>
<ul class="text-sm text-blue-700 space-y-1">
<li><i class="fas fa-check-circle text-blue-500 mr-2"></i>Clear price action visible</li>
<li><i class="fas fa-check-circle text-blue-500 mr-2"></i>Preferred timeframes: 1H, 4H, Daily</li>
<li><i class="fas fa-check-circle text-blue-500 mr-2"></i>PNG or JPG format</li>
</ul>
</div>
<button id="analyzeBtn" disabled class="w-full bg-blue-600 hover:bg-blue-700 text-white font-medium py-2 px-4 rounded-lg transition disabled:opacity-50 disabled:cursor-not-allowed">
<i class="fas fa-wave-square mr-2"></i> Analyze Elliott Waves
</button>
</div>
<div>
<h2 class="text-xl font-semibold text-gray-800 mb-4">Elliott Wave Basics</h2>
<div class="bg-gray-50 p-4 rounded-lg">
<div class="flex items-start mb-3">
<div class="bg-blue-100 p-2 rounded-full mr-3">
<i class="fas fa-arrow-up text-blue-600"></i>
</div>
<div>
<h4 class="font-medium">Impulse Waves (5 waves)</h4>
<p class="text-sm text-gray-600">Directional moves with the trend</p>
</div>
</div>
<div class="flex items-start">
<div class="bg-purple-100 p-2 rounded-full mr-3">
<i class="fas fa-undo text-purple-600"></i>
</div>
<div>
<h4 class="font-medium">Corrective Waves (3 waves)</h4>
<p class="text-sm text-gray-600">Counter-trend moves</p>
</div>
</div>
</div>
<div class="mt-4 bg-yellow-50 p-4 rounded-lg">
<h3 class="font-medium text-yellow-800 mb-2">Analysis Parameters</h3>
<div class="space-y-3">
<div>
<label class="block text-sm font-medium text-gray-700 mb-1">Wave Degree</label>
<select id="waveDegree" class="w-full border border-gray-300 rounded-md px-3 py-2 text-sm">
<option value="minute">Minute</option>
<option value="minor">Minor</option>
<option value="intermediate" selected>Intermediate</option>
<option value="primary">Primary</option>
<option value="cycle">Cycle</option>
</select>
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-1">Analysis Aggressiveness</label>
<select id="analysisMode" class="w-full border border-gray-300 rounded-md px-3 py-2 text-sm">
<option value="conservative">Conservative (Higher accuracy)</option>
<option value="moderate" selected>Moderate (Balanced)</option>
<option value="aggressive">Aggressive (More wave counts)</option>
</select>
</div>
</div>
</div>
</div>
</div>
</div>
<div id="resultsSection" class="hidden max-w-6xl mx-auto bg-white rounded-xl shadow-md overflow-hidden p-6 mb-8">
<h2 class="text-xl font-semibold text-gray-800 mb-4">Analysis Results</h2>
<div class="grid md:grid-cols-3 gap-6 mb-6">
<div class="bg-green-50 p-4 rounded-lg">
<h3 class="font-medium text-green-800 mb-2">Current Wave</h3>
<div class="flex items-center">
<div class="text-2xl font-bold text-green-600 mr-3" id="currentWave">Wave 3</div>
<div class="text-sm text-green-700" id="waveType">Impulse Wave</div>
</div>
</div>
<div class="bg-blue-50 p-4 rounded-lg">
<h3 class="font-medium text-blue-800 mb-2">Probability Score</h3>
<div class="mb-2 text-sm text-blue-700" id="probabilityText">High Confidence (78%)</div>
<div class="probability-meter">
<div id="probabilityBar" class="h-full bg-green-500 rounded" style="width: 78%"></div>
</div>
</div>
<div class="bg-purple-50 p-4 rounded-lg">
<h3 class="font-medium text-purple-800 mb-2">Next Expected Move</h3>
<div class="flex items-center">
<div id="nextMoveDirection" class="text-2xl font-bold text-purple-600 mr-3"></div>
<div class="text-sm text-purple-700" id="nextMoveText">Wave 4 Correction Expected</div>
</div>
</div>
</div>
<div class="mb-6">
<h3 class="font-medium text-gray-800 mb-3">Support & Resistance Levels</h3>
<div class="grid md:grid-cols-2 gap-4">
<div class="bg-red-50 p-3 rounded-lg">
<h4 class="font-medium text-red-700 mb-1">Resistance Levels</h4>
<ul class="text-sm text-red-600 space-y-1" id="resistanceLevels">
<li><i class="fas fa-level-up-alt mr-2"></i>1.2350 (Strong)</li>
<li><i class="fas fa-level-up-alt mr-2"></i>1.2420 (Moderate)</li>
<li><i class="fas fa-level-up-alt mr-2"></i>1.2500 (Weak)</li>
</ul>
</div>
<div class="bg-green-50 p-3 rounded-lg">
<h4 class="font-medium text-green-700 mb-1">Support Levels</h4>
<ul class="text-sm text-green-600 space-y-1" id="supportLevels">
<li><i class="fas fa-level-down-alt mr-2"></i>1.2200 (Strong)</li>
<li><i class="fas fa-level-down-alt mr-2"></i>1.2150 (Moderate)</li>
<li><i class="fas fa-level-down-alt mr-2"></i>1.2100 (Weak)</li>
</ul>
</div>
</div>
</div>
<div class="canvas-container">
<div class="flex justify-between items-center mb-3">
<h3 class="font-medium text-gray-800">Annotated Chart</h3>
<button id="downloadBtn" class="text-sm bg-blue-600 hover:bg-blue-700 text-white py-1 px-3 rounded">
<i class="fas fa-download mr-1"></i> Download Analysis
</button>
</div>
<canvas id="analysisCanvas" class="border border-gray-200 rounded-lg"></canvas>
<div id="waveTooltip" class="wave-tooltip" style="display: none;"></div>
</div>
<div class="mt-6 bg-gray-50 p-4 rounded-lg">
<h3 class="font-medium text-gray-800 mb-2">Analysis Notes</h3>
<div class="text-sm text-gray-700 space-y-2" id="analysisNotes">
<p><i class="fas fa-check-circle text-green-500 mr-2"></i>Wave 3 shows strong momentum with extended characteristics.</p>
<p><i class="fas fa-exclamation-triangle text-yellow-500 mr-2"></i>Watch for potential truncation if price fails to exceed 1.2350.</p>
<p><i class="fas fa-arrow-right text-blue-500 mr-2"></i>Next expected move is Wave 4 correction, typically retracing 38.2% of Wave 3.</p>
</div>
</div>
</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
// DOM elements
const dropzone = document.getElementById('dropzone');
const fileInput = document.getElementById('fileInput');
const analyzeBtn = document.getElementById('analyzeBtn');
const resultsSection = document.getElementById('resultsSection');
const canvas = document.getElementById('analysisCanvas');
const waveTooltip = document.getElementById('waveTooltip');
const downloadBtn = document.getElementById('downloadBtn');
// Fabric.js setup
const fabricCanvas = new fabric.Canvas('analysisCanvas', {
backgroundColor: '#ffffff',
selection: false
});
let uploadedImage = null;
// Event listeners
dropzone.addEventListener('click', () => fileInput.click());
fileInput.addEventListener('change', function(e) {
if (e.target.files.length) {
handleFileUpload(e.target.files[0]);
}
});
dropzone.addEventListener('dragover', (e) => {
e.preventDefault();
dropzone.classList.add('active');
});
dropzone.addEventListener('dragleave', () => {
dropzone.classList.remove('active');
});
dropzone.addEventListener('drop', (e) => {
e.preventDefault();
dropzone.classList.remove('active');
if (e.dataTransfer.files.length) {
handleFileUpload(e.dataTransfer.files[0]);
}
});
analyzeBtn.addEventListener('click', analyzeElliottWaves);
downloadBtn.addEventListener('click', downloadAnalysis);
// Canvas mouse events
fabricCanvas.on('mouse:move', function(options) {
if (!options.target) {
waveTooltip.style.display = 'none';
return;
}
if (options.target.waveData) {
const pointer = fabricCanvas.getPointer(options.e);
waveTooltip.style.left = pointer.x + 'px';
waveTooltip.style.top = pointer.y + 'px';
waveTooltip.style.display = 'block';
waveTooltip.innerHTML = `
<strong>${options.target.waveData.label}</strong><br>
Type: ${options.target.waveData.type}<br>
Confidence: ${options.target.waveData.confidence}%
`;
} else {
waveTooltip.style.display = 'none';
}
});
fabricCanvas.on('mouse:out', function() {
waveTooltip.style.display = 'none';
});
// Functions
function handleFileUpload(file) {
if (!file.type.match('image.*')) {
alert('Please upload an image file');
return;
}
const reader = new FileReader();
reader.onload = function(e) {
// Remove previous image if exists
if (uploadedImage) {
fabricCanvas.remove(uploadedImage);
}
fabric.Image.fromURL(e.target.result, function(img) {
// Scale image to fit canvas while maintaining aspect ratio
const scale = Math.min(
canvas.width / img.width,
canvas.height / img.height
);
img.set({
left: canvas.width / 2,
top: canvas.height / 2,
originX: 'center',
originY: 'center',
scaleX: scale * 0.95,
scaleY: scale * 0.95
});
uploadedImage = img;
fabricCanvas.add(img);
fabricCanvas.renderAll();
// Enable analyze button
analyzeBtn.disabled = false;
});
};
reader.readAsDataURL(file);
}
function analyzeElliottWaves() {
if (!uploadedImage) return;
// Show loading state
analyzeBtn.innerHTML = '<i class="fas fa-spinner fa-spin mr-2"></i> Analyzing...';
analyzeBtn.disabled = true;
// Simulate analysis delay
setTimeout(() => {
// Generate random analysis results for demo
const waveDegree = document.getElementById('waveDegree').value;
const analysisMode = document.getElementById('analysisMode').value;
// This is where you would normally call your actual Elliott Wave analysis logic
// For this demo, we'll simulate results
simulateElliottWaveAnalysis(waveDegree, analysisMode);
// Show results section
resultsSection.classList.remove('hidden');
// Reset button
analyzeBtn.innerHTML = '<i class="fas fa-wave-square mr-2"></i> Analyze Elliott Waves';
analyzeBtn.disabled = false;
}, 2000);
}
function simulateElliottWaveAnalysis(waveDegree, analysisMode) {
// Clear previous drawings
fabricCanvas.getObjects().forEach(obj => {
if (obj !== uploadedImage) {
fabricCanvas.remove(obj);
}
});
// Get image dimensions
const imgWidth = uploadedImage.width * uploadedImage.scaleX;
const imgHeight = uploadedImage.height * uploadedImage.scaleY;
const imgLeft = uploadedImage.left - imgWidth / 2;
const imgTop = uploadedImage.top - imgHeight / 2;
// Generate random wave points (simulated analysis)
const wavePoints = [];
const segmentCount = 8; // Number of wave segments to draw
for (let i = 0; i < segmentCount; i++) {
const x = imgLeft + (imgWidth / (segmentCount - 1)) * i;
const baseY = imgTop + imgHeight / 2;
const amplitude = imgHeight / (4 + Math.random() * 4);
const y = baseY + amplitude * Math.sin(i * Math.PI / 2);
wavePoints.push({ x, y });
}
// Draw wave segments with labels
for (let i = 0; i < wavePoints.length - 1; i++) {
const start = wavePoints[i];
const end = wavePoints[i + 1];
// Determine wave type (impulse or corrective)
const isImpulse = i % 2 === 0;
const waveType = isImpulse ? 'Impulse' : 'Corrective';
const waveLabel = isImpulse ? `Wave ${Math.floor(i/2) + 1}` : `Wave ${Math.floor(i/2) + 1} Correction`;
// Random confidence based on analysis mode
let confidence;
if (analysisMode === 'conservative') {
confidence = 70 + Math.floor(Math.random() * 25);
} else if (analysisMode === 'moderate') {
confidence = 60 + Math.floor(Math.random() * 35);
} else {
confidence = 50 + Math.floor(Math.random() * 45);
}
// Draw wave line
const line = new fabric.Line([start.x, start.y, end.x, end.y], {
stroke: isImpulse ? '#3b82f6' : '#8b5cf6',
strokeWidth: 3,
selectable: false,
waveData: {
label: waveLabel,
type: waveType,
confidence: confidence
}
});
// Add arrowhead
const angle = Math.atan2(end.y - start.y, end.x - start.x);
const arrowSize = 12;
const arrow = new fabric.Triangle({
left: end.x,
top: end.y,
width: arrowSize,
height: arrowSize,
fill: isImpulse ? '#3b82f6' : '#8b5cf6',
angle: angle * 180 / Math.PI,
originX: 'center',
originY: 'center',
selectable: false
});
// Add wave label
const midX = (start.x + end.x) / 2;
const midY = (start.y + end.y) / 2;
const label = new fabric.Text(waveLabel, {
left: midX,
top: midY - 20,
fontSize: 12,
fill: isImpulse ? '#3b82f6' : '#8b5cf6',
fontWeight: 'bold',
originX: 'center',
selectable: false
});
// Add confidence indicator
const confidenceText = new fabric.Text(`${confidence}%`, {
left: midX,
top: midY + 5,
fontSize: 10,
fill: '#6b7280',
originX: 'center',
selectable: false
});
fabricCanvas.add(line, arrow, label, confidenceText);
}
// Draw support/resistance levels
const supportLevels = [
{ price: '1.2200', strength: 'Strong' },
{ price: '1.2150', strength: 'Moderate' },
{ price: '1.2100', strength: 'Weak' }
];
const resistanceLevels = [
{ price: '1.2350', strength: 'Strong' },
{ price: '1.2420', strength: 'Moderate' },
{ price: '1.2500', strength: 'Weak' }
];
// Draw support levels (left side)
supportLevels.forEach((level, i) => {
const y = imgTop + imgHeight * (0.3 + i * 0.2);
const line = new fabric.Line([imgLeft, y, imgLeft + imgWidth * 0.8, y], {
stroke: '#10b981',
strokeWidth: 1,
strokeDashArray: [5, 3],
selectable: false
});
const label = new fabric.Text(`S: ${level.price}`, {
left: imgLeft + 5,
top: y - 10,
fontSize: 10,
fill: '#10b981',
selectable: false
});
fabricCanvas.add(line, label);
});
// Draw resistance levels (right side)
resistanceLevels.forEach((level, i) => {
const y = imgTop + imgHeight * (0.2 + i * 0.25);
const line = new fabric.Line([imgLeft + imgWidth * 0.2, y, imgLeft + imgWidth, y], {
stroke: '#ef4444',
strokeWidth: 1,
strokeDashArray: [5, 3],
selectable: false
});
const label = new fabric.Text(`R: ${level.price}`, {
left: imgLeft + imgWidth - 35,
top: y - 10,
fontSize: 10,
fill: '#ef4444',
selectable: false
});
fabricCanvas.add(line, label);
});
// Update UI with analysis results
document.getElementById('currentWave').textContent = 'Wave 3';
document.getElementById('waveType').textContent = 'Impulse Wave';
const probability = 78;
document.getElementById('probabilityText').textContent = `High Confidence (${probability}%)`;
document.getElementById('probabilityBar').style.width = `${probability}%`;
document.getElementById('nextMoveDirection').textContent = '↓';
document.getElementById('nextMoveText').textContent = 'Wave 4 Correction Expected';
// Update support/resistance lists
const supportList = document.getElementById('supportLevels');
const resistanceList = document.getElementById('resistanceLevels');
supportList.innerHTML = supportLevels.map(level =>
`<li><i class="fas fa-level-down-alt mr-2"></i>${level.price} (${level.strength})</li>`
).join('');
resistanceList.innerHTML = resistanceLevels.map(level =>
`<li><i class="fas fa-level-up-alt mr-2"></i>${level.price} (${level.strength})</li>`
).join('');
// Update wave degree in notes
const degreeMap = {
'minute': 'Minute',
'minor': 'Minor',
'intermediate': 'Intermediate',
'primary': 'Primary',
'cycle': 'Cycle'
};
document.getElementById('analysisNotes').innerHTML = `
<p><i class="fas fa-check-circle text-green-500 mr-2"></i>Wave 3 shows strong momentum with extended characteristics.</p>
<p><i class="fas fa-exclamation-triangle text-yellow-500 mr-2"></i>Watch for potential truncation if price fails to exceed 1.2350.</p>
<p><i class="fas fa-arrow-right text-blue-500 mr-2"></i>Next expected move is Wave 4 correction, typically retracing 38.2% of Wave 3.</p>
<p><i class="fas fa-info-circle text-gray-500 mr-2"></i>Analysis performed on ${degreeMap[waveDegree]} degree chart.</p>
`;
}
function downloadAnalysis() {
// Create temporary link to download canvas as image
const link = document.createElement('a');
link.download = 'elliott-wave-analysis.png';
link.href = fabricCanvas.toDataURL({
format: 'png',
quality: 1
});
link.click();
}
// Initialize canvas size
function resizeCanvas() {
const container = document.querySelector('.canvas-container');
canvas.width = container.clientWidth - 40;
canvas.height = Math.min(600, window.innerHeight * 0.6);
fabricCanvas.setDimensions({ width: canvas.width, height: canvas.height });
if (uploadedImage) {
// Re-center and scale image
const scale = Math.min(
canvas.width / (uploadedImage.width * uploadedImage.scaleX / uploadedImage.scaleX),
canvas.height / (uploadedImage.height * uploadedImage.scaleY / uploadedImage.scaleY)
);
uploadedImage.set({
left: canvas.width / 2,
top: canvas.height / 2,
scaleX: scale * 0.95,
scaleY: scale * 0.95
});
fabricCanvas.renderAll();
}
}
window.addEventListener('resize', resizeCanvas);
resizeCanvas();
});
</script>
<p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=Albian2025/elliott-wave-analisis" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
</html>