EricSam commited on
Commit
4e6a8bd
Β·
verified Β·
1 Parent(s): d60dc75

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +43 -42
index.html CHANGED
@@ -267,39 +267,39 @@
267
 
268
  // Generate Signature
269
  function generateSignature(params) {
270
- params.timestamp = Date.now();
271
- params.apiKey = API_KEY;
272
- params.recvWindow = 5000; // Optional, check BingX docs
273
- const queryString = new URLSearchParams(params).toString();
274
  return CryptoJS.HmacSHA256(queryString, API_SECRET).toString(CryptoJS.enc.Hex);
275
  }
276
 
277
  // Fetch from API
278
  async function fetchFromAPI(endpoint, params = {}) {
279
- params.timestamp = Date.now();
280
- params.apiKey = API_KEY;
281
- params.recvWindow = 5000;
282
- params.signature = generateSignature(params);
283
- const url = `${API_BASE_URL}${endpoint}?${new URLSearchParams(params)}`;
284
- const response = await fetch(url, { method: 'GET', headers: { 'X-BX-APIKEY': API_KEY } });
285
- if (!response.ok) throw new Error(`API Error: ${response.statusText}`);
 
 
286
  return response.json();
287
  }
288
 
289
  // Fetch Specific Data
290
  async function fetchBalance() {
291
- const data = await fetchFromAPI('/openApi/v1/account/balance');
292
- return data.data.balance.find(b => b.asset === 'USDT').free; // Adjust based on actual response
293
  }
294
 
295
  async function fetchOpenPositions() {
296
- const data = await fetchFromAPI('/openApi/v1/position');
297
- return data.data; // Adjust based on actual response structure
298
  }
299
 
300
  async function fetchTradeHistory() {
301
- const data = await fetchFromAPI('/openApi/v1/trade/history', { limit: 100 });
302
- return data.data; // Adjust based on actual response structure
303
  }
304
 
305
  // Helper Functions
