File size: 8,205 Bytes
e859d8e
 
 
 
 
 
5e4dd46
 
 
e859d8e
5e4dd46
c2d59df
5e4dd46
c2d59df
5e4dd46
 
c2d59df
 
 
5e4dd46
 
c2d59df
5e4dd46
 
 
 
 
 
c2d59df
5e4dd46
 
 
 
 
 
c2d59df
 
 
 
 
 
 
 
e859d8e
11a6361
e859d8e
5e4dd46
9686866
c2d59df
e859d8e
 
 
5e4dd46
c2d59df
5e4dd46
11a6361
5e4dd46
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
e859d8e
 
5e4dd46
e859d8e
5e4dd46
e859d8e
5e4dd46
 
e859d8e
 
3d74982
c2d59df
 
 
 
 
 
 
 
 
 
 
 
5e4dd46
9686866
5e4dd46
c2d59df
 
5e4dd46
 
 
e859d8e
5e4dd46
 
 
 
 
 
 
 
c2d59df
5e4dd46
 
 
 
 
c2d59df
 
 
 
 
 
 
 
9686866
 
 
 
 
 
 
 
5e4dd46
 
 
 
 
 
c2d59df
5e4dd46
 
 
 
 
 
c2d59df
9686866
5e4dd46
c2d59df
5e4dd46
c2d59df
 
 
5e4dd46
c2d59df
5e4dd46
 
 
 
c2d59df
 
5e4dd46
9686866
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5e4dd46
9686866
868baee
11a6361
5e4dd46
e859d8e
5e4dd46
 
 
 
 
 
 
 
 
e859d8e
9686866
5e4dd46
9686866
 
 
5e4dd46
9686866
c2d59df
 
 
 
 
 
e859d8e
 
5e4dd46
 
 
e859d8e
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <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>
</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 flex-wrap">
      <select id="crypto-select" class="p-2 border border-gray-300 rounded-md shadow-md w-full sm:w-auto">
        <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 sm:w-auto">
        Получить совет
      </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"></canvas>
    </div>

    <!-- Новости -->
    <div id="news-section" class="mt-6 bg-white p-6 rounded-md shadow-md">
      <h2 class="text-xl font-bold mb-4">Новости</h2>
      <ul id="news-list" class="list-disc pl-5">
        <li class="text-gray-500">Здесь появятся новости о криптовалютах.</li>
      </ul>
    </div>
  </div>

  <script>
    const API_BASE = 'https://api.coingecko.com/api/v3';
    const NEWS_API_KEY = 'your_newsapi_key_here'; // Замените на ваш ключ API с https://newsapi.org/
    const NEWS_API_URL = 'https://newsapi.org/v2/everything';
    const resultDiv = document.getElementById('result');
    const select = document.getElementById('crypto-select');
    const button = document.getElementById('get-advice');
    const chartCanvas = document.getElementById('crypto-chart');
    const newsList = document.getElementById('news-list');
    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) // Ограничиваем список первыми 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>`;
      }
    }

    // Загрузка новостей
    async function fetchNews(query) {
      try {
        const response = await fetch(`${NEWS_API_URL}?q=${query}&apiKey=${NEWS_API_KEY}`);
        const data = await response.json();
        return data.articles;
      } catch (error) {
        console.error('Ошибка при загрузке новостей:', error);
        newsList.innerHTML = `<li class="text-red-500">Ошибка при загрузке новостей.</li>`;
      }
    }

    // Построение графика цен
    function renderChart(prices, volumes, predictions = []) {
      const labels = prices.map((_, index) => `Day ${index + 1}`);
      const priceData = prices.map(price => price[1]);
      const volumeData = volumes.map(volume => volume[1]);

      if (chartInstance) {
        chartInstance.destroy(); // Уничтожаем старый график, если он существует
      }

      chartInstance = new Chart(chartCanvas, {
        type: 'line',
        data: {
          labels: labels,
          datasets: [
            {
              label: 'Цена (USD)',
              data: priceData,
              backgroundColor: 'rgba(59, 130, 246, 0.2)',
              borderColor: 'rgba(59, 130, 246, 1)',
              borderWidth: 2,
              fill: true,
            },
            {
              label: 'Объем торгов (USD)',
              data: volumeData,
              backgroundColor: 'rgba(34, 197, 94, 0.2)',
              borderColor: 'rgba(34, 197, 94, 1)',
              borderWidth: 2,
              fill: true,
            },
            {
              label: 'Прогноз цены',
              data: predictions,
              borderColor: 'rgba(255, 99, 132, 1)',
              borderWidth: 2,
              borderDash: [5, 5],
              fill: false,
            },
          ],
        },
        options: {
          responsive: true,
          plugins: {
            legend: {
              display: true,
            },
          },
        },
      });
    }

    // Анализ с помощью LSTM
    async function analyzeWithLSTM(prices, callback) {
      const data = prices.map(price => price[1]);
      const normalizedData = data.map(value => value / Math.max(...data)); // Нормализация данных

      const inputs = tf.tensor(normalizedData.slice(0, -1));
      const targets = tf.tensor(normalizedData.slice(1));

      const model = tf.sequential();
      model.add(tf.layers.lstm({ units: 50, inputShape: [1, 1], returnSequences: false }));
      model.add(tf.layers.dense({ units: 1 }));

      model.compile({ optimizer: 'adam', loss: 'meanSquaredError' });

      const inputReshaped = inputs.reshape([inputs.size, 1, 1]);
      const targetReshaped = targets.reshape([targets.size, 1]);

      const predictions = [];

      // Визуализация обучения
      await model.fit(inputReshaped, targetReshaped, {
        epochs: 50,
        callbacks: {
          onEpochEnd: (epoch, logs) => {
            const prediction = model.predict(inputReshaped);
            const predData = prediction.dataSync();
            predictions.length = 0; // Очищаем массив
            predictions.push(...predData.map(v => v * Math.max(...data)));
            callback(predictions);
          },
        },
      });

      return predictions;
    }

    // Обработчик кнопки
    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) {
        const { prices, total_volumes } = data;

        const predictions = await analyzeWithLSTM(prices, (updatedPredictions) => {
          renderChart(prices, total_volumes, updatedPredictions);
        });

        renderChart(prices, total_volumes, predictions);

        const news = await fetchNews(crypto);
        newsList.innerHTML = news
          .slice(0, 5)
          .map(article => `<li><a href="${article.url}" target="_blank" class="text-blue-500">${article.title}</a></li>`)
          .join('');
      }
    });

    // Инициализация
    loadCryptos();
  </script>
</body>
</html>