Spaces:
Running
Running
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Cryptocurrency Price Prediction</title> | |
| <link rel="shortcut icon" type="image/x-icon" href="https://raw.githubusercontent.com/belajarqywok/belajarqywok.github.io/main/favicon.ico"> | |
| <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet"> | |
| <script src="https://cdn.jsdelivr.net/npm/chart.js"></script> | |
| <script src="https://cdn.jsdelivr.net/npm/chartjs-adapter-date-fns@3.0.0/dist/chartjs-adapter-date-fns.bundle.min.js"></script> | |
| </head> | |
| <body onload="predict()"> | |
| <header class="bg-dark py-3 mb-4"> | |
| <div class="container"> | |
| <div class="row"> | |
| <div class="col"> | |
| <h1 class="text-white">Cryptocurrency Price Prediction</h1> | |
| </div> | |
| </div> | |
| </div> | |
| </header> | |
| <div class="container"> | |
| <div class="card shadow-sm"> | |
| <div class="card-body"> | |
| <div class="row mb-3"> | |
| <div class="col-md-3"> | |
| <label for="days" class="form-label">Days to Predict:</label> | |
| <input type="number" id="days" name="days" class="form-control" min="1" value="7" onchange="predict()"> | |
| </div> | |
| <div class="col-md-3"> | |
| <label for="crypto" class="form-label">Cryptocurrency:</label> | |
| <select id="crypto" class="form-select" onchange="predict()"> | |
| <option value="ADA-USD">ADA-USD</option> | |
| </select> | |
| </div> | |
| <div class="col-md-3 align-self-end"> | |
| <div class="spinner-border text-primary d-none" role="status" id="loadingSpinner"> | |
| <span class="visually-hidden">Loading...</span> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="row mt-4"> | |
| <div class="col"> | |
| <canvas id="myChart" width="400" height="200"></canvas> | |
| </div> | |
| </div> | |
| </div> | |
| <br \> | |
| <script> | |
| fetch('https://qywok-cryptocurrency-prediction.hf.space/crypto/lists') | |
| .then(response => response.json()) | |
| .then(data => { | |
| const cryptoList = data.data | |
| const selectCrypto = document.getElementById('crypto') | |
| selectCrypto.innerHTML = '' | |
| cryptoList.forEach(crypto => { | |
| const option = document.createElement('option') | |
| option.value = crypto | |
| option.text = crypto | |
| selectCrypto.appendChild(option) | |
| }) | |
| }) | |
| .catch(error => console.error('Error fetching crypto list:', error)) | |
| </script> | |
| <script> | |
| let myChart | |
| const predict = async () => { | |
| const days = document.getElementById('days').value | |
| const crypto = document.getElementById('crypto').value | |
| const loadingSpinner = document.getElementById('loadingSpinner') | |
| loadingSpinner.classList.remove('d-none') | |
| const apiUrl = 'https://qywok-cryptocurrency-prediction.hf.space/crypto/prediction' | |
| try { | |
| const response = await fetch(apiUrl, { | |
| method: 'POST', | |
| headers: { | |
| 'Accept': 'application/json', | |
| 'Content-Type': 'application/json' | |
| }, | |
| body: JSON.stringify({ | |
| days: days, | |
| currency: crypto | |
| }) | |
| }) | |
| if (!response.ok) throw new Error('Network response was not ok') | |
| const data = await response.json() | |
| updateChart(data) | |
| } catch (error) { | |
| console.error('Error fetching data:', error) | |
| } finally { | |
| loadingSpinner.classList.add('d-none') | |
| } | |
| } | |
| </script> | |
| <script> | |
| const updateChart = (data) => { | |
| const actualDates = data.data.predictions | |
| .actuals.map(entry => new Date(entry.date)) | |
| const actualPrices = data.data.predictions | |
| .actuals.map(entry => entry.price) | |
| const predictionDates = data.data.predictions | |
| .predictions.map(entry => new Date(entry.date)) | |
| const predictionPrices = data.data.predictions | |
| .predictions.map(entry => entry.price) | |
| const dates = [...actualDates, ...predictionDates] | |
| const prices = [...actualPrices, ...predictionPrices] | |
| if (myChart) { | |
| myChart.data.labels = dates | |
| myChart.data.datasets[0].data = actualDates.map( | |
| (date, index) => ({ x: date, y: actualPrices[index] }) | |
| ) | |
| myChart.data.datasets[1].data = predictionDates.map( | |
| (date, index) => ({ x: date, y: predictionPrices[index] }) | |
| ) | |
| myChart.update() | |
| } else { | |
| const ctx = document.getElementById('myChart').getContext('2d') | |
| myChart = new Chart(ctx, { | |
| type: 'line', | |
| data: { | |
| labels: dates, | |
| datasets: [ | |
| { | |
| label: 'Actual', | |
| data: actualDates.map( | |
| (date, index) => ({ x: date, y: actualPrices[index] }) | |
| ), | |
| borderColor: 'rgba(75, 192, 192, 1)', | |
| borderWidth: 1, | |
| fill: false, | |
| tension: 0.1 | |
| }, | |
| { | |
| label: 'Prediction', | |
| data: predictionDates.map( | |
| (date, index) => ({ x: date, y: predictionPrices[index] }) | |
| ), | |
| borderColor: 'rgba(255, 99, 132, 1)', | |
| borderWidth: 1, | |
| fill: false, | |
| tension: 0.1 | |
| } | |
| ] | |
| }, | |
| options: { | |
| scales: { | |
| x: { | |
| type: 'time', | |
| time: { | |
| unit: 'day', | |
| tooltipFormat: 'yyyy-MM-dd' | |
| }, | |
| title: { | |
| display: true, | |
| text: 'Date' | |
| } | |
| }, | |
| y: { | |
| beginAtZero: false, | |
| title: { | |
| display: true, | |
| text: 'Price (USD)' | |
| } | |
| } | |
| } | |
| } | |
| }) | |
| } | |
| } | |
| </script> | |
| </body> | |
| </html> | |