@@ -336,12 +336,12 @@
336
  positions.forEach(pos => {
337
  tbody.innerHTML += `
338
  <tr class="border-b border-gray-200 dark:border-gray-700">
339
- <td class="py-4">${pos.symbol}</td>
340
- <td class="py-4"><span class="${pos.side === 'Long' ? 'bg-green-100 text-green-800' : 'bg-red-100 text-red-800'} px-2 py-1 rounded">${pos.side}</span></td>
341
- <td class="py-4">${pos.quantity}</td>
342
- <td class="py-4">$${pos.entryPrice.toFixed(2)}</td>
343
- <td class="py-4 font-medium">$${pos.markPrice.toFixed(2)}</td>
344
- <td class="py-4 font-bold ${pos.unrealizedProfit > 0 ? 'text-green-500' : 'text-red-500'}">$${pos.unrealizedProfit.toFixed(2)}</td>
345
  <td class="py-4"><span class="px-2 py-1 rounded bg-blue-100 text-blue-800">Open</span></td>
346
  <td class="py-4 text-right"><button class="text-gray-400 hover:text-primary"><i class="fas fa-ellipsis-v"></i></button></td>
347
  </tr>`;
@@ -349,12 +349,12 @@
349
  trades.slice(0, 5).forEach(trade => {
350
  tbody.innerHTML += `
351
  <tr class="border-b border-gray-200 dark:border-gray-700">
352
- <td class="py-4">${trade.symbol}</td>
353
- <td class="py-4"><span class="${trade.side === 'Long' ? 'bg-green-100 text-green-800' : 'bg-red-100 text-red-800'} px-2 py-1 rounded">${trade.side}</span></td>
354
- <td class="py-4">${trade.quantity}</td>
355
- <td class="py-4">$${trade.entryPrice.toFixed(2)}</td>
356
- <td class="py-4 font-medium">$${trade.exitPrice.toFixed(2)}</td>
357
- <td class="py-4 font-bold ${trade.realizedProfit > 0 ? 'text-green-500' : 'text-red-500'}">$${trade.realizedProfit.toFixed(2)}</td>
358
  <td class="py-4"><span class="px-2 py-1 rounded bg-gray-100 text-gray-800">Closed</span></td>
359
  <td class="py-4 text-right"><button class="text-gray-400 hover:text-primary"><i class="fas fa-ellipsis-v"></i></button></td>
360
  </tr>`;
@@ -375,7 +375,7 @@
375
 
376
  function updatePerformanceChart(trades) {
377
  const monthlyPL = trades.reduce((acc, trade) => {
378
- const month = new Date(trade.closeTime).toLocaleString('default', { month: 'short' });
379
  acc[month] = (acc[month] || 0) + (trade.realizedProfit || 0);
380
  return acc;
381
  }, {});
@@ -385,21 +385,21 @@
385
  }
386
 
387
  function updateAllocationChart(allocation) {
388
- allocationChart.data.labels = allocation.labels;
389
- allocationChart.data.datasets[0].data = allocation.data;
390
  allocationChart.update();
391
  const legend = document.getElementById('allocation-legend');
392
  legend.innerHTML = allocation.labels.map((label, i) => `
393
  <div class="mb-3">
394
  <div class="flex justify-between mb-1">
395
  <span class="text-gray-500 dark:text-gray-400 flex items-center">
396
- <span class="h-3 w-3 bg-[${allocationChart.data.datasets[0].backgroundColor[i]}] rounded-full mr-2"></span>
397
- ${label}
398
  </span>
399
- <span class="font-medium dark:text-white">${allocation.data[i].toFixed(1)}%</span>
400
  </div>
401
  <div class="w-full bg-gray-200 rounded-full h-2 dark:bg-gray-700">
402
- <div class="bg-[${allocationChart.data.datasets[0].backgroundColor[i]}] h-2 rounded-full" style="width: ${allocation.data[i]}%"></div>
403
  </div>
404
  </div>`).join('');
405
  }
@@ -416,9 +416,9 @@
416
  fetchTradeHistory()
417
  ]);
418
 
419
- document.getElementById('total-balance').textContent = `$${balance.toFixed(2)}`;
420
  document.getElementById('open-trades').textContent = positions.length;
421
- const longCount = positions.filter(p => p.side === 'Long').length;
422
  document.getElementById('trade-types').innerHTML = `<span class="font-medium">${longCount} Long</span><span class="text-gray-500 mx-2 dark:text-gray-400">β€’</span><span class="font-medium">${positions.length - longCount} Short</span>`;
423
  const todayProfit = calculateTodayProfit(trades);
424
  document.getElementById('today-profit').textContent = `$${todayProfit.toFixed(2)}`;
@@ -433,11 +433,12 @@
433
  const allocation = calculatePortfolioAllocation(positions);
434
  updateAllocationChart(allocation);
435
 
436
- document.getElementById('last-sync').textContent = `Last synced: ${new Date().toLocaleTimeString()}`;
437
- document.getElementById('allocation-update').textContent = `Last updated: ${new Date().toLocaleTimeString()}`;
 
438
  } catch (error) {
439
  console.error('Error fetching data:', error);
440
- alert('Failed to sync with BingX API. Please check your API credentials or network.');
441
  }
442
  }
443
 
@@ -445,7 +446,7 @@
445
  document.getElementById('refresh-btn').addEventListener('click', fetchData);
446
  document.getElementById('sync-now').addEventListener('click', fetchData);
447
  window.addEventListener('load', fetchData);
448
- setInterval(fetchData, 120000); // Increased to 2 minutes to avoid rate limiting
449
  </script>
450
  <p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px; position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle; display:inline-block; margin-right:3px; filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff; text-decoration: underline;" target="_blank">DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=EricSam/bingx-monitoring" style="color: #fff; text-decoration: underline;" target="_blank">Remix</a></p>
451
  </body>
 
267
 
268
  // Generate Signature
