Spaces:
Running
Running
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Crypto Arbitrage Bot</title> | |
| <script src="https://cdn.tailwindcss.com"></script> | |
| <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> | |
| <style> | |
| .price-up { | |
| color: #10b981; | |
| } | |
| .price-down { | |
| color: #ef4444; | |
| } | |
| .blink { | |
| animation: blink-animation 1s steps(5, start) infinite; | |
| } | |
| @keyframes blink-animation { | |
| to { | |
| opacity: 0.5; | |
| } | |
| } | |
| .gradient-bg { | |
| background: linear-gradient(135deg, #1e3a8a 0%, #0ea5e9 100%); | |
| } | |
| </style> | |
| </head> | |
| <body class="bg-gray-900 text-gray-100 min-h-screen"> | |
| <div class="container mx-auto px-4 py-8"> | |
| <!-- Header --> | |
| <header class="gradient-bg rounded-xl p-6 mb-8 shadow-lg"> | |
| <div class="flex flex-col md:flex-row justify-between items-center"> | |
| <div class="mb-4 md:mb-0"> | |
| <h1 class="text-3xl font-bold">Crypto Arbitrage Bot</h1> | |
| <p class="text-blue-200">Automated profit opportunities across exchanges</p> | |
| </div> | |
| <div class="flex items-center space-x-4"> | |
| <div class="bg-blue-800/50 rounded-lg p-3"> | |
| <div class="text-xs text-blue-300">BALANCE</div> | |
| <div class="font-mono text-xl">$<span id="balance">10,000.00</span></div> | |
| </div> | |
| <button id="connectBtn" class="bg-green-600 hover:bg-green-700 px-6 py-3 rounded-lg font-medium transition flex items-center"> | |
| <i class="fas fa-plug mr-2"></i> Connect Exchanges | |
| </button> | |
| </div> | |
| </div> | |
| </header> | |
| <!-- Main Dashboard --> | |
| <div class="grid grid-cols-1 lg:grid-cols-3 gap-6 mb-8"> | |
| <!-- Settings Panel --> | |
| <div class="bg-gray-800 rounded-xl p-6 shadow-lg"> | |
| <h2 class="text-xl font-semibold mb-4 flex items-center"> | |
| <i class="fas fa-cog mr-2 text-blue-400"></i> Bot Settings | |
| </h2> | |
| <div class="space-y-4"> | |
| <div> | |
| <label class="block text-sm font-medium mb-1">Minimum Profit %</label> | |
| <input type="range" min="0.1" max="5" step="0.1" value="1.5" class="w-full" id="profitRange"> | |
| <div class="flex justify-between text-xs"> | |
| <span>0.1%</span> | |
| <span id="profitValue">1.5%</span> | |
| <span>5%</span> | |
| </div> | |
| </div> | |
| <div> | |
| <label class="block text-sm font-medium mb-1">Trade Amount ($)</label> | |
| <input type="number" min="10" max="10000" step="10" value="100" class="w-full bg-gray-700 border border-gray-600 rounded-lg px-3 py-2" id="tradeAmount"> | |
| </div> | |
| <div class="flex items-center justify-between"> | |
| <div> | |
| <label class="block text-sm font-medium mb-1">Max Trades/Min</label> | |
| <input type="number" min="1" max="20" value="5" class="w-20 bg-gray-700 border border-gray-600 rounded-lg px-3 py-2" id="maxTrades"> | |
| </div> | |
| <div class="flex items-center"> | |
| <input type="checkbox" id="autoTrade" class="mr-2" checked> | |
| <label for="autoTrade">Auto Trade</label> | |
| </div> | |
| </div> | |
| <div class="pt-4 border-t border-gray-700"> | |
| <label class="block text-sm font-medium mb-2">Exchanges</label> | |
| <div class="space-y-2"> | |
| <div class="flex items-center"> | |
| <input type="checkbox" id="binance" class="mr-2" checked> | |
| <label for="binance" class="flex items-center"> | |
| <img src="https://cryptologos.cc/logos/binance-coin-bnb-logo.png" class="w-5 h-5 mr-2"> Binance | |
| </label> | |
| </div> | |
| <div class="flex items-center"> | |
| <input type="checkbox" id="coinbase" class="mr-2" checked> | |
| <label for="coinbase" class="flex items-center"> | |
| <img src="https://cryptologos.cc/logos/coinbase-coin-logo.png" class="w-5 h-5 mr-2"> Coinbase | |
| </label> | |
| </div> | |
| <div class="flex items-center"> | |
| <input type="checkbox" id="kraken" class="mr-2"> | |
| <label for="kraken" class="flex items-center"> | |
| <img src="https://cryptologos.cc/logos/kraken-krk-logo.png" class="w-5 h-5 mr-2"> Kraken | |
| </label> | |
| </div> | |
| </div> | |
| </div> | |
| <button id="startBot" class="w-full bg-blue-600 hover:bg-blue-700 py-3 rounded-lg font-medium mt-4 transition flex items-center justify-center"> | |
| <i class="fas fa-play mr-2"></i> Start Bot | |
| </button> | |
| </div> | |
| </div> | |
| <!-- Arbitrage Opportunities --> | |
| <div class="bg-gray-800 rounded-xl p-6 shadow-lg lg:col-span-2"> | |
| <div class="flex justify-between items-center mb-4"> | |
| <h2 class="text-xl font-semibold flex items-center"> | |
| <i class="fas fa-bolt mr-2 text-yellow-400"></i> Arbitrage Opportunities | |
| </h2> | |
| <div class="text-sm bg-gray-700 px-3 py-1 rounded-lg"> | |
| <span id="lastUpdate">Updating...</span> | |
| </div> | |
| </div> | |
| <div class="overflow-x-auto"> | |
| <table class="w-full"> | |
| <thead> | |
| <tr class="text-left border-b border-gray-700 text-gray-400 text-sm"> | |
| <th class="pb-2">Pair</th> | |
| <th class="pb-2">Buy Exchange</th> | |
| <th class="pb-2">Buy Price</th> | |
| <th class="pb-2">Sell Exchange</th> | |
| <th class="pb-2">Sell Price</th> | |
| <th class="pb-2">Profit %</th> | |
| <th class="pb-2">Action</th> | |
| </tr> | |
| </thead> | |
| <tbody id="opportunitiesTable"> | |
| <!-- Will be populated by JavaScript --> | |
| </tbody> | |
| </table> | |
| </div> | |
| <div class="mt-4 text-center text-sm text-gray-500" id="noOpportunities"> | |
| <i class="fas fa-search mr-1"></i> Scanning for opportunities... | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Trade History & Stats --> | |
| <div class="grid grid-cols-1 lg:grid-cols-3 gap-6"> | |
| <!-- Performance Stats --> | |
| <div class="bg-gray-800 rounded-xl p-6 shadow-lg"> | |
| <h2 class="text-xl font-semibold mb-4 flex items-center"> | |
| <i class="fas fa-chart-line mr-2 text-green-400"></i> Performance | |
| </h2> | |
| <div class="space-y-4"> | |
| <div class="flex justify-between"> | |
| <div> | |
| <div class="text-sm text-gray-400">Today's Profit</div> | |
| <div class="text-2xl font-mono text-green-400">$<span id="todayProfit">124.75</span></div> | |
| </div> | |
| <div> | |
| <div class="text-sm text-gray-400">Total Profit</div> | |
| <div class="text-2xl font-mono text-green-400">$<span id="totalProfit">892.50</span></div> | |
| </div> | |
| </div> | |
| <div class="pt-4 border-t border-gray-700"> | |
| <div class="text-sm text-gray-400 mb-2">Win Rate</div> | |
| <div class="w-full bg-gray-700 h-4 rounded-full overflow-hidden"> | |
| <div class="bg-green-500 h-full" style="width: 87%"></div> | |
| </div> | |
| <div class="text-right text-xs mt-1">87%</div> | |
| </div> | |
| <div class="grid grid-cols-2 gap-4 pt-4 border-t border-gray-700"> | |
| <div> | |
| <div class="text-sm text-gray-400">Trades Today</div> | |
| <div class="text-xl"><span id="tradesToday">14</span></div> | |
| </div> | |
| <div> | |
| <div class="text-sm text-gray-400">Avg. Profit</div> | |
| <div class="text-xl">$<span id="avgProfit">8.91</span></div> | |
| </div> | |
| <div> | |
| <div class="text-sm text-gray-400">Best Trade</div> | |
| <div class="text-xl">$<span id="bestTrade">24.30</span></div> | |
| </div> | |
| <div> | |
| <div class="text-sm text-gray-400">Success Streak</div> | |
| <div class="text-xl"><span id="successStreak">9</span></div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Trade History --> | |
| <div class="bg-gray-800 rounded-xl p-6 shadow-lg lg:col-span-2"> | |
| <h2 class="text-xl font-semibold mb-4 flex items-center"> | |
| <i class="fas fa-history mr-2 text-purple-400"></i> Trade History | |
| </h2> | |
| <div class="overflow-x-auto"> | |
| <table class="w-full"> | |
| <thead> | |
| <tr class="text-left border-b border-gray-700 text-gray-400 text-sm"> | |
| <th class="pb-2">Time</th> | |
| <th class="pb-2">Pair</th> | |
| <th class="pb-2">Buy</th> | |
| <th class="pb-2">Sell</th> | |
| <th class="pb-2">Amount</th> | |
| <th class="pb-2">Profit</th> | |
| <th class="pb-2">Status</th> | |
| </tr> | |
| </thead> | |
| <tbody id="tradeHistory"> | |
| <!-- Will be populated by JavaScript --> | |
| </tbody> | |
| </table> | |
| </div> | |
| <div class="mt-4 text-center text-sm text-gray-500" id="noTrades"> | |
| No trades yet. Start the bot to begin arbitrage. | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Exchange Connection Modal --> | |
| <div id="exchangeModal" class="fixed inset-0 bg-black bg-opacity-70 flex items-center justify-center z-50 hidden"> | |
| <div class="bg-gray-800 rounded-xl p-6 w-full max-w-md"> | |
| <div class="flex justify-between items-center mb-4"> | |
| <h3 class="text-xl font-semibold">Connect Exchanges</h3> | |
| <button id="closeModal" class="text-gray-400 hover:text-white"> | |
| <i class="fas fa-times"></i> | |
| </button> | |
| </div> | |
| <div class="space-y-4"> | |
| <div> | |
| <label class="block text-sm font-medium mb-1">Binance API Key</label> | |
| <input type="text" class="w-full bg-gray-700 border border-gray-600 rounded-lg px-3 py-2" placeholder="Enter API Key"> | |
| </div> | |
| <div> | |
| <label class="block text-sm font-medium mb-1">Binance Secret Key</label> | |
| <input type="password" class="w-full bg-gray-700 border border-gray-600 rounded-lg px-3 py-2" placeholder="Enter Secret Key"> | |
| </div> | |
| <div class="pt-2"> | |
| <label class="block text-sm font-medium mb-1">Coinbase API Key</label> | |
| <input type="text" class="w-full bg-gray-700 border border-gray-600 rounded-lg px-3 py-2" placeholder="Enter API Key"> | |
| </div> | |
| <div> | |
| <label class="block text-sm font-medium mb-1">Coinbase Secret Key</label> | |
| <input type="password" class="w-full bg-gray-700 border border-gray-600 rounded-lg px-3 py-2" placeholder="Enter Secret Key"> | |
| </div> | |
| <div class="pt-4 border-t border-gray-700"> | |
| <button class="w-full bg-blue-600 hover:bg-blue-700 py-3 rounded-lg font-medium transition"> | |
| <i class="fas fa-save mr-2"></i> Save Connections | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <script> | |
| // Mock data for demonstration | |
| const cryptoPairs = ['BTC/USDT', 'ETH/USDT', 'SOL/USDT', 'ADA/USDT', 'DOT/USDT', 'AVAX/USDT']; | |
| const exchanges = ['Binance', 'Coinbase', 'Kraken']; | |
| // Bot state | |
| let botRunning = false; | |
| let updateInterval; | |
| let balance = 10000; | |
| let todayProfit = 124.75; | |
| let totalProfit = 892.50; | |
| let tradesToday = 14; | |
| let successStreak = 9; | |
| // DOM elements | |
| const connectBtn = document.getElementById('connectBtn'); | |
| const exchangeModal = document.getElementById('exchangeModal'); | |
| const closeModal = document.getElementById('closeModal'); | |
| const startBot = document.getElementById('startBot'); | |
| const profitRange = document.getElementById('profitRange'); | |
| const profitValue = document.getElementById('profitValue'); | |
| const tradeAmount = document.getElementById('tradeAmount'); | |
| const maxTrades = document.getElementById('maxTrades'); | |
| const autoTrade = document.getElementById('autoTrade'); | |
| const opportunitiesTable = document.getElementById('opportunitiesTable'); | |
| const noOpportunities = document.getElementById('noOpportunities'); | |
| const tradeHistory = document.getElementById('tradeHistory'); | |
| const noTrades = document.getElementById('noTrades'); | |
| const lastUpdate = document.getElementById('lastUpdate'); | |
| const balanceDisplay = document.getElementById('balance'); | |
| const todayProfitDisplay = document.getElementById('todayProfit'); | |
| const totalProfitDisplay = document.getElementById('totalProfit'); | |
| const tradesTodayDisplay = document.getElementById('tradesToday'); | |
| const avgProfitDisplay = document.getElementById('avgProfit'); | |
| const bestTradeDisplay = document.getElementById('bestTrade'); | |
| const successStreakDisplay = document.getElementById('successStreak'); | |
| // Event listeners | |
| connectBtn.addEventListener('click', () => { | |
| exchangeModal.classList.remove('hidden'); | |
| }); | |
| closeModal.addEventListener('click', () => { | |
| exchangeModal.classList.add('hidden'); | |
| }); | |
| profitRange.addEventListener('input', () => { | |
| profitValue.textContent = profitRange.value; | |
| }); | |
| startBot.addEventListener('click', toggleBot); | |
| // Initialize with some sample data | |
| document.addEventListener('DOMContentLoaded', () => { | |
| updateStats(); | |
| generateSampleOpportunities(); | |
| generateSampleHistory(); | |
| // Simulate real-time updates | |
| setInterval(() => { | |
| if (botRunning) { | |
| updateLastUpdateTime(); | |
| generateSampleOpportunities(); | |
| } | |
| }, 3000); | |
| }); | |
| function toggleBot() { | |
| botRunning = !botRunning; | |
| if (botRunning) { | |
| startBot.innerHTML = '<i class="fas fa-stop mr-2"></i> Stop Bot'; | |
| startBot.classList.remove('bg-blue-600', 'hover:bg-blue-700'); | |
| startBot.classList.add('bg-red-600', 'hover:bg-red-700'); | |
| startBot.classList.add('blink'); | |
| updateLastUpdateTime(); | |
| noOpportunities.classList.add('hidden'); | |
| } else { | |
| startBot.innerHTML = '<i class="fas fa-play mr-2"></i> Start Bot'; | |
| startBot.classList.remove('bg-red-600', 'hover:bg-red-700'); | |
| startBot.classList.add('bg-blue-600', 'hover:bg-blue-700'); | |
| startBot.classList.remove('blink'); | |
| noOpportunities.classList.remove('hidden'); | |
| } | |
| } | |
| function updateLastUpdateTime() { | |
| const now = new Date(); | |
| lastUpdate.textContent = now.toLocaleTimeString(); | |
| } | |
| function generateSampleOpportunities() { | |
| opportunitiesTable.innerHTML = ''; | |
| // Generate random opportunities | |
| const numOpportunities = Math.floor(Math.random() * 5) + 3; | |
| for (let i = 0; i < numOpportunities; i++) { | |
| const pair = cryptoPairs[Math.floor(Math.random() * cryptoPairs.length)]; | |
| const buyExchange = exchanges[Math.floor(Math.random() * exchanges.length)]; | |
| let sellExchange; | |
| do { | |
| sellExchange = exchanges[Math.floor(Math.random() * exchanges.length)]; | |
| } while (sellExchange === buyExchange); | |
| const basePrice = Math.random() * 100 + 10; | |
| const spread = Math.random() * 2 + parseFloat(profitRange.value)/100; | |
| const buyPrice = basePrice; | |
| const sellPrice = basePrice * (1 + spread); | |
| const profitPercent = (spread * 100).toFixed(2); | |
| const row = document.createElement('tr'); | |
| row.className = 'border-b border-gray-700 hover:bg-gray-700/50'; | |
| row.innerHTML = ` | |
| <td class="py-3 font-medium">${pair}</td> | |
| <td class="py-3"> | |
| <div class="flex items-center"> | |
| <img src="https://cryptologos.cc/logos/${buyExchange.toLowerCase()}-${pair.split('/')[0].toLowerCase()}-logo.png" class="w-5 h-5 mr-2"> | |
| ${buyExchange} | |
| </div> | |
| </td> | |
| <td class="py-3">$${buyPrice.toFixed(4)}</td> | |
| <td class="py-3"> | |
| <div class="flex items-center"> | |
| <img src="https://cryptologos.cc/logos/${sellExchange.toLowerCase()}-${pair.split('/')[0].toLowerCase()}-logo.png" class="w-5 h-5 mr-2"> | |
| ${sellExchange} | |
| </div> | |
| </td> | |
| <td class="py-3">$${sellPrice.toFixed(4)}</td> | |
| <td class="py-3 font-mono text-green-400">+${profitPercent}%</td> | |
| <td class="py-3"> | |
| <button class="trade-btn px-3 py-1 bg-blue-600 hover:bg-blue-700 rounded text-sm" data-pair="${pair}" data-buy-exchange="${buyExchange}" data-buy-price="${buyPrice.toFixed(4)}" data-sell-exchange="${sellExchange}" data-sell-price="${sellPrice.toFixed(4)}" data-profit="${profitPercent}"> | |
| Trade | |
| </button> | |
| </td> | |
| `; | |
| opportunitiesTable.appendChild(row); | |
| } | |
| // Add event listeners to trade buttons | |
| document.querySelectorAll('.trade-btn').forEach(btn => { | |
| btn.addEventListener('click', executeTrade); | |
| }); | |
| } | |
| function executeTrade(e) { | |
| if (!botRunning) return; | |
| const btn = e.target; | |
| const pair = btn.dataset.pair; | |
| const buyExchange = btn.dataset.buyExchange; | |
| const buyPrice = parseFloat(btn.dataset.buyPrice); | |
| const sellExchange = btn.dataset.sellExchange; | |
| const sellPrice = parseFloat(btn.dataset.sellPrice); | |
| const profitPercent = parseFloat(btn.dataset.profit); | |
| const amount = parseFloat(tradeAmount.value); | |
| const profit = amount * (profitPercent / 100); | |
| // Simulate trade execution | |
| btn.disabled = true; | |
| btn.innerHTML = '<i class="fas fa-spinner fa-spin mr-1"></i> Trading...'; | |
| btn.classList.remove('bg-blue-600', 'hover:bg-blue-700'); | |
| btn.classList.add('bg-gray-600'); | |
| setTimeout(() => { | |
| // Update balance and profits | |
| balance += profit; | |
| todayProfit += profit; | |
| totalProfit += profit; | |
| tradesToday++; | |
| successStreak++; | |
| // Add to trade history | |
| addTradeToHistory({ | |
| time: new Date(), | |
| pair, | |
| buyExchange, | |
| buyPrice, | |
| sellExchange, | |
| sellPrice, | |
| amount, | |
| profit, | |
| status: 'Completed' | |
| }); | |
| // Update stats | |
| updateStats(); | |
| // Reset button after delay | |
| setTimeout(() => { | |
| btn.disabled = false; | |
| btn.innerHTML = 'Trade'; | |
| btn.classList.add('bg-blue-600', 'hover:bg-blue-700'); | |
| btn.classList.remove('bg-gray-600'); | |
| }, 1000); | |
| }, 1500); | |
| } | |
| function addTradeToHistory(trade) { | |
| noTrades.classList.add('hidden'); | |
| const row = document.createElement('tr'); | |
| row.className = 'border-b border-gray-700 hover:bg-gray-700/50'; | |
| row.innerHTML = ` | |
| <td class="py-3 text-sm">${trade.time.toLocaleTimeString()}</td> | |
| <td class="py-3 font-medium">${trade.pair}</td> | |
| <td class="py-3"> | |
| <div class="flex items-center"> | |
| <img src="https://cryptologos.cc/logos/${trade.buyExchange.toLowerCase()}-${trade.pair.split('/')[0].toLowerCase()}-logo.png" class="w-5 h-5 mr-2"> | |
| $${trade.buyPrice.toFixed(4)} | |
| </div> | |
| </td> | |
| <td class="py-3"> | |
| <div class="flex items-center"> | |
| <img src="https://cryptologos.cc/logos/${trade.sellExchange.toLowerCase()}-${trade.pair.split('/')[0].toLowerCase()}-logo.png" class="w-5 h-5 mr-2"> | |
| $${trade.sellPrice.toFixed(4)} | |
| </div> | |
| </td> | |
| <td class="py-3">$${trade.amount.toFixed(2)}</td> | |
| <td class="py-3 font-mono text-green-400">+$${trade.profit.toFixed(2)}</td> | |
| <td class="py-3"> | |
| <span class="px-2 py-1 bg-green-900/50 text-green-400 rounded text-xs">${trade.status}</span> | |
| </td> | |
| `; | |
| tradeHistory.prepend(row); | |
| } | |
| function generateSampleHistory() { | |
| const now = new Date(); | |
| // Generate some sample history | |
| for (let i = 0; i < 5; i++) { | |
| const pair = cryptoPairs[Math.floor(Math.random() * cryptoPairs.length)]; | |
| const buyExchange = exchanges[Math.floor(Math.random() * exchanges.length)]; | |
| let sellExchange; | |
| do { | |
| sellExchange = exchanges[Math.floor(Math.random() * exchanges.length)]; | |
| } while (sellExchange === buyExchange); | |
| const basePrice = Math.random() * 100 + 10; | |
| const spread = Math.random() * 2 + 0.5; | |
| const buyPrice = basePrice; | |
| const sellPrice = basePrice * (1 + spread/100); | |
| const profitPercent = spread; | |
| const amount = Math.floor(Math.random() * 500) + 50; | |
| const profit = amount * (profitPercent / 100); | |
| const tradeTime = new Date(now.getTime() - (i * 3600000)); | |
| addTradeToHistory({ | |
| time: tradeTime, | |
| pair, | |
| buyExchange, | |
| buyPrice, | |
| sellExchange, | |
| sellPrice, | |
| amount, | |
| profit, | |
| status: 'Completed' | |
| }); | |
| } | |
| } | |
| function updateStats() { | |
| balanceDisplay.textContent = balance.toFixed(2).replace(/\B(?=(\d{3})+(?!\d))/g, ","); | |
| todayProfitDisplay.textContent = todayProfit.toFixed(2); | |
| totalProfitDisplay.textContent = totalProfit.toFixed(2); | |
| tradesTodayDisplay.textContent = tradesToday; | |
| avgProfitDisplay.textContent = (totalProfit / tradesToday).toFixed(2); | |
| bestTradeDisplay.textContent = (todayProfit * 0.2).toFixed(2); | |
| successStreakDisplay.textContent = successStreak; | |
| } | |
| </script> | |
| <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=Chiagozie/arbitrage-projects" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body> | |
| </html> |