olywwe's picture
em Fetch Type ao clicar abrir pop up para inserir API key e API Secret - Initial Deployment
e1cdab3 verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Bybit OrderBook Data Fetcher</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">
<script>
tailwind.config = {
theme: {
extend: {
colors: {
primary: '#1e293b',
secondary: '#0f172a',
accent: '#3b82f6',
bid: '#10b981',
ask: '#ef4444'
}
}
}
}
</script>
<style>
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap');
body {
font-family: 'Inter', sans-serif;
background-color: #0f172a;
color: #e2e8f0;
}
.orderbook-container {
height: 600px;
overflow-y: auto;
}
.orderbook-row {
transition: all 0.3s ease;
}
.orderbook-row:hover {
background-color: rgba(59, 130, 246, 0.1);
}
.depth-bar {
height: 100%;
position: absolute;
top: 0;
left: 0;
z-index: 0;
opacity: 0.2;
}
.loading-bar {
height: 4px;
background: linear-gradient(90deg, #3b82f6, #8b5cf6, #ec4899);
width: 0%;
transition: width 0.5s ease;
}
.pulse {
animation: pulse 2s infinite;
}
@keyframes pulse {
0% { opacity: 0.5; }
50% { opacity: 1; }
100% { opacity: 0.5; }
}
</style>
</head>
<body class="min-h-screen">
<div class="container mx-auto px-4 py-8">
<!-- Header -->
<header class="mb-10 text-center">
<h1 class="text-3xl md:text-4xl font-bold mb-2">Bybit OrderBook Data Fetcher</h1>
<p class="text-gray-400 mb-6">Real-time order book data with support for 1000 depth levels</p>
<div class="bg-blue-900/30 border border-blue-700 rounded-lg p-4 max-w-3xl mx-auto">
<div class="flex items-start">
<i class="fas fa-info-circle text-blue-400 mt-1 mr-3"></i>
<div>
<h3 class="font-semibold text-blue-300 mb-1">API Update Information</h3>
<ul class="text-sm text-gray-300 space-y-1">
<li><span class="text-yellow-400">Aug 21, 2025:</span> OrderBook REST API now supports 1,000 depth levels (up from 500 for futures and 200 for spot)</li>
<li><span class="text-red-400">Sep 11, 2025:</span> WebSocket Futures OrderBook (500 depth levels) will be offline</li>
</ul>
</div>
</div>
</div>
</header>
<!-- Controls -->
<div class="bg-primary rounded-xl p-6 mb-8 shadow-xl">
<div class="grid grid-cols-1 md:grid-cols-3 gap-6">
<div>
<label class="block text-sm font-medium mb-2">Select Symbol</label>
<div class="relative">
<select id="symbol-select" class="w-full bg-secondary border border-gray-700 rounded-lg py-3 px-4 appearance-none focus:outline-none focus:ring-2 focus:ring-accent">
<option>BTCUSDT</option>
<option>ETHUSDT</option>
<option>BNBUSDT</option>
<option>XRPUSDT</option>
<option>ADAUSDT</option>
<option>DOGEUSDT</option>
<option>MATICUSDT</option>
<option>SOLUSDT</option>
</select>
<div class="pointer-events-none absolute inset-y-0 right-0 flex items-center px-2 text-gray-400">
<i class="fas fa-chevron-down"></i>
</div>
</div>
</div>
<div>
<label class="block text-sm font-medium mb-2">Depth Levels</label>
<div class="relative">
<select id="depth-select" class="w-full bg-secondary border border-gray-700 rounded-lg py-3 px-4 appearance-none focus:outline-none focus:ring-2 focus:ring-accent">
<option value="10">10 Levels</option>
<option value="50">50 Levels</option>
<option value="100" selected>100 Levels</option>
<option value="500">500 Levels</option>
<option value="1000">1000 Levels (New)</option>
</select>
<div class="pointer-events-none absolute inset-y-0 right-0 flex items-center px-2 text-gray-400">
<i class="fas fa-chevron-down"></i>
</div>
</div>
</div>
<div>
<label class="block text-sm font-medium mb-2">Fetch Type</label>
<div class="flex space-x-4">
<button id="rest-btn" class="flex-1 bg-accent text-white py-3 px-4 rounded-lg font-medium hover:bg-blue-500 transition">REST API</button>
<button id="ws-btn" class="flex-1 bg-gray-700 text-gray-300 py-3 px-4 rounded-lg font-medium hover:bg-gray-600 transition">WebSocket</button>
</div>
</div>
</div>
<div class="mt-6 flex justify-center">
<button id="fetch-btn" class="bg-gradient-to-r from-blue-600 to-indigo-700 hover:from-blue-500 hover:to-indigo-600 text-white font-bold py-3 px-8 rounded-full shadow-lg transform hover:scale-105 transition-all duration-300">
<i class="fas fa-sync-alt mr-2"></i> Fetch Order Book Data
</button>
</div>
</div>
<!-- Loading Bar -->
<div class="loading-bar rounded-full mb-6" id="loading-bar"></div>
<!-- Data Display -->
<div class="grid grid-cols-1 lg:grid-cols-2 gap-8">
<!-- Order Book -->
<div class="bg-primary rounded-xl p-6 shadow-xl">
<div class="flex justify-between items-center mb-6">
<h2 class="text-xl font-bold">Order Book <span id="symbol-display" class="text-accent">BTCUSDT</span></h2>
<div class="flex items-center space-x-2">
<span class="px-3 py-1 bg-gray-800 rounded-full text-sm">Level <span id="depth-display">100</span></span>
<span id="connection-status" class="px-3 py-1 bg-green-900/30 text-green-400 rounded-full text-sm">Connected</span>
</div>
</div>
<div class="orderbook-container rounded-lg overflow-hidden border border-gray-800">
<!-- Asks -->
<div class="bg-gradient-to-r from-red-900/20 to-transparent p-3 text-sm font-medium">
<div class="grid grid-cols-3 gap-4">
<div>Price (USDT)</div>
<div class="text-right">Amount (BTC)</div>
<div class="text-right">Total (USDT)</div>
</div>
</div>
<div id="asks-container">
<!-- Asks will be populated here -->
</div>
<!-- Market Price -->
<div class="bg-gray-900 py-3 text-center border-y border-gray-800">
<div class="text-2xl font-bold text-gray-200">$61,842.35</div>
<div class="text-sm text-gray-500">Market Price</div>
</div>
<!-- Bids -->
<div class="bg-gradient-to-r from-green-900/20 to-transparent p-3 text-sm font-medium">
<div class="grid grid-cols-3 gap-4">
<div>Price (USDT)</div>
<div class="text-right">Amount (BTC)</div>
<div class="text-right">Total (USDT)</div>
</div>
</div>
<div id="bids-container">
<!-- Bids will be populated here -->
</div>
</div>
<div class="mt-4 flex justify-between text-sm text-gray-500">
<div><i class="fas fa-circle text-green-500 mr-1"></i> Bids (Buy Orders)</div>
<div>Asks <i class="fas fa-circle text-red-500 ml-1"></i> (Sell Orders)</div>
</div>
</div>
<!-- API Response -->
<div class="bg-primary rounded-xl p-6 shadow-xl">
<div class="flex justify-between items-center mb-6">
<h2 class="text-xl font-bold">API Response</h2>
<button id="copy-response" class="text-sm bg-gray-800 hover:bg-gray-700 py-1 px-3 rounded-lg flex items-center">
<i class="far fa-copy mr-1"></i> Copy
</button>
</div>
<div class="bg-secondary border border-gray-800 rounded-lg p-4 h-96 overflow-auto">
<pre id="response-output" class="text-sm text-gray-300 whitespace-pre-wrap">{/* API response will appear here */}</pre>
</div>
<div class="mt-4 bg-gray-900/50 rounded-lg p-4">
<h3 class="font-bold mb-2">API Documentation</h3>
<ul class="text-sm space-y-1">
<li class="flex items-start">
<i class="fas fa-link text-accent mt-1 mr-2 text-xs"></i>
<a href="https://bybit-exchange.github.io/docs/v5/market/orderbook" target="_blank" class="text-blue-400 hover:underline">OrderBook REST API</a>
</li>
<li class="flex items-start">
<i class="fas fa-link text-accent mt-1 mr-2 text-xs"></i>
<a href="https://bybit-exchange.github.io/docs/v5/websocket/public/orderbook" target="_blank" class="text-blue-400 hover:underline">WebSocket OrderBook</a>
</li>
</ul>
</div>
</div>
</div>
<!-- Footer -->
<footer class="mt-12 text-center text-gray-500 text-sm">
<p>Data provided by Bybit API • As of August 2025, REST API supports 1000 depth levels • WebSocket will be upgraded</p>
<p class="mt-2">© 2025 OrderBook Data Fetcher | This is a demo application</p>
</footer>
</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
// DOM Elements
const fetchBtn = document.getElementById('fetch-btn');
const copyBtn = document.getElementById('copy-response');
const restBtn = document.getElementById('rest-btn');
const wsBtn = document.getElementById('ws-btn');
const symbolSelect = document.getElementById('symbol-select');
const depthSelect = document.getElementById('depth-select');
const symbolDisplay = document.getElementById('symbol-display');
const depthDisplay = document.getElementById('depth-display');
const asksContainer = document.getElementById('asks-container');
const bidsContainer = document.getElementById('bids-container');
const responseOutput = document.getElementById('response-output');
const loadingBar = document.getElementById('loading-bar');
const connectionStatus = document.getElementById('connection-status');
// State
let currentFetchType = 'rest';
let wsConnected = false;
let simulatedData = null;
// Initialize UI
updateFetchType('rest');
symbolSelect.addEventListener('change', updateSymbolDisplay);
depthSelect.addEventListener('change', updateDepthDisplay);
restBtn.addEventListener('click', () => updateFetchType('rest'));
wsBtn.addEventListener('click', () => updateFetchType('websocket'));
fetchBtn.addEventListener('click', fetchOrderBookData);
copyBtn.addEventListener('click', copyResponse);
updateSymbolDisplay();
updateDepthDisplay();
// Fetch Data
async function fetchOrderBookData() {
const symbol = symbolSelect.value;
const depth = depthSelect.value;
symbolDisplay.textContent = symbol;
depthDisplay.textContent = depth;
// Show loading
loadingBar.style.width = '30%';
loadingBar.classList.add('pulse');
try {
// Simulate API call
await new Promise(resolve => setTimeout(resolve, 800));
if (currentFetchType === 'rest') {
// Simulate REST API response (new 1000 levels support)
simulatedData = generateOrderBookData(symbol, depth);
displayOrderBook(simulatedData);
displayResponse(simulatedData);
loadingBar.style.width = '100%';
connectionStatus.textContent = 'Connected (REST)';
connectionStatus.className = 'px-3 py-1 bg-green-900/30 text-green-400 rounded-full text-sm';
} else {
// Simulate WebSocket connection
if (!wsConnected) {
simulateWebSocketConnection();
} else {
// Update with new data
simulatedData = generateOrderBookData(symbol, depth);
displayOrderBook(simulatedData);
displayResponse(simulatedData);
}
loadingBar.style.width = '100%';
connectionStatus.textContent = 'Connected (WebSocket)';
connectionStatus.className = 'px-3 py-1 bg-green-900/30 text-green-400 rounded-full text-sm';
}
} catch (error) {
loadingBar.style.width = '0%';
loadingBar.classList.remove('pulse');
connectionStatus.textContent = 'Connection Error';
connectionStatus.className = 'px-3 py-1 bg-red-900/30 text-red-400 rounded-full text-sm';
alert('Error fetching data: ' + error.message);
}
// Remove pulse after completion
setTimeout(() => {
loadingBar.classList.remove('pulse');
}, 500);
}
// Simulate WebSocket connection
function simulateWebSocketConnection() {
connectionStatus.textContent = 'Connecting...';
connectionStatus.className = 'px-3 py-1 bg-yellow-900/30 text-yellow-400 rounded-full text-sm';
setTimeout(() => {
wsConnected = true;
simulatedData = generateOrderBookData(symbolSelect.value, depthSelect.value);
displayOrderBook(simulatedData);
displayResponse(simulatedData);
// Simulate periodic updates
setInterval(() => {
if (wsConnected && currentFetchType === 'websocket') {
simulatedData = generateOrderBookData(symbolSelect.value, depthSelect.value);
displayOrderBook(simulatedData);
displayResponse(simulatedData);
}
}, 3000);
}, 1500);
}
// Update Fetch Type
function updateFetchType(type) {
currentFetchType = type;
if (type === 'rest') {
restBtn.classList.remove('bg-gray-700', 'text-gray-300');
restBtn.classList.add('bg-accent', 'text-white');
wsBtn.classList.remove('bg-accent', 'text-white');
wsBtn.classList.add('bg-gray-700', 'text-gray-300');
} else {
wsBtn.classList.remove('bg-gray-700', 'text-gray-300');
wsBtn.classList.add('bg-accent', 'text-white');
restBtn.classList.remove('bg-accent', 'text-white');
restBtn.classList.add('bg-gray-700', 'text-gray-300');
}
}
// Update symbol display
function updateSymbolDisplay() {
symbolDisplay.textContent = symbolSelect.value;
}
// Update depth display
function updateDepthDisplay() {
depthDisplay.textContent = depthSelect.value;
}
// Generate simulated order book data
function generateOrderBookData(symbol, depth) {
const data = {
symbol: symbol,
asks: [],
bids: [],
timestamp: new Date().toISOString(),
seq: Math.floor(Math.random() * 1000000),
u: Math.floor(Math.random() * 1000000)
};
const basePrice = 61842.35; // Base BTC price
const priceStep = 0.5; // Price increment between levels
const amountMin = 0.1;
const amountMax = 5.0;
// Generate asks (sell orders)
for (let i = 0; i < depth; i++) {
const price = basePrice + (i * priceStep);
const amount = (Math.random() * (amountMax - amountMin) + amountMin).toFixed(6);
const total = (price * amount).toFixed(2);
data.asks.push([price.toFixed(2), amount, total]);
}
// Generate bids (buy orders)
for (let i = 0; i < depth; i++) {
const price = basePrice - (i * priceStep);
const amount = (Math.random() * (amountMax - amountMin) + amountMin).toFixed(6);
const total = (price * amount).toFixed(2);
data.bids.push([price.toFixed(2), amount, total]);
}
return data;
}
// Display order book
function displayOrderBook(data) {
// Clear containers
asksContainer.innerHTML = '';
bidsContainer.innerHTML = '';
// Find max total for depth bars
let maxTotal = 0;
[...data.asks, ...data.bids].forEach(order => {
const total = parseFloat(order[2]);
if (total > maxTotal) maxTotal = total;
});
// Display asks (reverse order so lowest is on top)
data.asks.slice().reverse().forEach(ask => {
const [price, amount, total] = ask;
const percentage = (total / maxTotal * 100).toFixed(2);
const row = document.createElement('div');
row.className = 'orderbook-row relative p-3 text-sm border-b border-gray-800 hover:bg-gray-800/50';
row.innerHTML = `
<div class="depth-bar bg-red-500" style="width: ${percentage}%"></div>
<div class="grid grid-cols-3 gap-4 relative z-10">
<div class="text-red-400 font-medium">${price}</div>
<div class="text-right">${amount}</div>
<div class="text-right">${total}</div>
</div>
`;
asksContainer.appendChild(row);
});
// Display bids
data.bids.forEach(bid => {
const [price, amount, total] = bid;
const percentage = (total / maxTotal * 100).toFixed(2);
const row = document.createElement('div');
row.className = 'orderbook-row relative p-3 text-sm border-b border-gray-800 hover:bg-gray-800/50';
row.innerHTML = `
<div class="depth-bar bg-green-500" style="width: ${percentage}%"></div>
<div class="grid grid-cols-3 gap-4 relative z-10">
<div class="text-green-400 font-medium">${price}</div>
<div class="text-right">${amount}</div>
<div class="text-right">${total}</div>
</div>
`;
bidsContainer.appendChild(row);
});
}
// Display API response
function displayResponse(data) {
responseOutput.textContent = JSON.stringify(data, null, 2);
}
// Copy response to clipboard
function copyResponse() {
const text = responseOutput.textContent;
navigator.clipboard.writeText(text).then(() => {
const originalText = copyBtn.innerHTML;
copyBtn.innerHTML = '<i class="fas fa-check mr-1"></i> Copied!';
setTimeout(() => {
copyBtn.innerHTML = originalText;
}, 2000);
});
}
// Initial data fetch
fetchOrderBookData();
});
</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=olywwe/https-huggingface-co-spaces-olywwe-bibytprivate" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
</html>