269
  function generateSignature(params) {
270
+ const sortedParams = Object.fromEntries(Object.entries(params).sort());
271
+ const queryString = new URLSearchParams(sortedParams).toString();
 
 
272
  return CryptoJS.HmacSHA256(queryString, API_SECRET).toString(CryptoJS.enc.Hex);
273
  }
274
 
275
  // Fetch from API
276
  async function fetchFromAPI(endpoint, params = {}) {
277
+ params.timestamp = Date.now().toString();
278
+ params.recvWindow = '5000'; // 5-second window, per BingX requirements
279
+ const signature = generateSignature(params);
280
+ const url = `${API_BASE_URL}${endpoint}?${new URLSearchParams({ ...params, signature })}`;
281
+ const response = await fetch(url, {
282
+ method: 'GET',
283
+ headers: { 'X-BX-APIKEY': API_KEY }
284
+ });
285
+ if (!response.ok) throw new Error(`API Error: ${response.status} - ${await response.text()}`);
286
  return response.json();
287
  }
288
 
289
  // Fetch Specific Data
290
  async function fetchBalance() {
291
+ const data = await fetchFromAPI('/openApi/swap/v2/account/balance');
292
+ return data.data.find(b => b.asset === 'USDT')?.balance || 0; // Adjust based on actual response
293
  }
294
 
295
  async function fetchOpenPositions() {
296
+ const data = await fetchFromAPI('/openApi/swap/v2/position');
297
+ return data.data || []; // Adjust based on actual response structure
298
  }
299
 
300
  async function fetchTradeHistory() {
301
+ const data = await fetchFromAPI('/openApi/swap/v2/trade/history', { limit: 100 });
302
+ return data.data || []; // Adjust based on actual response structure
303
  }
304
 
305
  // Helper Functions
 
