Spaces:
Running
Running
| <html lang="ru"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>CryptoAnalyzer Pro - Анализ и прогноз криптовалют</title> | |
| <script src="https://cdn.tailwindcss.com"></script> | |
| <script src="https://cdn.jsdelivr.net/npm/chart.js"></script> | |
| <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script> | |
| <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> | |
| <style> | |
| .indicator-active { | |
| @apply bg-blue-100 border-blue-500; | |
| } | |
| .news-card:hover { | |
| transform: translateY(-5px); | |
| box-shadow: 0 10px 20px rgba(0,0,0,0.1); | |
| } | |
| .blink { | |
| animation: blink-animation 1s steps(2, start) infinite; | |
| } | |
| @keyframes blink-animation { | |
| to { opacity: 0.5; } | |
| } | |
| .chart-container { | |
| height: 400px; | |
| } | |
| .tooltip { | |
| position: relative; | |
| display: inline-block; | |
| } | |
| .tooltip .tooltiptext { | |
| visibility: hidden; | |
| width: 200px; | |
| background-color: #333; | |
| color: #fff; | |
| text-align: center; | |
| border-radius: 6px; | |
| padding: 5px; | |
| position: absolute; | |
| z-index: 1; | |
| bottom: 125%; | |
| left: 50%; | |
| margin-left: -100px; | |
| opacity: 0; | |
| transition: opacity 0.3s; | |
| } | |
| .tooltip:hover .tooltiptext { | |
| visibility: visible; | |
| opacity: 1; | |
| } | |
| </style> | |
| </head> | |
| <body class="bg-gray-50 text-gray-800"> | |
| <div class="container mx-auto px-4 py-8"> | |
| <!-- Header --> | |
| <header class="mb-8"> | |
| <div class="flex justify-between items-center"> | |
| <div> | |
| <h1 class="text-3xl font-bold text-blue-600">CryptoAnalyzer <span class="text-yellow-500">Pro</span></h1> | |
| <p class="text-gray-600">Комплексный анализ и прогнозирование криптовалютных активов</p> | |
| </div> | |
| <div class="flex items-center space-x-4"> | |
| <div class="relative"> | |
| <select id="cryptoSelect" class="block appearance-none bg-white border border-gray-300 text-gray-700 py-2 px-4 pr-8 rounded leading-tight focus:outline-none focus:border-blue-500"> | |
| <option value="BTC">Bitcoin (BTC)</option> | |
| <option value="ETH">Ethereum (ETH)</option> | |
| <option value="BNB">Binance Coin (BNB)</option> | |
| <option value="SOL">Solana (SOL)</option> | |
| <option value="XRP">Ripple (XRP)</option> | |
| </select> | |
| <div class="pointer-events-none absolute inset-y-0 right-0 flex items-center px-2 text-gray-700"> | |
| <i class="fas fa-chevron-down"></i> | |
| </div> | |
| </div> | |
| <div class="relative"> | |
| <select id="timeframeSelect" class="block appearance-none bg-white border border-gray-300 text-gray-700 py-2 px-4 pr-8 rounded leading-tight focus:outline-none focus:border-blue-500"> | |
| <option value="1d">1 день</option> | |
| <option value="1h">1 час</option> | |
| <option value="4h">4 часа</option> | |
| <option value="1w">1 неделя</option> | |
| <option value="1m">1 месяц</option> | |
| </select> | |
| <div class="pointer-events-none absolute inset-y-0 right-0 flex items-center px-2 text-gray-700"> | |
| <i class="fas fa-chevron-down"></i> | |
| </div> | |
| </div> | |
| <button id="refreshBtn" class="bg-blue-500 hover:bg-blue-600 text-white px-4 py-2 rounded-lg flex items-center"> | |
| <i class="fas fa-sync-alt mr-2"></i> Обновить | |
| </button> | |
| </div> | |
| </div> | |
| </header> | |
| <!-- Main Dashboard --> | |
| <div class="grid grid-cols-1 lg:grid-cols-3 gap-6 mb-8"> | |
| <!-- Price Overview --> | |
| <div class="bg-white rounded-xl shadow-md p-6 col-span-1"> | |
| <div class="flex justify-between items-center mb-4"> | |
| <h2 class="text-xl font-semibold">Обзор цены</h2> | |
| <span id="priceChange" class="px-3 py-1 rounded-full text-sm font-medium"></span> | |
| </div> | |
| <div class="flex items-end mb-2"> | |
| <span id="currentPrice" class="text-3xl font-bold mr-2">$--</span> | |
| <span id="priceChangePercent" class="text-lg"></span> | |
| </div> | |
| <div class="grid grid-cols-2 gap-4 mt-4"> | |
| <div> | |
| <p class="text-gray-500 text-sm">Максимум (24ч)</p> | |
| <p id="high24h" class="font-medium">$--</p> | |
| </div> | |
| <div> | |
| <p class="text-gray-500 text-sm">Минимум (24ч)</p> | |
| <p id="low24h" class="font-medium">$--</p> | |
| </div> | |
| <div> | |
| <p class="text-gray-500 text-sm">Объем (24ч)</p> | |
| <p id="volume24h" class="font-medium">$--</p> | |
| </div> | |
| <div> | |
| <p class="text-gray-500 text-sm">Рыночная капитализация</p> | |
| <p id="marketCap" class="font-medium">$--</p> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Indicators Summary --> | |
| <div class="bg-white rounded-xl shadow-md p-6 col-span-1"> | |
| <h2 class="text-xl font-semibold mb-4">Технические индикаторы</h2> | |
| <div class="space-y-4"> | |
| <div> | |
| <div class="flex justify-between mb-1"> | |
| <span class="font-medium">RSI (14)</span> | |
| <span id="rsiValue" class="font-bold">--</span> | |
| </div> | |
| <div class="w-full bg-gray-200 rounded-full h-2.5"> | |
| <div id="rsiBar" class="bg-blue-600 h-2.5 rounded-full" style="width: 50%"></div> | |
| </div> | |
| <div class="flex justify-between text-xs text-gray-500 mt-1"> | |
| <span>Перепроданность</span> | |
| <span>Нейтрально</span> | |
| <span>Перекупленность</span> | |
| </div> | |
| </div> | |
| <div> | |
| <div class="flex justify-between mb-1"> | |
| <span class="font-medium">MACD</span> | |
| <span id="macdValue" class="font-bold">--</span> | |
| </div> | |
| <div class="flex items-center"> | |
| <div class="w-4 h-4 rounded-full mr-2" id="macdSignal"></div> | |
| <span id="macdSignalText" class="text-sm">Сигнал: --</span> | |
| </div> | |
| </div> | |
| <div> | |
| <div class="flex justify-between mb-1"> | |
| <span class="font-medium">Скользящие средние</span> | |
| <span id="maSignal" class="font-bold">--</span> | |
| </div> | |
| <div class="flex items-center"> | |
| <div class="w-4 h-4 rounded-full mr-2" id="maSignalDot"></div> | |
| <span id="maSignalText" class="text-sm">Сигнал: --</span> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Prediction Card --> | |
| <div class="bg-white rounded-xl shadow-md p-6 col-span-1"> | |
| <h2 class="text-xl font-semibold mb-4">Прогноз на основе анализа</h2> | |
| <div class="flex flex-col items-center justify-center h-full"> | |
| <div id="predictionIcon" class="text-5xl mb-4"> | |
| <i class="fas fa-question-circle text-gray-400"></i> | |
| </div> | |
| <div id="predictionText" class="text-center"> | |
| <p class="text-lg font-medium mb-2">Загрузка данных...</p> | |
| <p class="text-gray-600 text-sm">Анализируем рыночные индикаторы и тенденции</p> | |
| </div> | |
| <div id="confidenceMeter" class="w-full mt-6"> | |
| <div class="flex justify-between mb-1"> | |
| <span class="text-sm font-medium">Уверенность прогноза</span> | |
| <span id="confidenceValue" class="text-sm font-bold">--%</span> | |
| </div> | |
| <div class="w-full bg-gray-200 rounded-full h-2.5"> | |
| <div id="confidenceBar" class="bg-green-500 h-2.5 rounded-full" style="width: 0%"></div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Charts Section --> | |
| <div class="bg-white rounded-xl shadow-md p-6 mb-8"> | |
| <div class="flex justify-between items-center mb-6"> | |
| <h2 class="text-xl font-semibold">Графики и анализ</h2> | |
| <div class="flex space-x-2"> | |
| <button id="priceChartBtn" class="px-3 py-1 bg-blue-500 text-white rounded-md">Цена</button> | |
| <button id="volumeChartBtn" class="px-3 py-1 bg-gray-200 text-gray-700 rounded-md">Объем</button> | |
| <button id="rsiChartBtn" class="px-3 py-1 bg-gray-200 text-gray-700 rounded-md">RSI</button> | |
| <button id="macdChartBtn" class="px-3 py-1 bg-gray-200 text-gray-700 rounded-md">MACD</button> | |
| </div> | |
| </div> | |
| <div class="chart-container"> | |
| <canvas id="mainChart"></canvas> | |
| </div> | |
| <div class="mt-4 flex flex-wrap gap-2"> | |
| <button class="indicator-btn px-3 py-1 border rounded-md" data-indicator="sma">SMA (20,50)</button> | |
| <button class="indicator-btn px-3 py-1 border rounded-md" data-indicator="ema">EMA (12,26)</button> | |
| <button class="indicator-btn px-3 py-1 border rounded-md" data-indicator="bollinger">Полосы Боллинджера</button> | |
| <button class="indicator-btn px-3 py-1 border rounded-md" data-indicator="fibonacci">Уровни Фибоначчи</button> | |
| <button class="indicator-btn px-3 py-1 border rounded-md" data-indicator="support">Уровни поддержки/сопротивления</button> | |
| </div> | |
| </div> | |
| <!-- News and Social Sentiment --> | |
| <div class="grid grid-cols-1 lg:grid-cols-2 gap-6 mb-8"> | |
| <!-- News Section --> | |
| <div class="bg-white rounded-xl shadow-md p-6"> | |
| <div class="flex justify-between items-center mb-4"> | |
| <h2 class="text-xl font-semibold">Последние новости</h2> | |
| <button id="refreshNews" class="text-blue-500 hover:text-blue-700"> | |
| <i class="fas fa-sync-alt"></i> | |
| </button> | |
| </div> | |
| <div id="newsContainer" class="space-y-4"> | |
| <div class="news-card bg-gray-50 p-4 rounded-lg transition-all duration-200 cursor-pointer"> | |
| <div class="flex justify-between items-start"> | |
| <div> | |
| <h3 class="font-medium">Загрузка новостей...</h3> | |
| <p class="text-gray-500 text-sm mt-1">Источник: --</p> | |
| </div> | |
| <span class="text-xs text-gray-400">-- минут назад</span> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Social Sentiment --> | |
| <div class="bg-white rounded-xl shadow-md p-6"> | |
| <h2 class="text-xl font-semibold mb-4">Социальные настроения</h2> | |
| <div class="flex items-center justify-center mb-6"> | |
| <div class="relative w-40 h-40"> | |
| <svg class="w-full h-full" viewBox="0 0 100 100"> | |
| <circle cx="50" cy="50" r="45" fill="none" stroke="#e6e6e6" stroke-width="8"></circle> | |
| <circle id="sentimentCircle" cx="50" cy="50" r="45" fill="none" stroke="#4CAF50" stroke-width="8" stroke-dasharray="283" stroke-dashoffset="141.5" stroke-linecap="round" transform="rotate(-90 50 50)"></circle> | |
| <text id="sentimentValue" x="50" y="50" text-anchor="middle" dy=".3em" font-size="20" font-weight="bold">--%</text> | |
| </svg> | |
| </div> | |
| <div class="ml-6"> | |
| <div class="mb-4"> | |
| <p class="text-gray-500 text-sm">Позитивные упоминания</p> | |
| <p id="positiveMentions" class="font-medium text-green-500">--%</p> | |
| </div> | |
| <div class="mb-4"> | |
| <p class="text-gray-500 text-sm">Негативные упоминания</p> | |
| <p id="negativeMentions" class="font-medium text-red-500">--%</p> | |
| </div> | |
| <div> | |
| <p class="text-gray-500 text-sm">Общее упоминаний (24ч)</p> | |
| <p id="totalMentions" class="font-medium">--</p> | |
| </div> | |
| </div> | |
| </div> | |
| <div> | |
| <p class="text-gray-500 text-sm mb-2">Ключевые слова</p> | |
| <div id="keywordsContainer" class="flex flex-wrap gap-2"> | |
| <span class="px-2 py-1 bg-blue-100 text-blue-800 text-xs rounded-full">загрузка...</span> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Detailed Indicators --> | |
| <div class="bg-white rounded-xl shadow-md p-6 mb-8"> | |
| <h2 class="text-xl font-semibold mb-4">Подробные индикаторы</h2> | |
| <div class="overflow-x-auto"> | |
| <table class="min-w-full divide-y divide-gray-200"> | |
| <thead class="bg-gray-50"> | |
| <tr> | |
| <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Индикатор</th> | |
| <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Значение</th> | |
| <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Сигнал</th> | |
| <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Описание</th> | |
| </tr> | |
| </thead> | |
| <tbody id="indicatorsTable" class="bg-white divide-y divide-gray-200"> | |
| <tr> | |
| <td class="px-6 py-4 whitespace-nowrap">RSI (14)</td> | |
| <td class="px-6 py-4 whitespace-nowrap">--</td> | |
| <td class="px-6 py-4 whitespace-nowrap">--</td> | |
| <td class="px-6 py-4">Индекс относительной силы показывает перекупленность/перепроданность</td> | |
| </tr> | |
| <tr> | |
| <td class="px-6 py-4 whitespace-nowrap">MACD (12,26,9)</td> | |
| <td class="px-6 py-4 whitespace-nowrap">--</td> | |
| <td class="px-6 py-4 whitespace-nowrap">--</td> | |
| <td class="px-6 py-4">Схождение/расхождение скользящих средних</td> | |
| </tr> | |
| <tr> | |
| <td class="px-6 py-4 whitespace-nowrap">SMA (50)</td> | |
| <td class="px-6 py-4 whitespace-nowrap">--</td> | |
| <td class="px-6 py-4 whitespace-nowrap">--</td> | |
| <td class="px-6 py-4">Простая скользящая средняя за 50 периодов</td> | |
| </tr> | |
| <tr> | |
| <td class="px-6 py-4 whitespace-nowrap">Bollinger Bands</td> | |
| <td class="px-6 py-4 whitespace-nowrap">--</td> | |
| <td class="px-6 py-4 whitespace-nowrap">--</td> | |
| <td class="px-6 py-4">Волатильность и ценовые экстремумы</td> | |
| </tr> | |
| <tr> | |
| <td class="px-6 py-4 whitespace-nowrap">Объем</td> | |
| <td class="px-6 py-4 whitespace-nowrap">--</td> | |
| <td class="px-6 py-4 whitespace-nowrap">--</td> | |
| <td class="px-6 py-4">Объем торгов за последние 24 часа</td> | |
| </tr> | |
| </tbody> | |
| </table> | |
| </div> | |
| </div> | |
| <!-- Disclaimer --> | |
| <div class="bg-yellow-50 border-l-4 border-yellow-400 p-4 mb-8"> | |
| <div class="flex"> | |
| <div class="flex-shrink-0"> | |
| <i class="fas fa-exclamation-triangle text-yellow-400"></i> | |
| </div> | |
| <div class="ml-3"> | |
| <p class="text-sm text-yellow-700"> | |
| <strong>Важно:</strong> Данный инструмент предоставляет аналитическую информацию и не является финансовой рекомендацией. Криптовалютные рынки крайне волатильны. Проводите собственное исследование перед принятием инвестиционных решений. | |
| </p> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <script> | |
| // Global variables | |
| let mainChart; | |
| let currentCrypto = 'BTC'; | |
| let currentTimeframe = '1d'; | |
| let activeIndicators = []; | |
| let chartType = 'price'; | |
| // DOM Elements | |
| const cryptoSelect = document.getElementById('cryptoSelect'); | |
| const timeframeSelect = document.getElementById('timeframeSelect'); | |
| const refreshBtn = document.getElementById('refreshBtn'); | |
| const currentPriceEl = document.getElementById('currentPrice'); | |
| const priceChangeEl = document.getElementById('priceChange'); | |
| const priceChangePercentEl = document.getElementById('priceChangePercent'); | |
| const high24hEl = document.getElementById('high24h'); | |
| const low24hEl = document.getElementById('low24h'); | |
| const volume24hEl = document.getElementById('volume24h'); | |
| const marketCapEl = document.getElementById('marketCap'); | |
| const rsiValueEl = document.getElementById('rsiValue'); | |
| const rsiBarEl = document.getElementById('rsiBar'); | |
| const macdValueEl = document.getElementById('macdValue'); | |
| const macdSignalEl = document.getElementById('macdSignal'); | |
| const macdSignalTextEl = document.getElementById('macdSignalText'); | |
| const maSignalEl = document.getElementById('maSignal'); | |
| const maSignalDotEl = document.getElementById('maSignalDot'); | |
| const maSignalTextEl = document.getElementById('maSignalText'); | |
| const predictionIconEl = document.getElementById('predictionIcon'); | |
| const predictionTextEl = document.getElementById('predictionText'); | |
| const confidenceValueEl = document.getElementById('confidenceValue'); | |
| const confidenceBarEl = document.getElementById('confidenceBar'); | |
| const priceChartBtn = document.getElementById('priceChartBtn'); | |
| const volumeChartBtn = document.getElementById('volumeChartBtn'); | |
| const rsiChartBtn = document.getElementById('rsiChartBtn'); | |
| const macdChartBtn = document.getElementById('macdChartBtn'); | |
| const newsContainer = document.getElementById('newsContainer'); | |
| const refreshNews = document.getElementById('refreshNews'); | |
| const sentimentCircle = document.getElementById('sentimentCircle'); | |
| const sentimentValueEl = document.getElementById('sentimentValue'); | |
| const positiveMentionsEl = document.getElementById('positiveMentions'); | |
| const negativeMentionsEl = document.getElementById('negativeMentions'); | |
| const totalMentionsEl = document.getElementById('totalMentions'); | |
| const keywordsContainer = document.getElementById('keywordsContainer'); | |
| const indicatorsTable = document.getElementById('indicatorsTable'); | |
| // Event Listeners | |
| cryptoSelect.addEventListener('change', (e) => { | |
| currentCrypto = e.target.value; | |
| loadData(); | |
| }); | |
| timeframeSelect.addEventListener('change', (e) => { | |
| currentTimeframe = e.target.value; | |
| loadData(); | |
| }); | |
| refreshBtn.addEventListener('click', loadData); | |
| refreshNews.addEventListener('click', loadNews); | |
| priceChartBtn.addEventListener('click', () => switchChartType('price')); | |
| volumeChartBtn.addEventListener('click', () => switchChartType('volume')); | |
| rsiChartBtn.addEventListener('click', () => switchChartType('rsi')); | |
| macdChartBtn.addEventListener('click', () => switchChartType('macd')); | |
| document.querySelectorAll('.indicator-btn').forEach(btn => { | |
| btn.addEventListener('click', function() { | |
| const indicator = this.dataset.indicator; | |
| toggleIndicator(indicator, this); | |
| }); | |
| }); | |
| // Initialize | |
| document.addEventListener('DOMContentLoaded', () => { | |
| loadData(); | |
| loadNews(); | |
| updateSocialSentiment(); | |
| initializeChart(); | |
| }); | |
| // Functions | |
| function initializeChart() { | |
| const ctx = document.getElementById('mainChart').getContext('2d'); | |
| mainChart = new Chart(ctx, { | |
| type: 'line', | |
| data: { | |
| labels: [], | |
| datasets: [ | |
| { | |
| label: 'Цена', | |
| data: [], | |
| borderColor: 'rgb(59, 130, 246)', | |
| backgroundColor: 'rgba(59, 130, 246, 0.1)', | |
| borderWidth: 2, | |
| fill: true, | |
| tension: 0.1 | |
| }, | |
| { | |
| label: 'SMA (20)', | |
| data: [], | |
| borderColor: 'rgb(234, 88, 12)', | |
| backgroundColor: 'rgba(234, 88, 12, 0.1)', | |
| borderWidth: 1, | |
| borderDash: [5, 5], | |
| fill: false | |
| }, | |
| { | |
| label: 'SMA (50)', | |
| data: [], | |
| borderColor: 'rgb(22, 163, 74)', | |
| backgroundColor: 'rgba(22, 163, 74, 0.1)', | |
| borderWidth: 1, | |
| borderDash: [5, 5], | |
| fill: false | |
| } | |
| ] | |
| }, | |
| options: { | |
| responsive: true, | |
| maintainAspectRatio: false, | |
| plugins: { | |
| tooltip: { | |
| mode: 'index', | |
| intersect: false, | |
| }, | |
| legend: { | |
| position: 'top', | |
| } | |
| }, | |
| scales: { | |
| x: { | |
| grid: { | |
| display: false | |
| } | |
| }, | |
| y: { | |
| beginAtZero: false | |
| } | |
| }, | |
| interaction: { | |
| mode: 'nearest', | |
| axis: 'x', | |
| intersect: false | |
| } | |
| } | |
| }); | |
| } | |
| function switchChartType(type) { | |
| chartType = type; | |
| // Reset all buttons | |
| priceChartBtn.classList.remove('bg-blue-500', 'text-white'); | |
| priceChartBtn.classList.add('bg-gray-200', 'text-gray-700'); | |
| volumeChartBtn.classList.remove('bg-blue-500', 'text-white'); | |
| volumeChartBtn.classList.add('bg-gray-200', 'text-gray-700'); | |
| rsiChartBtn.classList.remove('bg-blue-500', 'text-white'); | |
| rsiChartBtn.classList.add('bg-gray-200', 'text-gray-700'); | |
| macdChartBtn.classList.remove('bg-blue-500', 'text-white'); | |
| macdChartBtn.classList.add('bg-gray-200', 'text-gray-700'); | |
| // Activate selected button | |
| switch(type) { | |
| case 'price': | |
| priceChartBtn.classList.add('bg-blue-500', 'text-white'); | |
| priceChartBtn.classList.remove('bg-gray-200', 'text-gray-700'); | |
| updateChartForPrice(); | |
| break; | |
| case 'volume': | |
| volumeChartBtn.classList.add('bg-blue-500', 'text-white'); | |
| volumeChartBtn.classList.remove('bg-gray-200', 'text-gray-700'); | |
| updateChartForVolume(); | |
| break; | |
| case 'rsi': | |
| rsiChartBtn.classList.add('bg-blue-500', 'text-white'); | |
| rsiChartBtn.classList.remove('bg-gray-200', 'text-gray-700'); | |
| updateChartForRSI(); | |
| break; | |
| case 'macd': | |
| macdChartBtn.classList.add('bg-blue-500', 'text-white'); | |
| macdChartBtn.classList.remove('bg-gray-200', 'text-gray-700'); | |
| updateChartForMACD(); | |
| break; | |
| } | |
| } | |
| function updateChartForPrice() { | |
| // In a real app, we would fetch actual data | |
| // For demo, we'll simulate data | |
| const labels = []; | |
| const prices = []; | |
| const sma20 = []; | |
| const sma50 = []; | |
| const now = new Date(); | |
| for (let i = 30; i >= 0; i--) { | |
| const date = new Date(now); | |
| date.setDate(date.getDate() - i); | |
| labels.push(date.toLocaleDateString()); | |
| // Simulate price with some randomness | |
| const basePrice = currentCrypto === 'BTC' ? 50000 : | |
| currentCrypto === 'ETH' ? 3000 : | |
| currentCrypto === 'BNB' ? 400 : | |
| currentCrypto === 'SOL' ? 100 : 0.5; | |
| const randFactor = 0.95 + Math.random() * 0.1; | |
| prices.push((basePrice * randFactor).toFixed(2)); | |
| // Calculate SMAs (simplified) | |
| if (i < 30) { | |
| sma20.push((prices[prices.length-1] * 0.3 + prices[prices.length-2] * 0.7).toFixed(2)); | |
| } else { | |
| sma20.push(null); | |
| } | |
| if (i < 28) { | |
| sma50.push((prices[prices.length-1] * 0.2 + prices[prices.length-2] * 0.3 + prices[prices.length-3] * 0.5).toFixed(2)); | |
| } else { | |
| sma50.push(null); | |
| } | |
| } | |
| mainChart.data.labels = labels; | |
| mainChart.data.datasets[0].data = prices; | |
| mainChart.data.datasets[0].label = 'Цена ' + currentCrypto; | |
| mainChart.data.datasets[1].data = sma20; | |
| mainChart.data.datasets[2].data = sma50; | |
| // Hide other datasets | |
| for (let i = 3; i < mainChart.data.datasets.length; i++) { | |
| mainChart.data.datasets[i].hidden = true; | |
| } | |
| // Show relevant datasets | |
| mainChart.data.datasets[0].hidden = false; | |
| mainChart.data.datasets[1].hidden = !activeIndicators.includes('sma'); | |
| mainChart.data.datasets[2].hidden = !activeIndicators.includes('sma'); | |
| mainChart.update(); | |
| } | |
| function updateChartForVolume() { | |
| // Simulate volume data | |
| const labels = mainChart.data.labels; | |
| const volumes = []; | |
| for (let i = 0; i < labels.length; i++) { | |
| // Random volume with some correlation to price changes | |
| const baseVol = currentCrypto === 'BTC' ? 30000 : | |
| currentCrypto === 'ETH' ? 20000 : | |
| currentCrypto === 'BNB' ? 15000 : | |
| currentCrypto === 'SOL' ? 10000 : 5000; | |
| const randFactor = 0.7 + Math.random() * 0.6; | |
| volumes.push((baseVol * randFactor).toFixed(2)); | |
| } | |
| // Change chart to bar type for volume | |
| mainChart.config.type = 'bar'; | |
| // Update datasets | |
| mainChart.data.datasets = [ | |
| { | |
| label: 'Объем торгов', | |
| data: volumes, | |
| backgroundColor: 'rgba(99, 102, 241, 0.6)', | |
| borderColor: 'rgba(99, 102, 241, 1)', | |
| borderWidth: 1 | |
| } | |
| ]; | |
| mainChart.update(); | |
| } | |
| function updateChartForRSI() { | |
| // Simulate RSI data | |
| const labels = mainChart.data.labels; | |
| const rsiValues = []; | |
| for (let i = 0; i < labels.length; i++) { | |
| // RSI between 30 and 70 with some randomness | |
| rsiValues.push((40 + Math.random() * 40).toFixed(2)); | |
| } | |
| // Change chart back to line type | |
| mainChart.config.type = 'line'; | |
| // Update datasets | |
| mainChart.data.datasets = [ | |
| { | |
| label: 'RSI (14)', | |
| data: rsiValues, | |
| borderColor: 'rgb(219, 39, 119)', | |
| backgroundColor: 'rgba(219, 39, 119, 0.1)', | |
| borderWidth: 2, | |
| fill: true | |
| }, | |
| { | |
| label: 'Перепроданность (30)', | |
| data: Array(labels.length).fill(30), | |
| borderColor: 'rgb(22, 163, 74)', | |
| backgroundColor: 'rgba(22, 163, 74, 0.1)', | |
| borderWidth: 1, | |
| borderDash: [5, 5] | |
| }, | |
| { | |
| label: 'Перекупленность (70)', | |
| data: Array(labels.length).fill(70), | |
| borderColor: 'rgb(220, 38, 38)', | |
| backgroundColor: 'rgba(220, 38, 38, 0.1)', | |
| borderWidth: 1, | |
| borderDash: [5, 5] | |
| } | |
| ]; | |
| mainChart.update(); | |
| } | |
| function updateChartForMACD() { | |
| // Simulate MACD data | |
| const labels = mainChart.data.labels; | |
| const macdLine = []; | |
| const signalLine = []; | |
| const histogram = []; | |
| for (let i = 0; i < labels.length; i++) { | |
| // MACD line | |
| const macdValue = (Math.random() * 4 - 2).toFixed(2); | |
| macdLine.push(macdValue); | |
| // Signal line (smoothed MACD) | |
| const signalValue = (macdValue * 0.3 + (i > 0 ? macdLine[i-1] * 0.7 : 0)).toFixed(2); | |
| signalLine.push(signalValue); | |
| // Histogram (difference) | |
| histogram.push((macdValue - signalValue).toFixed(2)); | |
| } | |
| // Change chart type to bar for histogram | |
| mainChart.config.type = 'bar'; | |
| // Update datasets | |
| mainChart.data.datasets = [ | |
| { | |
| label: 'MACD Линия', | |
| data: macdLine, | |
| borderColor: 'rgb(59, 130, 246)', | |
| backgroundColor: 'rgba(59, 130, 246, 0.1)', | |
| borderWidth: 2, | |
| type: 'line' | |
| }, | |
| { | |
| label: 'Сигнальная линия', | |
| data: signalLine, | |
| borderColor: 'rgb(234, 88, 12)', | |
| backgroundColor: 'rgba(234, 88, 12, 0.1)', | |
| borderWidth: 2, | |
| type: 'line' | |
| }, | |
| { | |
| label: 'Гистограмма MACD', | |
| data: histogram, | |
| backgroundColor: histogram.map(val => val > 0 ? 'rgba(22, 163, 74, 0.7)' : 'rgba(220, 38, 38, 0.7)'), | |
| borderColor: histogram.map(val => val > 0 ? 'rgba(22, 163, 74, 1)' : 'rgba(220, 38, 38, 1)'), | |
| borderWidth: 1, | |
| type: 'bar' | |
| } | |
| ]; | |
| mainChart.update(); | |
| } | |
| function toggleIndicator(indicator, button) { | |
| const index = activeIndicators.indexOf(indicator); | |
| if (index === -1) { | |
| activeIndicators.push(indicator); | |
| button.classList.add('indicator-active'); | |
| button.classList.add('border-blue-500'); | |
| button.classList.remove('border-gray-300'); | |
| } else { | |
| activeIndicators.splice(index, 1); | |
| button.classList.remove('indicator-active'); | |
| button.classList.remove('border-blue-500'); | |
| button.classList.add('border-gray-300'); | |
| } | |
| // Update chart based on active indicators | |
| if (chartType === 'price') { | |
| updateChartForPrice(); | |
| } | |
| } | |
| function loadData() { | |
| // Show loading state | |
| refreshBtn.innerHTML = '<i class="fas fa-spinner fa-spin mr-2"></i> Загрузка...'; | |
| // Simulate API call delay | |
| setTimeout(() => { | |
| // Update price info | |
| const basePrice = currentCrypto === 'BTC' ? 50000 : | |
| currentCrypto === 'ETH' ? 3000 : | |
| currentCrypto === 'BNB' ? 400 : | |
| currentCrypto === 'SOL' ? 100 : 0.5; | |
| const priceChange = (Math.random() * 10 - 5).toFixed(2); | |
| const currentPrice = (basePrice * (1 + priceChange/100)). | |
| </html> |