386 lines
22 KiB
PHP
386 lines
22 KiB
PHP
<?php
|
|
require_once 'includes/header.php';
|
|
|
|
$symbol = $_GET['symbol'] ?? 'BTC';
|
|
$type = $_GET['type'] ?? 'spot';
|
|
?>
|
|
|
|
<style>
|
|
.trade-container { height: calc(100vh - 62px); overflow: hidden; background-color: var(--primary-bg); }
|
|
.market-list { height: 100%; overflow-y: auto; background-color: var(--primary-bg); border-right: 1px solid #2b2f36; }
|
|
.trade-main { height: 100%; display: flex; flex-direction: column; background-color: var(--primary-bg); }
|
|
.order-sidebar { height: 100%; overflow-y: auto; background-color: var(--primary-bg); border-left: 1px solid #2b2f36; }
|
|
|
|
.market-bar { background-color: var(--primary-bg); border-bottom: 1px solid #2b2f36; }
|
|
.chart-container { flex-grow: 1; min-height: 450px; background-color: var(--primary-bg); }
|
|
|
|
.trade-tabs .nav-link { color: #848e9c; border: none; font-weight: 600; padding: 10px 15px; font-size: 0.85rem; background: transparent; }
|
|
.trade-tabs .nav-link.active { color: var(--okx-blue); background: transparent; border-bottom: 2px solid var(--okx-blue); }
|
|
|
|
.order-book-row { display: flex; justify-content: space-between; font-size: 0.75rem; padding: 2px 10px; position: relative; cursor: pointer; }
|
|
.order-book-row:hover { background-color: rgba(255,255,255,0.05); }
|
|
.order-book-row .price { z-index: 1; font-family: 'Roboto Mono', monospace; }
|
|
.order-book-row .amount { z-index: 1; color: #848e9c; }
|
|
.order-book-row.ask .price { color: #f6465d; }
|
|
.order-book-row.bid .price { color: #0ecb81; }
|
|
|
|
.depth-bg { position: absolute; right: 0; top: 0; height: 100%; opacity: 0.15; z-index: 0; transition: width 0.3s; }
|
|
.depth-bg.ask { background-color: #f6465d; }
|
|
.depth-bg.bid { background-color: #0ecb81; }
|
|
|
|
.crypto-item { padding: 8px 12px; border-bottom: 1px solid rgba(255,255,255,0.03); cursor: pointer; transition: background 0.2s; }
|
|
.crypto-item:hover { background-color: #1e2329; }
|
|
.crypto-item.active { background-color: #1e2329; border-left: 2px solid var(--okx-blue); }
|
|
.crypto-icon { width: 18px; height: 18px; margin-right: 8px; border-radius: 50%; }
|
|
.crypto-name-text { font-size: 0.75rem; font-weight: 600; }
|
|
.crypto-sub-text { font-size: 0.65rem; color: #848e9c; }
|
|
.crypto-price-text { font-size: 0.75rem; font-weight: 600; }
|
|
.crypto-change-text { font-size: 0.65rem; }
|
|
|
|
.btn-buy { background-color: #0ecb81; color: white; border: none; font-weight: bold; transition: opacity 0.2s; }
|
|
.btn-buy:hover { opacity: 0.9; color: white; }
|
|
.btn-sell { background-color: #f6465d; color: white; border: none; font-weight: bold; transition: opacity 0.2s; }
|
|
.btn-sell:hover { opacity: 0.9; color: white; }
|
|
|
|
.percent-btn { font-size: 0.65rem; padding: 2px 5px; background: #2b2f36; border: 1px solid #3b3f46; color: #848e9c; border-radius: 4px; }
|
|
.percent-btn:hover { background: #3b3f46; color: white; }
|
|
|
|
@media (max-width: 991px) {
|
|
.trade-container { height: auto; overflow: visible; }
|
|
.market-list { display: none; }
|
|
.order-sidebar { border-left: none; border-top: 1px solid #2b2f36; padding-bottom: 80px; }
|
|
.chart-container { min-height: 350px; }
|
|
}
|
|
</style>
|
|
|
|
<div class="container-fluid trade-container px-0">
|
|
<div class="row g-0 h-100">
|
|
<!-- Market List (Left) -->
|
|
<div class="col-lg-2 market-list d-none d-lg-block">
|
|
<div class="p-2 border-bottom border-secondary">
|
|
<div class="input-group input-group-sm">
|
|
<span class="input-group-text bg-transparent border-0 text-muted"><i class="fas fa-search"></i></span>
|
|
<input type="text" id="market-search" class="form-control bg-transparent text-white border-0 shadow-none" placeholder="<?php echo mt('Search Pairs'); ?>" style="font-size: 0.75rem;">
|
|
</div>
|
|
</div>
|
|
<div id="crypto-list-container">
|
|
<div class="text-center py-5"><div class="spinner-border spinner-border-sm text-primary"></div></div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Main Trading Area (Middle) -->
|
|
<div class="col-lg-7 trade-main">
|
|
<!-- Market Info Bar -->
|
|
<div class="market-bar p-2 d-flex align-items-center flex-wrap gap-4">
|
|
<div class="d-flex align-items-center me-2 ps-2">
|
|
<img id="current-coin-icon" src="https://static.okx.com/cdn/oksupport/asset/currency/icon/<?php echo strtolower($symbol); ?>.png" width="24" class="me-2">
|
|
<h5 class="mb-0 fw-bold text-white" style="font-size: 1.1rem;"><?php echo $symbol; ?>/USDT <span class="badge bg-secondary ms-2" style="font-size: 0.6rem; vertical-align: middle;"><?php echo mt($type === 'contract' ? 'Perpetual' : 'Spot'); ?></span></h5>
|
|
</div>
|
|
<div>
|
|
<div id="last-price" class="fw-bold text-success fs-5">--</div>
|
|
<div id="price-fiat" class="small text-muted" style="font-size: 0.7rem;">≈ $0.00</div>
|
|
</div>
|
|
<div>
|
|
<div class="small text-muted" style="font-size: 0.7rem;">24h <?php echo mt('Change'); ?></div>
|
|
<div id="24h-change" class="fw-bold" style="font-size: 0.8rem;">--</div>
|
|
</div>
|
|
<div class="d-none d-md-block">
|
|
<div class="small text-muted" style="font-size: 0.7rem;">24h <?php echo mt('High'); ?></div>
|
|
<div id="24h-high" class="fw-bold text-white" style="font-size: 0.8rem;">--</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Chart -->
|
|
<div class="chart-container border-bottom border-secondary">
|
|
<div id="tradingview_chart" class="h-100"></div>
|
|
<script type="text/javascript" src="https://s3.tradingview.com/tv.js"></script>
|
|
<script type="text/javascript">
|
|
function initChart(symbol) {
|
|
new TradingView.widget({
|
|
"autosize": true,
|
|
"symbol": "BINANCE:" + symbol + "USDT",
|
|
"interval": "15",
|
|
"timezone": "Etc/UTC",
|
|
"theme": "dark",
|
|
"style": "1",
|
|
"locale": "<?php echo ($lang == 'zh' ? 'zh_CN' : 'en'); ?>",
|
|
"toolbar_bg": "#101216",
|
|
"enable_publishing": false,
|
|
"hide_side_toolbar": false,
|
|
"allow_symbol_change": true,
|
|
"container_id": "tradingview_chart",
|
|
"studies": [
|
|
"MASimple@tv-basicstudies",
|
|
"RSI@tv-basicstudies"
|
|
],
|
|
"show_popup_button": true,
|
|
"popup_width": "1000",
|
|
"popup_height": "650",
|
|
"backgroundColor": "#101216",
|
|
"gridColor": "rgba(255, 255, 255, 0.05)",
|
|
"overrides": {
|
|
"mainSeriesProperties.candleStyle.upColor": "#0ecb81",
|
|
"mainSeriesProperties.candleStyle.downColor": "#f6465d",
|
|
"mainSeriesProperties.candleStyle.drawWick": true,
|
|
"mainSeriesProperties.candleStyle.drawBorder": true,
|
|
"mainSeriesProperties.candleStyle.borderColor": "#378658",
|
|
"mainSeriesProperties.candleStyle.borderUpColor": "#0ecb81",
|
|
"mainSeriesProperties.candleStyle.borderDownColor": "#f6465d",
|
|
"mainSeriesProperties.candleStyle.wickUpColor": "#0ecb81",
|
|
"mainSeriesProperties.candleStyle.wickDownColor": "#f6465d",
|
|
"paneProperties.background": "#101216",
|
|
"paneProperties.vertGridProperties.color": "rgba(255, 255, 255, 0.05)",
|
|
"paneProperties.horzGridProperties.color": "rgba(255, 255, 255, 0.05)",
|
|
"symbolWatermarkProperties.transparency": 90,
|
|
"scalesProperties.textColor" : "#848e9c",
|
|
"mainSeriesProperties.showPriceLine": true
|
|
}
|
|
});
|
|
}
|
|
initChart("<?php echo $symbol; ?>");
|
|
</script>
|
|
</div>
|
|
|
|
<!-- Orders/History (Bottom) -->
|
|
<div class="flex-grow-1 overflow-auto" style="background-color: var(--primary-bg);">
|
|
<ul class="nav nav-tabs trade-tabs border-bottom border-secondary sticky-top bg-dark" id="bottomTabs">
|
|
<li class="nav-item"><a class="nav-link active" data-bs-toggle="tab" href="#open-orders"><?php echo mt('Open Orders'); ?></a></li>
|
|
<li class="nav-item"><a class="nav-link" data-bs-toggle="tab" href="#order-history"><?php echo mt('Order History'); ?></a></li>
|
|
<li class="nav-item"><a class="nav-link" data-bs-toggle="tab" href="#positions"><?php echo mt('Positions'); ?></a></li>
|
|
</ul>
|
|
<div class="tab-content">
|
|
<div class="tab-pane fade show active p-2" id="open-orders">
|
|
<table class="table table-dark table-sm small align-middle mb-0">
|
|
<thead>
|
|
<tr class="text-muted border-0" style="font-size: 0.7rem;">
|
|
<th><?php echo mt('Time'); ?></th>
|
|
<th><?php echo mt('Pair'); ?></th>
|
|
<th><?php echo mt('Type'); ?></th>
|
|
<th><?php echo mt('Side'); ?></th>
|
|
<th><?php echo mt('Price'); ?></th>
|
|
<th><?php echo mt('Amount'); ?></th>
|
|
<th><?php echo mt('Filled'); ?></th>
|
|
<th><?php echo mt('Action'); ?></th>
|
|
</tr>
|
|
</thead>
|
|
<tbody id="open-orders-list">
|
|
<tr><td colspan="8" class="text-center py-5 text-muted"><?php echo mt('No open orders'); ?></td></tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Order Sidepanel (Right) -->
|
|
<div class="col-lg-3 order-sidebar">
|
|
<div class="order-book p-0 border-bottom border-secondary" style="height: 320px; display: flex; flex-direction: column;">
|
|
<div class="p-2 d-flex justify-content-between small text-muted border-bottom border-secondary" style="background: var(--primary-bg); font-size: 0.65rem;">
|
|
<span><?php echo mt('Price'); ?> (USDT)</span>
|
|
<span><?php echo mt('Amount'); ?> (<?php echo $symbol; ?>)</span>
|
|
</div>
|
|
<div id="order-book-asks" style="flex: 1; overflow: hidden; display: flex; flex-direction: column-reverse;"></div>
|
|
<div id="mid-price-row" class="px-3 py-1 fs-5 fw-bold text-success bg-black bg-opacity-25 border-top border-bottom border-secondary">
|
|
<span id="book-price">--</span>
|
|
</div>
|
|
<div id="order-book-bids" style="flex: 1; overflow: hidden;"></div>
|
|
</div>
|
|
|
|
<div class="p-3">
|
|
<div class="d-flex justify-content-between align-items-center mb-3">
|
|
<div class="nav nav-pills small bg-dark p-1 rounded-pill" id="order-type-tabs">
|
|
<button class="nav-link active py-1 px-3 rounded-pill" id="tab-limit" style="font-size: 0.7rem; color: #848e9c;"><?php echo mt('Limit'); ?></button>
|
|
<button class="nav-link py-1 px-3 rounded-pill" id="tab-market" style="font-size: 0.7rem; color: #848e9c;"><?php echo mt('Market'); ?></button>
|
|
</div>
|
|
<?php if ($type === 'contract'): ?>
|
|
<div class="dropdown">
|
|
<button class="btn btn-sm btn-dark border-secondary dropdown-toggle py-0" type="button" data-bs-toggle="dropdown" id="leverage-btn" style="font-size: 0.7rem;">20x</button>
|
|
<ul class="dropdown-menu dropdown-menu-dark">
|
|
<li><a class="dropdown-item" href="#" onclick="setLeverage(10)">10x</a></li>
|
|
<li><a class="dropdown-item active" href="#" onclick="setLeverage(20)">20x</a></li>
|
|
<li><a class="dropdown-item" href="#" onclick="setLeverage(50)">50x</a></li>
|
|
<li><a class="dropdown-item" href="#" onclick="setLeverage(100)">100x</a></li>
|
|
</ul>
|
|
</div>
|
|
<?php endif; ?>
|
|
</div>
|
|
|
|
<form id="order-form">
|
|
<input type="hidden" id="current-symbol" value="<?php echo $symbol; ?>">
|
|
<input type="hidden" id="trade-type" value="<?php echo $type; ?>">
|
|
<input type="hidden" id="user-balance" value="<?php echo $user['balance_usdt'] ?? 0; ?>">
|
|
|
|
<div class="btn-group w-100 mb-3" role="group">
|
|
<input type="radio" class="btn-check" name="side" id="side-buy" value="buy" checked>
|
|
<label class="btn btn-outline-success border-0 py-2 fw-bold" for="side-buy" style="background-color: rgba(14, 203, 129, 0.05); font-size: 0.85rem;"><?php echo mt('Buy'); ?></label>
|
|
<input type="radio" class="btn-check" name="side" id="side-sell" value="sell">
|
|
<label class="btn btn-outline-danger border-0 py-2 fw-bold" for="side-sell" style="background-color: rgba(246, 70, 93, 0.05); font-size: 0.85rem;"><?php echo mt('Sell'); ?></label>
|
|
</div>
|
|
|
|
<div class="mb-2" id="price-input-group">
|
|
<div class="input-group input-group-sm">
|
|
<span class="input-group-text bg-dark border-secondary text-muted" style="min-width: 70px; font-size: 0.7rem;"><?php echo mt('Price'); ?></span>
|
|
<input type="number" id="order-price" class="form-control bg-dark text-white border-secondary shadow-none" step="0.01" style="font-size: 0.8rem;">
|
|
<span class="input-group-text bg-dark border-secondary text-muted" style="font-size: 0.7rem;">USDT</span>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="mb-2">
|
|
<div class="input-group input-group-sm">
|
|
<span class="input-group-text bg-dark border-secondary text-muted" style="min-width: 70px; font-size: 0.7rem;"><?php echo mt($type === 'contract' ? 'Lots' : 'Amount'); ?></span>
|
|
<input type="number" id="order-amount" class="form-control bg-dark text-white border-secondary shadow-none" placeholder="0.00" style="font-size: 0.8rem;">
|
|
<span class="input-group-text bg-dark border-secondary text-muted" style="font-size: 0.7rem;"><?php echo $symbol; ?></span>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="d-flex justify-content-between gap-1 mb-3">
|
|
<button type="button" class="percent-btn flex-grow-1" onclick="setPercent(0.25)">25%</button>
|
|
<button type="button" class="percent-btn flex-grow-1" onclick="setPercent(0.50)">50%</button>
|
|
<button type="button" class="percent-btn flex-grow-1" onclick="setPercent(0.75)">75%</button>
|
|
<button type="button" class="percent-btn flex-grow-1" onclick="setPercent(1.00)">100%</button>
|
|
</div>
|
|
|
|
<?php if ($type === 'contract'): ?>
|
|
<div class="mb-2">
|
|
<div class="input-group input-group-sm">
|
|
<span class="input-group-text bg-dark border-secondary text-muted" style="min-width: 70px; font-size: 0.7rem;"><?php echo mt('Take-Profit'); ?></span>
|
|
<input type="number" id="take-profit" class="form-control bg-dark text-white border-secondary shadow-none" placeholder="0.00" style="font-size: 0.8rem;">
|
|
</div>
|
|
</div>
|
|
<div class="mb-3">
|
|
<div class="input-group input-group-sm">
|
|
<span class="input-group-text bg-dark border-secondary text-muted" style="min-width: 70px; font-size: 0.7rem;"><?php echo mt('Stop-Loss'); ?></span>
|
|
<input type="number" id="stop-loss" class="form-control bg-dark text-white border-secondary shadow-none" placeholder="0.00" style="font-size: 0.8rem;">
|
|
</div>
|
|
</div>
|
|
<?php endif; ?>
|
|
|
|
<div class="d-flex justify-content-between small text-muted mb-4 px-1" style="font-size: 0.7rem;">
|
|
<span><?php echo mt('Available'); ?></span>
|
|
<span class="text-white"><?php echo number_format($user['balance_usdt'] ?? 0, 2); ?> USDT</span>
|
|
</div>
|
|
|
|
<button type="button" id="submit-btn" class="btn btn-buy w-100 py-3 mb-3 fs-6 rounded-3" onclick="submitOrder()">
|
|
<?php echo mt('Buy'); ?> <?php echo $symbol; ?>
|
|
</button>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script src="assets/js/main.js?v=<?php echo time(); ?>"></script>
|
|
<script>
|
|
let currentLeverage = 20;
|
|
|
|
function setLeverage(lev) {
|
|
currentLeverage = lev;
|
|
const btn = document.getElementById('leverage-btn');
|
|
if (btn) btn.innerText = lev + 'x';
|
|
calculateMax();
|
|
}
|
|
|
|
function calculateMax() {
|
|
const balance = parseFloat(document.getElementById('user-balance').value);
|
|
const priceInput = document.getElementById('order-price');
|
|
let price = parseFloat(priceInput.value);
|
|
|
|
const symbol = document.getElementById('current-symbol').value;
|
|
const isMarket = document.getElementById('tab-market').classList.contains('active');
|
|
|
|
if (isMarket || !price) {
|
|
if (window.currentMarketData && window.currentMarketData[symbol]) {
|
|
price = window.currentMarketData[symbol].price;
|
|
}
|
|
}
|
|
|
|
if (price > 0) {
|
|
let max = balance / price;
|
|
if (document.getElementById('trade-type').value === 'contract') {
|
|
max *= currentLeverage;
|
|
}
|
|
window.currentMaxAmount = max;
|
|
if (isMarket) {
|
|
priceInput.value = price.toFixed(2);
|
|
}
|
|
}
|
|
}
|
|
|
|
function setPercent(p) {
|
|
if (window.currentMaxAmount > 0) {
|
|
document.getElementById('order-amount').value = (window.currentMaxAmount * p).toFixed(4);
|
|
}
|
|
}
|
|
|
|
function submitOrder() {
|
|
const amount = document.getElementById('order-amount').value;
|
|
if (!amount || amount <= 0) {
|
|
alert('<?php echo mt('Please enter a valid amount.'); ?>');
|
|
return;
|
|
}
|
|
|
|
const side = document.querySelector('input[name="side"]:checked').value;
|
|
const type = document.getElementById('tab-limit').classList.contains('active') ? 'Limit' : 'Market';
|
|
const symbol = document.getElementById('current-symbol').value;
|
|
const price = type === 'Limit' ? document.getElementById('order-price').value : 'Market';
|
|
|
|
const list = document.getElementById('open-orders-list');
|
|
const row = `
|
|
<tr class="border-secondary">
|
|
<td>${new Date().toLocaleTimeString()}</td>
|
|
<td>${symbol}/USDT</td>
|
|
<td>${type}</td>
|
|
<td class="${side === 'buy' ? 'text-success' : 'text-danger'}">${side.toUpperCase()}</td>
|
|
<td>${price}</td>
|
|
<td>${amount}</td>
|
|
<td>0%</td>
|
|
<td><button class="btn btn-sm btn-link text-danger p-0 text-decoration-none"><?php echo mt('Cancel'); ?></button></td>
|
|
</tr>
|
|
`;
|
|
|
|
if (list.innerHTML.includes('No open orders') || list.innerHTML.includes('无挂单') || list.innerHTML.includes('暂无挂单')) {
|
|
list.innerHTML = row;
|
|
} else {
|
|
list.innerHTML = row + list.innerHTML;
|
|
}
|
|
|
|
alert('<?php echo mt('Order submitted successfully!'); ?>');
|
|
}
|
|
|
|
document.addEventListener('DOMContentLoaded', () => {
|
|
setTimeout(calculateMax, 1000);
|
|
setInterval(calculateMax, 3000);
|
|
|
|
document.getElementById('tab-limit').addEventListener('click', function() {
|
|
document.getElementById('price-input-group').style.display = 'block';
|
|
this.classList.add('active');
|
|
document.getElementById('tab-market').classList.remove('active');
|
|
calculateMax();
|
|
});
|
|
|
|
document.getElementById('tab-market').addEventListener('click', function() {
|
|
document.getElementById('price-input-group').style.display = 'none';
|
|
this.classList.add('active');
|
|
document.getElementById('tab-limit').classList.remove('active');
|
|
calculateMax();
|
|
});
|
|
|
|
document.querySelectorAll('input[name="side"]').forEach(radio => {
|
|
radio.addEventListener('change', (e) => {
|
|
const btn = document.getElementById('submit-btn');
|
|
const sym = document.getElementById('current-symbol').value;
|
|
const buyText = '<?php echo mt('Buy'); ?>';
|
|
const sellText = '<?php echo mt('Sell'); ?>';
|
|
if (e.target.value === 'buy') {
|
|
btn.className = 'btn btn-buy w-100 py-3 mb-3 fs-6 rounded-3';
|
|
btn.textContent = buyText + ' ' + sym;
|
|
} else {
|
|
btn.className = 'btn btn-sell w-100 py-3 mb-3 fs-6 rounded-3';
|
|
btn.textContent = sellText + ' ' + sym;
|
|
}
|
|
});
|
|
});
|
|
});
|
|
</script>
|
|
|
|
<?php require_once 'includes/footer.php'; ?>
|