<!DOCTYPE html>
|
<html lang="zh-CN">
|
<head>
|
<meta charset="UTF-8">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<title>OKX 标记价格K线频道</title>
|
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
<script src="https://cdn.jsdelivr.net/npm/chartjs-adapter-date-fns"></script>
|
<script src="https://cdn.jsdelivr.net/npm/chartjs-chart-financial"></script>
|
<style>
|
body {
|
font-family: Arial, sans-serif;
|
margin: 20px;
|
}
|
.channel {
|
margin-bottom: 20px;
|
padding: 15px;
|
border: 1px solid #ccc;
|
border-radius: 5px;
|
}
|
.channel h3 {
|
margin-top: 0;
|
}
|
.status {
|
font-weight: bold;
|
}
|
.connected {
|
color: green;
|
}
|
.disconnected {
|
color: red;
|
}
|
.messages {
|
height: 300px;
|
overflow-y: scroll;
|
border: 1px solid #eee;
|
padding: 10px;
|
margin-top: 10px;
|
background-color: #f9f9f9;
|
}
|
.chart-container {
|
width: 100%;
|
height: 300px;
|
margin-top: 20px;
|
}
|
.mode-toggle {
|
margin: 10px 0;
|
padding: 10px;
|
background-color: #f0f0f0;
|
border-radius: 5px;
|
}
|
.mode-toggle button {
|
margin: 0 5px;
|
padding: 5px 10px;
|
border: 1px solid #ccc;
|
background-color: #fff;
|
cursor: pointer;
|
}
|
.mode-toggle button.active {
|
background-color: #007bff;
|
color: white;
|
}
|
</style>
|
</head>
|
<body>
|
<h1>OKX 标记价格K线频道</h1>
|
|
<div class="mode-toggle">
|
<span>当前模式:</span>
|
<button id="demoModeBtn" class="active" onclick="switchMode('demo')">模拟盘 (wspap)</button>
|
<button id="liveModeBtn" onclick="switchMode('live')">实盘 (ws)</button>
|
</div>
|
|
<div class="channel" id="markPriceCandleChannel">
|
<h3>标记价格K线频道</h3>
|
<p>URL: <span id="markPriceCandleUrl">wss://wspap.okx.com:8443/ws/v5/business</span></p>
|
<p>状态: <span class="status disconnected" id="markPriceCandleStatus">未连接</span></p>
|
<button onclick="toggleConnection()">连接/断开</button>
|
<button onclick="clearMessages()">清除消息</button>
|
<div class="chart-container">
|
<canvas id="markPriceCandleChart"></canvas>
|
</div>
|
<div class="messages" id="markPriceCandleMessages"></div>
|
</div>
|
|
<script>
|
// 存储WebSocket连接对象
|
let connection = null;
|
|
// 存储各模式的URL
|
const urls = {
|
demo: 'wss://wspap.okx.com:8443/ws/v5/business',
|
live: 'wss://ws.okx.com:8443/ws/v5/business'
|
};
|
|
// 当前模式,默认为模拟盘
|
let currentMode = 'demo';
|
|
// 标记价格K线数据
|
const markPriceCandleData = [];
|
const markPriceCandleTimes = [];
|
let markPriceCandleChart = null;
|
|
// 初始化图表
|
function initChart() {
|
const ctx = document.getElementById('markPriceCandleChart').getContext('2d');
|
markPriceCandleChart = new Chart(ctx, {
|
type: 'line',
|
data: {
|
labels: [],
|
datasets: [{
|
label: 'ETH-USDT Mark Price',
|
data: [],
|
borderColor: 'rgb(75, 192, 192)',
|
tension: 0.1
|
}]
|
},
|
options: {
|
responsive: true,
|
maintainAspectRatio: false,
|
scales: {
|
x: {
|
type: 'time',
|
time: {
|
unit: 'minute'
|
}
|
},
|
y: {
|
beginAtZero: false
|
}
|
}
|
}
|
});
|
}
|
|
// 更新图表
|
function updateChart() {
|
if (markPriceCandleChart) {
|
// 为折线图准备数据
|
const times = markPriceCandleData.map(item => item.x);
|
const prices = markPriceCandleData.map(item => item.c); // 使用收盘价
|
|
markPriceCandleChart.data.labels = times;
|
markPriceCandleChart.data.datasets[0].data = prices;
|
markPriceCandleChart.update();
|
}
|
}
|
|
// 连接/断开WebSocket连接
|
function toggleConnection() {
|
if (connection) {
|
// 如果已经连接,则断开连接
|
connection.close();
|
connection = null;
|
document.getElementById('markPriceCandleStatus').textContent = '未连接';
|
document.getElementById('markPriceCandleStatus').className = 'status disconnected';
|
} else {
|
// 如果未连接,则建立连接
|
connectToChannel();
|
}
|
}
|
|
// 清除消息
|
function clearMessages() {
|
const messagesDiv = document.getElementById('markPriceCandleMessages');
|
messagesDiv.innerHTML = '';
|
|
// 清除图表数据
|
markPriceCandleData.length = 0;
|
updateChart();
|
}
|
|
// 切换模式
|
function switchMode(mode) {
|
// 更新当前模式
|
currentMode = mode;
|
|
// 更新按钮状态
|
document.getElementById('demoModeBtn').classList.toggle('active', mode === 'demo');
|
document.getElementById('liveModeBtn').classList.toggle('active', mode === 'live');
|
|
// 更新URL显示
|
document.getElementById('markPriceCandleUrl').textContent = urls[mode];
|
}
|
|
// 连接到频道
|
function connectToChannel() {
|
const ws = new WebSocket(urls[currentMode]);
|
|
ws.onopen = function() {
|
console.log('标记价格K线频道连接成功');
|
document.getElementById('markPriceCandleStatus').textContent = '已连接';
|
document.getElementById('markPriceCandleStatus').className = 'status connected';
|
|
// 订阅标记价格K线数据 (BTC-USD-190628, 1分钟K线)
|
const subscribeMsg = {
|
op: 'subscribe',
|
args: [
|
{
|
channel: 'mark-price-candle1m',
|
instId: 'ETH-USDT'
|
}
|
]
|
};
|
ws.send(JSON.stringify(subscribeMsg));
|
|
// 初始化图表
|
if (!markPriceCandleChart) {
|
initChart();
|
}
|
};
|
|
ws.onmessage = function(event) {
|
const message = event.data;
|
console.log('标记价格K线频道收到消息:', message);
|
|
// 在页面上显示消息
|
const messagesDiv = document.getElementById('markPriceCandleMessages');
|
const messageElement = document.createElement('div');
|
|
// 尝试解析JSON消息并格式化显示
|
try {
|
const jsonData = JSON.parse(message);
|
|
// 检查是否为标记价格K线数据
|
if (jsonData.arg && jsonData.arg.channel && jsonData.arg.channel.startsWith('mark-price-candle') &&
|
jsonData.arg.instId === 'ETH-USDT' && jsonData.data && jsonData.data.length > 0) {
|
// 处理标记价格K线数据
|
// 标记价格K线数据格式: [ts, o, h, l, c]
|
// ts: 开始时间, o: 开盘价, h: 最高价, l: 最低价, c: 收盘价
|
const candleData = jsonData.data[0];
|
const ts = parseInt(candleData[0]); // 时间戳
|
const o = parseFloat(candleData[1]); // 开盘价
|
const h = parseFloat(candleData[2]); // 最高价
|
const l = parseFloat(candleData[3]); // 最低价
|
const c = parseFloat(candleData[4]); // 收盘价
|
|
// 添加时间戳到时间数组
|
markPriceCandleTimes.push(ts);
|
|
// 添加K线数据到数组
|
markPriceCandleData.push({
|
x: ts,
|
o: o,
|
h: h,
|
l: l,
|
c: c
|
});
|
|
// 限制数据点数量,只保留最近的30个
|
if (markPriceCandleData.length > 30) {
|
markPriceCandleData.shift();
|
markPriceCandleTimes.shift();
|
}
|
|
// 更新图表
|
updateChart();
|
|
console.log('标记价格K线数据:', candleData);
|
}
|
|
messageElement.innerHTML = `<strong>[${new Date().toLocaleTimeString()}]</strong> ${JSON.stringify(jsonData, null, 2)}`;
|
} catch (e) {
|
// 如果不是JSON格式,则直接显示
|
messageElement.innerHTML = `<strong>[${new Date().toLocaleTimeString()}]</strong> ${message}`;
|
}
|
|
messagesDiv.appendChild(messageElement);
|
messagesDiv.scrollTop = messagesDiv.scrollHeight;
|
};
|
|
ws.onerror = function(error) {
|
console.error('标记价格K线频道连接错误:', error);
|
document.getElementById('markPriceCandleStatus').textContent = '连接错误';
|
document.getElementById('markPriceCandleStatus').className = 'status disconnected';
|
};
|
|
ws.onclose = function() {
|
console.log('标记价格K线频道连接已关闭');
|
document.getElementById('markPriceCandleStatus').textContent = '连接已关闭';
|
document.getElementById('markPriceCandleStatus').className = 'status disconnected';
|
connection = null;
|
};
|
|
connection = ws;
|
}
|
</script>
|
</body>
|
</html>
|