fre / index.html
luguog's picture
Create index.html
4ab1a62 verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>CYBERGRID - Rotten Market Dominator</title>
<script src="https://cdn.tailwindcss.com"></script>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script src="https://cdn.jsdelivr.net/npm/ccxt"></script>
<style>
@import url('https://fonts.googleapis.com/css2?family=Orbitron:wght@400;700&family=Share+Tech+Mono&display=swap');
:root {
--rotten-orange: #ff6d00;
--cyber-purple: #7b2cbf;
--neon-blue: #00f5d4;
--dark-bg: #0a0a0a;
}
body {
font-family: 'Share Tech Mono', monospace;
background-color: var(--dark-bg);
color: white;
background-image:
radial-gradient(circle at 10% 20%, rgba(255, 109, 0, 0.05) 0%, transparent 20%),
radial-gradient(circle at 90% 80%, rgba(123, 44, 191, 0.05) 0%, transparent 20%),
linear-gradient(to bottom, transparent, rgba(0, 0, 0, 0.8));
overflow-x: hidden;
}
.cyber-font {
font-family: 'Orbitron', sans-serif;
}
.rotten-texture {
position: relative;
}
.rotten-texture::after {
content: "";
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background:
linear-gradient(45deg,
transparent 48%,
rgba(255, 109, 0, 0.1) 48%,
rgba(255, 109, 0, 0.1) 52%,
transparent 52%),
linear-gradient(-45deg,
transparent 48%,
rgba(255, 109, 0, 0.1) 48%,
rgba(255, 109, 0, 0.1) 52%,
transparent 52%);
background-size: 10px 10px;
pointer-events: none;
}
.glitch-effect {
text-shadow:
0.05em 0 0 rgba(255, 0, 0, 0.7),
-0.05em -0.025em 0 rgba(0, 255, 0, 0.7),
-0.025em 0.05em 0 rgba(0, 0, 255, 0.7);
animation: glitch 500ms infinite;
}
@keyframes glitch {
0% { text-shadow: 0.05em 0 0 rgba(255, 0, 0, 0.7), -0.05em -0.025em 0 rgba(0, 255, 0, 0.7), -0.025em 0.05em 0 rgba(0, 0, 255, 0.7); }
14% { text-shadow: 0.05em 0 0 rgba(255, 0, 0, 0.7), -0.05em -0.025em 0 rgba(0, 255, 0, 0.7), -0.025em 0.05em 0 rgba(0, 0, 255, 0.7); }
15% { text-shadow: -0.05em -0.025em 0 rgba(255, 0, 0, 0.7), 0.025em 0.025em 0 rgba(0, 255, 0, 0.7), -0.05em -0.05em 0 rgba(0, 0, 255, 0.7); }
49% { text-shadow: -0.05em -0.025em 0 rgba(255, 0, 0, 0.7), 0.025em 0.025em 0 rgba(0, 255, 0, 0.7), -0.05em -0.05em 0 rgba(0, 0, 255, 0.7); }
50% { text-shadow: 0.025em 0.05em 0 rgba(255, 0, 0, 0.7), 0.05em 0 0 rgba(0, 255, 0, 0.7), 0 -0.05em 0 rgba(0, 0, 255, 0.7); }
99% { text-shadow: 0.025em 0.05em 0 rgba(255, 0, 0, 0.7), 0.05em 0 0 rgba(0, 255, 0, 0.7), 0 -0.05em 0 rgba(0, 0, 255, 0.7); }
100% { text-shadow: -0.025em 0 0 rgba(255, 0, 0, 0.7), -0.025em -0.025em 0 rgba(0, 255, 0, 0.7), -0.025em -0.05em 0 rgba(0, 0, 255, 0.7); }
}
.neon-pulse {
animation: neon-pulse 2s infinite alternate;
}
@keyframes neon-pulse {
from { box-shadow: 0 0 5px rgba(0, 245, 212, 0.3), 0 0 10px rgba(0, 245, 212, 0.2); }
to { box-shadow: 0 0 15px rgba(0, 245, 212, 0.6), 0 0 30px rgba(0, 245, 212, 0.4); }
}
.terminal-scroll::-webkit-scrollbar {
width: 8px;
height: 8px;
}
.terminal-scroll::-webkit-scrollbar-track {
background: rgba(0, 0, 0, 0.2);
}
.terminal-scroll::-webkit-scrollbar-thumb {
background: var(--rotten-orange);
border-radius: 4px;
}
.terminal-scroll::-webkit-scrollbar-thumb:hover {
background: var(--cyber-purple);
}
.grid-cell {
transition: all 0.3s ease;
}
.grid-cell:hover {
transform: scale(1.05);
box-shadow: 0 0 15px rgba(123, 44, 191, 0.5);
}
.search-dropdown {
max-height: 300px;
overflow-y: auto;
scrollbar-width: thin;
}
.search-dropdown::-webkit-scrollbar {
width: 6px;
}
.search-dropdown::-webkit-scrollbar-thumb {
background-color: var(--rotten-orange);
border-radius: 3px;
}
</style>
</head>
<body class="min-h-screen">
<div class="rotten-texture">
<!-- Header -->
<header class="bg-black bg-opacity-70 border-b border-purple-900 py-4 px-6 flex justify-between items-center sticky top-0 z-50 backdrop-blur-sm">
<div class="flex items-center space-x-4">
<div class="w-10 h-10 bg-gradient-to-br from-orange-600 to-purple-800 rounded-full flex items-center justify-center neon-pulse">
<span class="cyber-font text-xl"></span>
</div>
<h1 class="cyber-font text-2xl md:text-3xl bg-clip-text text-transparent bg-gradient-to-r from-orange-500 via-purple-500 to-blue-400">
CYBER<span class="glitch-effect">GRID</span>
</h1>
</div>
<div class="flex items-center space-x-4">
<div class="hidden md:block px-4 py-2 bg-gray-900 rounded-lg text-sm">
<span class="text-gray-400">STATUS:</span>
<span id="connection-status" class="ml-2 text-green-400">CONNECTED</span>
</div>
<div class="px-4 py-2 bg-gray-900 rounded-lg text-sm">
<span class="text-gray-400">TIME:</span>
<span id="current-time" class="ml-2">00:00:00</span>
</div>
</div>
</header>
<!-- Main Content -->
<main class="container mx-auto px-4 py-6">
<div class="grid grid-cols-1 lg:grid-cols-3 gap-6">
<!-- Left Panel -->
<div class="lg:col-span-2 space-y-6">
<!-- Market Selector -->
<div class="bg-gray-900 bg-opacity-70 rounded-xl border border-purple-900 p-4">
<div class="flex flex-col md:flex-row md:items-center md:justify-between space-y-4 md:space-y-0">
<h2 class="cyber-font text-xl text-orange-400">MARKET DOMINATOR</h2>
<div class="relative w-full md:w-64">
<input type="text" id="pair-search" placeholder="Search trading pair..."
class="w-full bg-gray-800 border border-purple-700 rounded-lg px-4 py-2 focus:outline-none focus:ring-2 focus:ring-purple-500">
<div id="search-results" class="hidden absolute z-10 mt-1 w-full bg-gray-900 border border-purple-700 rounded-lg shadow-lg search-dropdown"></div>
</div>
</div>
<div class="mt-6 grid grid-cols-1 md:grid-cols-3 gap-4">
<div class="bg-gray-800 bg-opacity-50 rounded-lg p-4 border border-orange-900 grid-cell">
<div class="text-gray-400 text-sm">SELECTED PAIR</div>
<div id="selected-pair" class="cyber-font text-xl text-purple-300 mt-1">-/-</div>
</div>
<div class="bg-gray-800 bg-opacity-50 rounded-lg p-4 border border-purple-900 grid-cell">
<div class="text-gray-400 text-sm">CURRENT PRICE</div>
<div id="current-price" class="cyber-font text-xl text-orange-400 mt-1">$0.00</div>
</div>
<div class="bg-gray-800 bg-opacity-50 rounded-lg p-4 border border-blue-900 grid-cell">
<div class="text-gray-400 text-sm">24H VOLUME</div>
<div id="daily-volume" class="cyber-font text-xl text-blue-400 mt-1">$0.00</div>
</div>
</div>
</div>
<!-- Price Chart -->
<div class="bg-gray-900 bg-opacity-70 rounded-xl border border-purple-900 p-4">
<div class="flex justify-between items-center mb-4">
<h2 class="cyber-font text-xl text-orange-400">PRICE CHART</h2>
<div class="flex space-x-2">
<button class="px-3 py-1 bg-gray-800 rounded-lg text-xs border border-purple-700 hover:bg-purple-900">1H</button>
<button class="px-3 py-1 bg-gray-800 rounded-lg text-xs border border-purple-700 hover:bg-purple-900">4H</button>
<button class="px-3 py-1 bg-purple-900 rounded-lg text-xs border border-purple-700">1D</button>
<button class="px-3 py-1 bg-gray-800 rounded-lg text-xs border border-purple-700 hover:bg-purple-900">1W</button>
</div>
</div>
<div class="h-64 md:h-80">
<canvas id="price-chart"></canvas>
</div>
</div>
<!-- Order Grid -->
<div class="bg-gray-900 bg-opacity-70 rounded-xl border border-purple-900 p-4">
<div class="flex justify-between items-center mb-4">
<h2 class="cyber-font text-xl text-orange-400">GRID ORDERS</h2>
<div class="flex items-center space-x-2">
<span class="text-gray-400 text-sm">GRID SPACING:</span>
<input type="number" id="grid-spacing" value="0.02" step="0.01" min="0.01"
class="w-20 bg-gray-800 border border-purple-700 rounded-lg px-2 py-1 text-sm focus:outline-none focus:ring-1 focus:ring-purple-500">
</div>
</div>
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
<div>
<h3 class="text-purple-400 mb-2">BUY ORDERS</h3>
<div id="buy-orders" class="space-y-2 max-h-60 overflow-y-auto terminal-scroll"></div>
</div>
<div>
<h3 class="text-orange-400 mb-2">SELL ORDERS</h3>
<div id="sell-orders" class="space-y-2 max-h-60 overflow-y-auto terminal-scroll"></div>
</div>
</div>
</div>
</div>
<!-- Right Panel -->
<div class="space-y-6">
<!-- Bot Controls -->
<div class="bg-gray-900 bg-opacity-70 rounded-xl border border-purple-900 p-4">
<h2 class="cyber-font text-xl text-orange-400 mb-4">BOT CONTROLS</h2>
<div class="space-y-4">
<div>
<label class="block text-gray-400 text-sm mb-1">ORDER SIZE (USDT)</label>
<input type="number" id="order-size" value="3" min="1" step="1"
class="w-full bg-gray-800 border border-purple-700 rounded-lg px-3 py-2 focus:outline-none focus:ring-1 focus:ring-purple-500">
</div>
<div>
<label class="block text-gray-400 text-sm mb-1">TOTAL DEPOSIT (USDT)</label>
<input type="number" id="total-deposit" value="60" min="10" step="10"
class="w-full bg-gray-800 border border-purple-700 rounded-lg px-3 py-2 focus:outline-none focus:ring-1 focus:ring-purple-500">
</div>
<div>
<label class="block text-gray-400 text-sm mb-1">MAX ORDERS</label>
<input type="number" id="max-orders" value="33" min="5" max="50" step="1"
class="w-full bg-gray-800 border border-purple-700 rounded-lg px-3 py-2 focus:outline-none focus:ring-1 focus:ring-purple-500">
</div>
<div class="pt-2">
<button id="start-bot" class="w-full bg-gradient-to-r from-orange-600 to-purple-700 hover:from-orange-700 hover:to-purple-800 text-white py-2 px-4 rounded-lg cyber-font transition-all duration-300">
ACTIVATE GRID
</button>
</div>
<div class="pt-2">
<button id="stop-bot" class="w-full bg-gray-800 hover:bg-gray-700 text-white py-2 px-4 rounded-lg cyber-font border border-red-900 transition-all duration-300">
EMERGENCY STOP
</button>
</div>
</div>
</div>
<!-- Account Info -->
<div class="bg-gray-900 bg-opacity-70 rounded-xl border border-purple-900 p-4">
<h2 class="cyber-font text-xl text-orange-400 mb-4">ACCOUNT STATUS</h2>
<div class="space-y-3">
<div class="flex justify-between">
<span class="text-gray-400">USDT Balance:</span>
<span id="usdt-balance" class="text-green-400">0.00</span>
</div>
<div class="flex justify-between">
<span class="text-gray-400">Base Asset:</span>
<span id="base-balance" class="text-blue-400">0.00</span>
</div>
<div class="flex justify-between">
<span class="text-gray-400">Active Orders:</span>
<span id="active-orders" class="text-purple-400">0</span>
</div>
<div class="flex justify-between">
<span class="text-gray-400">Total Profit:</span>
<span id="total-profit" class="text-orange-400">0.00</span>
</div>
</div>
</div>
<!-- Log Terminal -->
<div class="bg-gray-900 bg-opacity-70 rounded-xl border border-purple-900 p-4">
<div class="flex justify-between items-center mb-3">
<h2 class="cyber-font text-xl text-orange-400">SYSTEM LOG</h2>
<button id="clear-log" class="text-xs bg-gray-800 hover:bg-gray-700 px-2 py-1 rounded border border-purple-700">
CLEAR
</button>
</div>
<div id="log-terminal" class="bg-black bg-opacity-80 rounded-lg p-3 h-48 overflow-y-auto terminal-scroll text-xs font-mono space-y-1"></div>
</div>
</div>
</div>
</main>
</div>
<script>
// Initialize variables
let exchange;
let selectedPair = '';
let botRunning = false;
let priceUpdateInterval;
let gridUpdateInterval;
let chart;
let allMarkets = [];
// DOM Elements
const pairSearch = document.getElementById('pair-search');
const searchResults = document.getElementById('search-results');
const selectedPairElement = document.getElementById('selected-pair');
const currentPriceElement = document.getElementById('current-price');
const dailyVolumeElement = document.getElementById('daily-volume');
const buyOrdersElement = document.getElementById('buy-orders');
const sellOrdersElement = document.getElementById('sell-orders');
const logTerminal = document.getElementById('log-terminal');
const startBotButton = document.getElementById('start-bot');
const stopBotButton = document.getElementById('stop-bot');
const connectionStatus = document.getElementById('connection-status');
const currentTimeElement = document.getElementById('current-time');
const usdtBalanceElement = document.getElementById('usdt-balance');
const baseBalanceElement = document.getElementById('base-balance');
const activeOrdersElement = document.getElementById('active-orders');
const totalProfitElement = document.getElementById('total-profit');
// Configuration
const API_KEY = '4efbe203fbac0e4bcd0003a0910c801b';
const API_SECRET = '8b0e9cf47fdd97f2a42bca571a74105c53a5f906cd4ada125938d05115d063a0';
// Initialize exchange connection
async function initExchange() {
try {
exchange = new ccxt.gateio({
'apiKey': API_KEY,
'secret': API_SECRET,
'enableRateLimit': true,
'options': {'defaultType': 'futures'}
});
await exchange.loadMarkets();
allMarkets = Object.keys(exchange.markets);
logMessage('Exchange connected successfully', 'success');
connectionStatus.textContent = 'CONNECTED';
connectionStatus.className = 'ml-2 text-green-400';
// Load popular pairs by default
loadPopularPairs();
} catch (error) {
logMessage(`Connection error: ${error.message}`, 'error');
connectionStatus.textContent = 'DISCONNECTED';
connectionStatus.className = 'ml-2 text-red-400';
}
}
// Load popular trading pairs
function loadPopularPairs() {
const popularPairs = [
'BTC/USDT', 'ETH/USDT', 'SOL/USDT',
'ADA/USDT', 'DOT/USDT', 'AVAX/USDT',
'MATIC/USDT', 'LINK/USDT', 'UNI/USDT'
];
const availablePairs = popularPairs.filter(pair => allMarkets.includes(pair));
if (availablePairs.length > 0) {
selectPair(availablePairs[0]);
}
}
// Search for trading pairs
pairSearch.addEventListener('input', () => {
const searchTerm = pairSearch.value.toUpperCase();
if (searchTerm.length < 2) {
searchResults.classList.add('hidden');
return;
}
const filteredPairs = allMarkets.filter(pair =>
pair.includes(searchTerm) ||
pair.replace('/', '').includes(searchTerm)
).slice(0, 20);
displaySearchResults(filteredPairs);
});
// Display search results
function displaySearchResults(pairs) {
searchResults.innerHTML = '';
if (pairs.length === 0) {
const noResult = document.createElement('div');
noResult.className = 'px-4 py-2 text-gray-400';
noResult.textContent = 'No results found';
searchResults.appendChild(noResult);
} else {
pairs.forEach(pair => {
const resultItem = document.createElement('div');
resultItem.className = 'px-4 py-2 hover:bg-purple-900 cursor-pointer flex justify-between';
resultItem.innerHTML = `
<span>${pair}</span>
<span class="text-gray-400 text-xs">${exchange.markets[pair].type}</span>
`;
resultItem.addEventListener('click', () => {
selectPair(pair);
pairSearch.value = '';
searchResults.classList.add('hidden');
});
searchResults.appendChild(resultItem);
});
}
searchResults.classList.remove('hidden');
}
// Select a trading pair
async function selectPair(pair) {
try {
selectedPair = pair;
selectedPairElement.textContent = pair;
logMessage(`Selected pair: ${pair}`, 'info');
// Fetch initial data
await updatePriceData();
await updateAccountBalances();
// Initialize chart
initChart();
// Start price updates
if (priceUpdateInterval) clearInterval(priceUpdateInterval);
priceUpdateInterval = setInterval(updatePriceData, 5000);
} catch (error) {
logMessage(`Error selecting pair: ${error.message}`, 'error');
}
}
// Update price data
async function updatePriceData() {
if (!selectedPair) return;
try {
const ticker = await exchange.fetchTicker(selectedPair);
const price = ticker.last;
const volume = ticker.quoteVolume;
currentPriceElement.textContent = `$${price.toFixed(6)}`;
dailyVolumeElement.textContent = `$${volume.toFixed(2)}`;
// Update chart
updateChart(price);
} catch (error) {
logMessage(`Price update error: ${error.message}`, 'error');
}
}
// Initialize chart
function initChart() {
const ctx = document.getElementById('price-chart').getContext('2d');
chart = new Chart(ctx, {
type: 'line',
data: {
labels: Array(30).fill(''),
datasets: [{
label: 'Price',
data: Array(30).fill(0),
borderColor: '#7b2cbf',
backgroundColor: 'rgba(123, 44, 191, 0.1)',
borderWidth: 2,
tension: 0.3,
pointRadius: 0,
fill: true
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: {
display: false
}
},
scales: {
x: {
display: false,
grid: {
display: false
}
},
y: {
display: true,
grid: {
color: 'rgba(255, 255, 255, 0.1)'
},
ticks: {
color: 'rgba(255, 255, 255, 0.7)'
}
}
},
interaction: {
intersect: false,
mode: 'index'
}
}
});
}
// Update chart with new price
function updateChart(price) {
if (!chart) return;
// Shift all data left and add new price
chart.data.datasets[0].data.shift();
chart.data.datasets[0].data.push(price);
// Update chart
chart.update();
}
// Update account balances
async function updateAccountBalances() {
if (!selectedPair) return;
try {
const [base, quote] = selectedPair.split('/');
const balance = await exchange.fetchBalance();
const usdtBalance = balance.total[quote] || 0;
const baseBalance = balance.total[base] || 0;
usdtBalanceElement.textContent = usdtBalance.toFixed(4);
baseBalanceElement.textContent = baseBalance.toFixed(4);
} catch (error) {
logMessage(`Balance update error: ${error.message}`, 'error');
}
}
// Generate grid orders
function generateGridOrders() {
if (!selectedPair || !botRunning) return;
const price = parseFloat(currentPriceElement.textContent.replace('$', ''));
if (isNaN(price) || price <= 0) return;
const gridSpacing = parseFloat(document.getElementById('grid-spacing').value) || 0.02;
const orderSize = parseFloat(document.getElementById('order-size').value) || 3;
const maxOrders = parseInt(document.getElementById('max-orders').value) || 33;
// Clear existing orders display
buyOrdersElement.innerHTML = '';
sellOrdersElement.innerHTML = '';
// Generate buy orders (below current price)
for (let i = 1; i <= maxOrders; i++) {
const buyPrice = price * (1 - (i * gridSpacing));
const buyAmount = orderSize / buyPrice;
if (buyPrice > 0) {
const buyOrderElement = createOrderElement('buy', buyPrice, buyAmount, i);
buyOrdersElement.appendChild(buyOrderElement);
}
}
// Generate sell orders (above current price)
for (let i = 1; i <= maxOrders; i++) {
const sellPrice = price * (1 + (i * gridSpacing));
const sellAmount = orderSize / price; // Using current price for amount calculation
if (sellPrice > 0) {
const sellOrderElement = createOrderElement('sell', sellPrice, sellAmount, i);
sellOrdersElement.appendChild(sellOrderElement);
}
}
}
// Create order display element
function createOrderElement(type, price, amount, index) {
const orderElement = document.createElement('div');
orderElement.className = 'bg-gray-800 rounded-lg p-2 flex justify-between items-center';
const colorClass = type === 'buy' ? 'text-purple-400' : 'text-orange-400';
const bgClass = type === 'buy' ? 'bg-purple-900' : 'bg-orange-900';
orderElement.innerHTML = `
<div class="flex items-center">
<span class="w-6 h-6 ${bgClass} rounded-full flex items-center justify-center text-xs mr-2">${index}</span>
<span class="${colorClass}">${type.toUpperCase()}</span>
</div>
<div class="text-right">
<div class="text-sm">$${price.toFixed(6)}</div>
<div class="text-xs text-gray-400">${amount.toFixed(4)}</div>
</div>
`;
return orderElement;
}
// Start grid trading bot
async function startBot() {
if (botRunning) return;
if (!selectedPair) {
logMessage('Please select a trading pair first', 'warning');
return;
}
botRunning = true;
logMessage('Grid trading bot activated', 'success');
startBotButton.disabled = true;
startBotButton.classList.add('opacity-50');
stopBotButton.disabled = false;
stopBotButton.classList.remove('opacity-50');
// Initial grid generation
generateGridOrders();
// Update grid periodically
if (gridUpdateInterval) clearInterval(gridUpdateInterval);
gridUpdateInterval = setInterval(generateGridOrders, 10000);
}
// Stop grid trading bot
function stopBot() {
if (!botRunning) return;
botRunning = false;
logMessage('Grid trading bot deactivated', 'warning');
startBotButton.disabled = false;
startBotButton.classList.remove('opacity-50');
stopBotButton.disabled = true;
stopBotButton.classList.add('opacity-50');
// Clear grid update interval
if (gridUpdateInterval) {
clearInterval(gridUpdateInterval);
gridUpdateInterval = null;
}
// Clear orders display
buyOrdersElement.innerHTML = '';
sellOrdersElement.innerHTML = '';
}
// Log messages to terminal
function logMessage(message, type = 'info') {
const now = new Date();
const timestamp = now.toLocaleTimeString();
let colorClass;
switch (type) {
case 'error': colorClass = 'text-red-400'; break;
case 'success': colorClass = 'text-green-400'; break;
case 'warning': colorClass = 'text-orange-400'; break;
default: colorClass = 'text-gray-300';
}
const messageElement = document.createElement('div');
messageElement.className = `flex ${colorClass}`;
messageElement.innerHTML = `
<span class="text-gray-500 mr-2">[${timestamp}]</span>
<span>${message}</span>
`;
logTerminal.appendChild(messageElement);
logTerminal.scrollTop = logTerminal.scrollHeight;
}
// Update current time
function updateCurrentTime() {
const now = new Date();
currentTimeElement.textContent = now.toLocaleTimeString();
}
// Event listeners
startBotButton.addEventListener('click', startBot);
stopBotButton.addEventListener('click', stopBot);
document.getElementById('clear-log').addEventListener('click', () => {
logTerminal.innerHTML = '';
});
// Initialize
document.addEventListener('DOMContentLoaded', () => {
initExchange();
setInterval(updateCurrentTime, 1000);
// Close search results when clicking outside
document.addEventListener('click', (e) => {
if (!pairSearch.contains(e.target) && !searchResults.contains(e.target)) {
searchResults.classList.add('hidden');
}
});
});
</script>
</body>
</html>