|
<!DOCTYPE html> |
|
<html lang="en"> |
|
<head> |
|
<meta charset="UTF-8"> |
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"> |
|
<title>Crypto Trading Advisor</title> |
|
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script> |
|
<script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs"></script> |
|
<script src="https://cdn.tailwindcss.com"></script> |
|
<style> |
|
@media (max-width: 768px) { |
|
.container { |
|
padding: 1rem; |
|
} |
|
.text-3xl { |
|
font-size: 1.5rem; |
|
} |
|
.text-xl { |
|
font-size: 1rem; |
|
} |
|
.px-4 { |
|
padding-left: 1rem; |
|
padding-right: 1rem; |
|
} |
|
.py-2 { |
|
padding-top: 0.5rem; |
|
padding-bottom: 0.5rem; |
|
} |
|
} |
|
</style> |
|
</head> |
|
<body class="bg-gray-100 text-gray-800 font-sans"> |
|
<div class="container mx-auto p-4"> |
|
<h1 class="text-3xl font-bold text-center mb-6">Crypto Trading Advisor</h1> |
|
|
|
|
|
<div class="flex justify-center mb-4"> |
|
<select id="crypto-select" class="p-2 border border-gray-300 rounded-md shadow-md w-full"> |
|
<option value="">Загрузка криптовалют...</option> |
|
</select> |
|
<button id="get-advice" class="ml-4 px-4 py-2 bg-blue-500 text-white rounded-md shadow-md hover:bg-blue-600 w-full"> |
|
Получить совет |
|
</button> |
|
</div> |
|
|
|
|
|
<div id="result" class="bg-white p-6 rounded-md shadow-md"> |
|
<p class="text-center text-gray-500">Выберите криптовалюту, чтобы увидеть советы и графики.</p> |
|
</div> |
|
|
|
|
|
<div class="mt-6"> |
|
<canvas id="crypto-chart" class="bg-white p-4 rounded-md shadow-md w-full"></canvas> |
|
</div> |
|
</div> |
|
|
|
<script> |
|
const API_BASE = 'https://api.coingecko.com/api/v3'; |
|
const resultDiv = document.getElementById('result'); |
|
const select = document.getElementById('crypto-select'); |
|
const button = document.getElementById('get-advice'); |
|
const chartCanvas = document.getElementById('crypto-chart'); |
|
let chartInstance; |
|
|
|
|
|
async function loadCryptos() { |
|
try { |
|
const response = await fetch(`${API_BASE}/coins/list`); |
|
const data = await response.json(); |
|
select.innerHTML = data |
|
.slice(0, 50) |
|
.map(coin => `<option value="${coin.id}">${coin.name} (${coin.symbol.toUpperCase()})</option>`) |
|
.join(''); |
|
} catch (error) { |
|
console.error('Ошибка при загрузке списка криптовалют:', error); |
|
select.innerHTML = '<option>Ошибка загрузки...</option>'; |
|
} |
|
} |
|
|
|
|
|
async function fetchCryptoData(crypto) { |
|
try { |
|
const response = await fetch(`${API_BASE}/coins/${crypto}/market_chart?vs_currency=usd&days=30`); |
|
const data = await response.json(); |
|
return data; |
|
} catch (error) { |
|
console.error('Ошибка при загрузке данных о криптовалюте:', error); |
|
resultDiv.innerHTML = `<p class="text-red-500">Ошибка при загрузке данных. Попробуйте позже.</p>`; |
|
} |
|
} |
|
|
|
|
|
function renderChart(prices) { |
|
const labels = prices.map((_, index) => `Day ${index + 1}`); |
|
const data = prices.map(price => price[1]); |
|
|
|
if (chartInstance) { |
|
chartInstance.destroy(); |
|
} |
|
|
|
chartInstance = new Chart(chartCanvas, { |
|
type: 'line', |
|
data: { |
|
labels: labels, |
|
datasets: [ |
|
{ |
|
label: 'Цена (USD)', |
|
data: data, |
|
backgroundColor: 'rgba(59, 130, 246, 0.2)', |
|
borderColor: 'rgba(59, 130, 246, 1)', |
|
borderWidth: 2, |
|
fill: true, |
|
}, |
|
], |
|
}, |
|
options: { |
|
responsive: true, |
|
plugins: { |
|
legend: { |
|
display: false, |
|
}, |
|
}, |
|
}, |
|
}); |
|
} |
|
|
|
|
|
async function analyzeWithNeuralNetwork(prices) { |
|
|
|
const data = prices.map(price => price[1]); |
|
const inputs = tf.tensor(data.slice(0, -1)); |
|
const targets = tf.tensor(data.slice(1)); |
|
|
|
|
|
const model = tf.sequential(); |
|
model.add(tf.layers.dense({ units: 10, activation: 'relu', inputShape: [1] })); |
|
model.add(tf.layers.dense({ units: 1 })); |
|
|
|
model.compile({ optimizer: 'adam', loss: 'meanSquaredError' }); |
|
|
|
|
|
await model.fit(inputs.reshape([inputs.size, 1]), targets.reshape([targets.size, 1]), { |
|
epochs: 50, |
|
}); |
|
|
|
|
|
const prediction = model.predict(tf.tensor([data[data.length - 1]]).reshape([1, 1])); |
|
const predictedValue = prediction.dataSync()[0]; |
|
|
|
return predictedValue > data[data.length - 1] |
|
? 'Цена, вероятно, вырастет. Рекомендуется держать или покупать.' |
|
: 'Цена, вероятно, снизится. Рекомендуется продавать.'; |
|
} |
|
|
|
|
|
button.addEventListener('click', async () => { |
|
const crypto = select.value; |
|
if (!crypto) { |
|
resultDiv.innerHTML = `<p class="text-red-500">Выберите криптовалюту.</p>`; |
|
return; |
|
} |
|
|
|
resultDiv.innerHTML = '<p class="text-gray-500">Загрузка данных...</p>'; |
|
const data = await fetchCryptoData(crypto); |
|
|
|
if (data) { |
|
|
|
renderChart(data.prices); |
|
|
|
|
|
const advice = await analyzeWithNeuralNetwork(data.prices); |
|
|
|
|
|
resultDiv.innerHTML = ` |
|
<h2 class="text-xl font-bold">${crypto.toUpperCase()}</h2> |
|
<p>${advice}</p> |
|
`; |
|
} |
|
}); |
|
|
|
|
|
loadCryptos(); |
|
</script> |
|
</body> |
|
</html> |