336
  positions.forEach(pos => {
337
  tbody.innerHTML += `
338
  <tr class="border-b border-gray-200 dark:border-gray-700">
339
+ <td class="py-4">${pos.symbol || 'N/A'}</td>
340
+ <td class="py-4"><span class="${pos.side === 'LONG' ? 'bg-green-100 text-green-800' : 'bg-red-100 text-red-800'} px-2 py-1 rounded">${pos.side || 'N/A'}</span></td>
341
+ <td class="py-4">${pos.quantity || 0}</td>
342
+ <td class="py-4">$${parseFloat(pos.entryPrice || 0).toFixed(2)}</td>
343
+ <td class="py-4 font-medium">$${parseFloat(pos.markPrice || 0).toFixed(2)}</td>
344
+ <td class="py-4 font-bold ${parseFloat(pos.unrealizedProfit || 0) > 0 ? 'text-green-500' : 'text-red-500'}">$${parseFloat(pos.unrealizedProfit || 0).toFixed(2)}</td>
345
  <td class="py-4"><span class="px-2 py-1 rounded bg-blue-100 text-blue-800">Open</span></td>
346
  <td class="py-4 text-right"><button class="text-gray-400 hover:text-primary"><i class="fas fa-ellipsis-v"></i></button></td>
347
  </tr>`;
 
349
  trades.slice(0, 5).forEach(trade => {
350
  tbody.innerHTML += `
351
  <tr class="border-b border-gray-200 dark:border-gray-700">
352
+ <td class="py-4">${trade.symbol || 'N/A'}</td>
353
+ <td class="py-4"><span class="${trade.side === 'LONG' ? 'bg-green-100 text-green-800' : 'bg-red-100 text-red-800'} px-2 py-1 rounded">${trade.side || 'N/A'}</span></td>
354
+ <td class="py-4">${trade.quantity || 0}</td>
355
+ <td class="py-4">$${parseFloat(trade.entryPrice || 0).toFixed(2)}</td>
356
+ <td class="py-4 font-medium">$${parseFloat(trade.exitPrice || 0).toFixed(2)}</td>
357
+ <td class="py-4 font-bold ${parseFloat(trade.realizedProfit || 0) > 0 ? 'text-green-500' : 'text-red-500'}">$${parseFloat(trade.realizedProfit || 0).toFixed(2)}</td>
358
  <td class="py-4"><span class="px-2 py-1 rounded bg-gray-100 text-gray-800">Closed</span></td>
359
  <td class="py-4 text-right"><button class="text-gray-400 hover:text-primary"><i class="fas fa-ellipsis-v"></i></button></td>
360
  </tr>`;
 
375
 
376
  function updatePerformanceChart(trades) {
377
  const monthlyPL = trades.reduce((acc, trade) => {
378
+ const month = new Date(trade.closeTime || Date.now()).toLocaleString('default', { month: 'short' });
379
  acc[month] = (acc[month] || 0) + (trade.realizedProfit || 0);
380
  return acc;
381
  }, {});
 
385
  }
386
 
387
  function updateAllocationChart(allocation) {
388
+ allocationChart.data.labels = allocation.labels.length ? allocation.labels : ['No Data'];
389
+ allocationChart.data.datasets[0].data = allocation.data.length ? allocation.data : [100];
390
  allocationChart.update();
391
  const legend = document.getElementById('allocation-legend');
392
  legend.innerHTML = allocation.labels.map((label, i) => `
393
  <div class="mb-3">
394
  <div class="flex justify-between mb-1">
395
  <span class="text-gray-500 dark:text-gray-400 flex items-center">
396
+ <span class="h-3 w-3 bg-[${allocationChart.data.datasets[0].backgroundColor[i % 4]}] rounded-full mr-2"></span>
397
+ ${label || 'N/A'}
398
  </span>
399
+ <span class="font-medium dark:text-white">${allocation.data[i] ? allocation.data[i].toFixed(1) : 0}%</span>
400
  </div>
401
  <div class="w-full bg-gray-200 rounded-full h-2 dark:bg-gray-700">
402
+ <div class="bg-[${allocationChart.data.datasets[0].backgroundColor[i % 4]}] h-2 rounded-full" style="width: ${allocation.data[i] || 0}%"></div>
403
  </div>
404
  </div>`).join('');
405
  }
 
416
  fetchTradeHistory()
417
  ]);
418
 
419
+ document.getElementById('total-balance').textContent = `$${parseFloat(balance).toFixed(2)}`;
420
  document.getElementById('open-trades').textContent = positions.length;
421
+ const longCount = positions.filter(p => p.side === 'LONG').length;
422
  document.getElementById('trade-types').innerHTML = `<span class="font-medium">${longCount} Long</span><span class="text-gray-500 mx-2 dark:text-gray-400">β€’</span><span class="font-medium">${positions.length - longCount} Short</span>`;
423
  const todayProfit = calculateTodayProfit(trades);
424
  document.getElementById('today-profit').textContent = `$${todayProfit.toFixed(2)}`;
 
433
  const allocation = calculatePortfolioAllocation(positions);
434
  updateAllocationChart(allocation);
435
 
436
+ const now = new Date().toLocaleString('en-US', { timeZone: 'Asia/Singapore', hour12: false });
437
+ document.getElementById('last-sync').textContent = `Last synced: ${now}`;
438
+ document.getElementById('allocation-update').textContent = `Last updated: ${now}`;
439
  } catch (error) {
440
  console.error('Error fetching data:', error);
441
+ alert(`Failed to sync with BingX API. Please check your API credentials, IP whitelisting, or network. Details: ${error.message}`);
442
  }
443
  }
444
 
 
446
  document.getElementById('refresh-btn').addEventListener('click', fetchData);
447
  document.getElementById('sync-now').addEventListener('click', fetchData);
448
  window.addEventListener('load', fetchData);
449
+ setInterval(fetchData, 120000); // Refresh every 2 minutes to avoid rate limiting
450
  </script>
451
  <p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px; position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle; display:inline-block; margin-right:3px; filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff; text-decoration: underline;" target="_blank">DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=EricSam/bingx-monitoring" style="color: #fff; text-decoration: underline;" target="_blank">Remix</a></p>
452
  </body>