Update index.html
Browse files- index.html +32 -20
index.html
CHANGED
@@ -45,7 +45,7 @@
|
|
45 |
|
46 |
<script>
|
47 |
const API_BASE = 'https://api.coingecko.com/api/v3';
|
48 |
-
const NEWS_API_KEY = '
|
49 |
const NEWS_API_URL = 'https://newsapi.org/v2/everything';
|
50 |
const resultDiv = document.getElementById('result');
|
51 |
const select = document.getElementById('crypto-select');
|
@@ -94,7 +94,7 @@
|
|
94 |
}
|
95 |
|
96 |
// Построение графика цен
|
97 |
-
function renderChart(prices, volumes) {
|
98 |
const labels = prices.map((_, index) => `Day ${index + 1}`);
|
99 |
const priceData = prices.map(price => price[1]);
|
100 |
const volumeData = volumes.map(volume => volume[1]);
|
@@ -124,6 +124,14 @@
|
|
124 |
borderWidth: 2,
|
125 |
fill: true,
|
126 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
127 |
],
|
128 |
},
|
129 |
options: {
|
@@ -138,34 +146,39 @@
|
|
138 |
}
|
139 |
|
140 |
// Анализ с помощью LSTM
|
141 |
-
async function analyzeWithLSTM(prices) {
|
142 |
-
// Подготовка данных
|
143 |
const data = prices.map(price => price[1]);
|
144 |
const normalizedData = data.map(value => value / Math.max(...data)); // Нормализация данных
|
145 |
|
146 |
const inputs = tf.tensor(normalizedData.slice(0, -1));
|
147 |
const targets = tf.tensor(normalizedData.slice(1));
|
148 |
|
149 |
-
// Создание модели
|
150 |
const model = tf.sequential();
|
151 |
model.add(tf.layers.lstm({ units: 50, inputShape: [1, 1], returnSequences: false }));
|
152 |
model.add(tf.layers.dense({ units: 1 }));
|
153 |
|
154 |
model.compile({ optimizer: 'adam', loss: 'meanSquaredError' });
|
155 |
|
156 |
-
// Тренировка
|
157 |
const inputReshaped = inputs.reshape([inputs.size, 1, 1]);
|
158 |
const targetReshaped = targets.reshape([targets.size, 1]);
|
159 |
-
await model.fit(inputReshaped, targetReshaped, { epochs: 50 });
|
160 |
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
165 |
|
166 |
-
return
|
167 |
-
? 'Цена, вероятно, вырастет. Рекомендуется держать или покупать.'
|
168 |
-
: 'Цена, вероятно, снизится. Рекомендуется продавать.';
|
169 |
}
|
170 |
|
171 |
// Обработчик кнопки
|
@@ -180,14 +193,13 @@
|
|
180 |
const data = await fetchCryptoData(crypto);
|
181 |
|
182 |
if (data) {
|
183 |
-
|
184 |
|
185 |
-
const
|
|
|
|
|
186 |
|
187 |
-
|
188 |
-
<h2 class="text-xl font-bold">${crypto.toUpperCase()}</h2>
|
189 |
-
<p>${advice}</p>
|
190 |
-
`;
|
191 |
|
192 |
const news = await fetchNews(crypto);
|
193 |
newsList.innerHTML = news
|
|
|
45 |
|
46 |
<script>
|
47 |
const API_BASE = 'https://api.coingecko.com/api/v3';
|
48 |
+
const NEWS_API_KEY = 'your_newsapi_key_here'; // Замените на ваш ключ API с https://newsapi.org/
|
49 |
const NEWS_API_URL = 'https://newsapi.org/v2/everything';
|
50 |
const resultDiv = document.getElementById('result');
|
51 |
const select = document.getElementById('crypto-select');
|
|
|
94 |
}
|
95 |
|
96 |
// Построение графика цен
|
97 |
+
function renderChart(prices, volumes, predictions = []) {
|
98 |
const labels = prices.map((_, index) => `Day ${index + 1}`);
|
99 |
const priceData = prices.map(price => price[1]);
|
100 |
const volumeData = volumes.map(volume => volume[1]);
|
|
|
124 |
borderWidth: 2,
|
125 |
fill: true,
|
126 |
},
|
127 |
+
{
|
128 |
+
label: 'Прогноз цены',
|
129 |
+
data: predictions,
|
130 |
+
borderColor: 'rgba(255, 99, 132, 1)',
|
131 |
+
borderWidth: 2,
|
132 |
+
borderDash: [5, 5],
|
133 |
+
fill: false,
|
134 |
+
},
|
135 |
],
|
136 |
},
|
137 |
options: {
|
|
|
146 |
}
|
147 |
|
148 |
// Анализ с помощью LSTM
|
149 |
+
async function analyzeWithLSTM(prices, callback) {
|
|
|
150 |
const data = prices.map(price => price[1]);
|
151 |
const normalizedData = data.map(value => value / Math.max(...data)); // Нормализация данных
|
152 |
|
153 |
const inputs = tf.tensor(normalizedData.slice(0, -1));
|
154 |
const targets = tf.tensor(normalizedData.slice(1));
|
155 |
|
|
|
156 |
const model = tf.sequential();
|
157 |
model.add(tf.layers.lstm({ units: 50, inputShape: [1, 1], returnSequences: false }));
|
158 |
model.add(tf.layers.dense({ units: 1 }));
|
159 |
|
160 |
model.compile({ optimizer: 'adam', loss: 'meanSquaredError' });
|
161 |
|
|
|
162 |
const inputReshaped = inputs.reshape([inputs.size, 1, 1]);
|
163 |
const targetReshaped = targets.reshape([targets.size, 1]);
|
|
|
164 |
|
165 |
+
const predictions = [];
|
166 |
+
|
167 |
+
// Визуализация обучения
|
168 |
+
await model.fit(inputReshaped, targetReshaped, {
|
169 |
+
epochs: 50,
|
170 |
+
callbacks: {
|
171 |
+
onEpochEnd: (epoch, logs) => {
|
172 |
+
const prediction = model.predict(inputReshaped);
|
173 |
+
const predData = prediction.dataSync();
|
174 |
+
predictions.length = 0; // Очищаем массив
|
175 |
+
predictions.push(...predData.map(v => v * Math.max(...data)));
|
176 |
+
callback(predictions);
|
177 |
+
},
|
178 |
+
},
|
179 |
+
});
|
180 |
|
181 |
+
return predictions;
|
|
|
|
|
182 |
}
|
183 |
|
184 |
// Обработчик кнопки
|
|
|
193 |
const data = await fetchCryptoData(crypto);
|
194 |
|
195 |
if (data) {
|
196 |
+
const { prices, total_volumes } = data;
|
197 |
|
198 |
+
const predictions = await analyzeWithLSTM(prices, (updatedPredictions) => {
|
199 |
+
renderChart(prices, total_volumes, updatedPredictions);
|
200 |
+
});
|
201 |
|
202 |
+
renderChart(prices, total_volumes, predictions);
|
|
|
|
|
|
|
203 |
|
204 |
const news = await fetchNews(crypto);
|
205 |
newsList.innerHTML = news
|