印度股票K线指标:从API对接到前端可视化实战
技术实现要点
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>印度股票K线指标演示</title>
<script src="https://cdn.jsdelivr.net/npm/klinecharts@latest/dist/klinecharts.min.js"></script>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
padding: 20px;
}
.container {
max-width: 1400px;
margin: 0 auto;
background: white;
border-radius: 15px;
box-shadow: 0 20px 40px rgba(0,0,0,0.1);
overflow: hidden;
}
.header {
background: #2c3e50;
color: white;
padding: 30px;
text-align: center;
}
.header h1 {
font-size: 2.5em;
margin-bottom: 10px;
}
.header p {
opacity: 0.8;
font-size: 1.1em;
}
.content {
padding: 30px;
}
.chart-container {
border: 1px solid #e0e0e0;
border-radius: 10px;
overflow: hidden;
margin-bottom: 30px;
}
#k-line-chart {
width: 100%;
height: 600px;
}
.controls {
display: flex;
justify-content: center;
gap: 15px;
margin-bottom: 20px;
flex-wrap: wrap;
}
.control-btn {
padding: 12px 25px;
border: none;
border-radius: 25px;
background: #3498db;
color: white;
font-size: 16px;
cursor: pointer;
transition: all 0.3s ease;
}
.control-btn:hover {
background: #2980b9;
transform: translateY(-2px);
}
.control-btn.active {
background: #e74c3c;
}
.indicators {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 20px;
margin-top: 30px;
}
.indicator-card {
background: #f8f9fa;
padding: 20px;
border-radius: 10px;
border-left: 4px solid #3498db;
}
.indicator-card h3 {
color: #2c3e50;
margin-bottom: 10px;
}
.stock-info {
display: flex;
justify-content: space-between;
background: #ecf0f1;
padding: 15px;
border-radius: 8px;
margin-bottom: 20px;
}
.info-item {
text-align: center;
}
.info-value {
font-size: 1.2em;
font-weight: bold;
color: #2c3e50;
}
.info-label {
font-size: 0.9em;
color: #7f8c8d;
}
@media (max-width: 768px) {
.controls {
flex-direction: column;
align-items: center;
}
.control-btn {
width: 100%;
max-width: 300px;
}
#k-line-chart {
height: 400px;
}
}
</style>
</head>
<body>
<div class="container">
<div class="header">
<h1>印度股票K线指标分析系统</h1>
<p>基于KLineChart的技术指标可视化演示</p>
</div>
<div class="content">
<div class="stock-info">
<div class="info-item">
<div class="info-value">RELIANCE.NS</div>
<div class="info-label">股票代码</div>
</div>
<div class="info-item">
<div class="info-value" id="current-price">2,845.50</div>
<div class="info-label">当前价格</div>
</div>
<div class="info-item">
<div class="info-value" id="price-change">+1.25%</div>
<div class="info-label">今日涨跌</div>
</div>
<div class="info-item">
<div class="info-value" id="volume">15.2M</div>
<div class="info-label">成交量</div>
</div>
</div>
<div class="controls">
<button class="control-btn active" onclick="changePeriod('1d')">日线图</button>
<button class="control-btn" onclick="changePeriod('1w')">周线图</button>
<button class="control-btn" onclick="changePeriod('1M')">月线图</button>
<button class="control-btn" onclick="addIndicator('MA')">添加MA均线</button>
<button class="control-btn" onclick="addIndicator('BOLL')">添加布林带</button>
<button class="control-btn" onclick="addIndicator('MACD')">添加MACD</button>
<button class="control-btn" onclick="resetChart()">重置图表</button>
</div>
<div class="chart-container">
<div id="k-line-chart"></div>
</div>
<div class="indicators">
<div class="indicator-card">
<h3>移动平均线(MA)</h3>
<p>通过计算特定周期内的平均价格来平滑价格数据,识别趋势方向。</p>
</div>
<div class="indicator-card">
<h3>布林带(BOLL)</h3>
<p>由中轨(MA)、上轨和下轨组成,反映价格波动范围和超买超卖状态。</p>
</div>
<div class="indicator-card">
<h3>MACD指标</h3>
<p>通过快慢线交叉和柱状图变化判断趋势强度和买卖信号。</p>
</div>
</div>
</div>
</div>
<script>
// 初始化图表
const chart = klinecharts.init('k-line-chart');
// 生成模拟的印度股票数据(信实工业)
const generateMockData = () => {
const data = [];
let basePrice = 2800; // 基础价格设为2800卢比
let timestamp = new Date('2024-01-01').getTime();
let volumeBase = 1000000;
for (let i = 0; i < 200; i++) {
// 生成更真实的价格波动
const volatility = 0.02; // 2%的波动率
const changePercent = (Math.random() - 0.5) * 2 * volatility;
const open = i === 0 ? basePrice : data[i-1].close;
const close = open * (1 + changePercent);
const high = Math.max(open, close) * (1 + Math.random() * 0.01);
const low = Math.min(open, close) * (1 - Math.random() * 0.01);
const volume = volumeBase + Math.floor(Math.random() * 500000);
data.push({
timestamp: timestamp + i * 24 * 60 * 60 * 1000,
open: parseFloat(open.toFixed(2)),
high: parseFloat(high.toFixed(2)),
low: parseFloat(low.toFixed(2)),
close: parseFloat(close.toFixed(2)),
volume: volume
});
}
return data;
};
// 应用初始数据
const initialData = generateMockData();
chart.applyNewData(initialData);
// 添加默认技术指标
chart.createTechnicalIndicator('MA', false, {
id: 'candle_pane',
calcParams: [5, 10, 20]
});
// 更新股票信息显示
function updateStockInfo() {
const lastDataPoint = initialData[initialData.length - 1];
document.getElementById('current-price').textContent = lastDataPoint.close.toLocaleString();
const change = ((lastDataPoint.close - lastDataPoint.open) / lastDataPoint.open * 100).toFixed(2);
const changeElement = document.getElementById('price-change');
changeElement.textContent = (change >= 0 ? '+' : '') + change + '%';
changeElement.style.color = change >= 0 ? '#27ae60' : '#e74c3c';
document.getElementById('volume').textContent = (lastDataPoint.volume / 1000000).toFixed(1) + 'M';
}
// 切换时间周期
window.changePeriod = (period) => {
// 移除所有按钮的active类
document.querySelectorAll('.control-btn').forEach(btn => {
btn.classList.remove('active');
});
// 为当前按钮添加active类
event.target.classList.add('active');
// 在实际应用中,这里会从API获取不同周期的数据
// 本例中我们简单过滤数据来模拟不同周期
let filteredData = [];
const dataPointCount = period === '1d' ? 200 : period === '1w' ? 40 : 20;
for (let i = 0; i < initialData.length; i += period === '1d' ? 1 : period === '1w' ? 5 : 22) {
if (filteredData.length < dataPointCount) {
filteredData.push(initialData[i]);
}
}
chart.applyNewData(filteredData);
};
// 添加技术指标
window.addIndicator = (indicatorType) => {
try {
switch(indicatorType) {
case 'MA':
chart.createTechnicalIndicator('MA', false, {
calcParams: [5, 10, 20]
});
break;
case 'BOLL':
chart.createTechnicalIndicator('BOLL');
break;
case 'MACD':
chart.createTechnicalIndicator('MACD');
break;
}
} catch (e) {
console.log('指标已存在或添加失败:', e);
}
};
// 重置图表
window.resetChart = () => {
// 清除所有技术指标
const technicalIndicators = chart.getTechnicalIndicators();
technicalIndicators.forEach(indicator => {
if (indicator.name !== 'MA') { // 保留主图MA
chart.removeTechnicalIndicator(indicator.paneId, indicator.name);
}
});
// 重新应用数据
chart.applyNewData(initialData);
// 重置按钮状态
document.querySelectorAll('.control-btn').forEach(btn => {
btn.classList.remove('active');
});
document.querySelectorAll('.control-btn')[0].classList.add('active');
};
// 初始化股票信息
updateStockInfo();
// 模拟实时数据更新
setInterval(() => {
const lastDataPoint = initialData[initialData.length - 1];
const newTimestamp = lastDataPoint.timestamp + 24 * 60 * 60 * 1000;
const changePercent = (Math.random() - 0.5) * 0.04; // ±2%的波动
const newDataPoint = {
timestamp: newTimestamp,
open: lastDataPoint.close,
close: parseFloat((lastDataPoint.close * (1 + changePercent)).toFixed(2)),
high: parseFloat((lastDataPoint.close * (1 + Math.max(changePercent, 0) + Math.random() * 0.02)).toFixed(2)),
low: parseFloat((lastDataPoint.close * (1 + Math.min(changePercent, 0) - Math.random() * 0.02)).toFixed(2)),
volume: lastDataPoint.volume + Math.floor(Math.random() * 100000) - 50000
};
initialData.push(newDataPoint);
chart.updateData(newDataPoint);
updateStockInfo();
}, 5000);
</script>
</body>
</html>
1. 数据模拟与格式化
- 使用算法生成符合印度股市特点的模拟数据
- 价格波动模拟真实市场行为(±2%日内波动)
- 时间戳格式符合KLineChart要求
2. 技术指标集成
- 移动平均线(MA):5日、10日、20日均线
- 布林带(BOLL):反映价格波动范围
- MACD指标:趋势强度和买卖信号判断
3. 响应式设计
- 适配桌面和移动端设备
- 灵活的网格布局和控件排列
- 触摸友好的交互设计
4. 实时数据更新
- 模拟实时市场数据推送
- 动态更新价格和指标显示
- 平滑的图表过渡动画
这个实现展示了完整的K线图表系统,可以直接在浏览器中运行。需要实时数据可以对接API获取展示
935

被折叠的 条评论
为什么被折叠?



