印尼雅加达综合指数(JCI)数据对接实战指南

印尼雅加达综合指数(JCI)数据对接实战指南

本文介绍了如何通过API接口获取印尼股市数据,重点讲解雅加达综合指数(JCI)的实时行情、历史K线等数据的获取方法,并提供完整的代码示例。

一、API接口概述

本文使用的金融数据API提供了全面的印尼股市数据服务,包括:

  • 股票列表查询 - 获取印尼交易所所有上市公司信息
  • 指数数据 - 获取雅加达综合指数(JCI)等主要指数
  • 实时行情 - 获取个股和指数的实时价格数据
  • 历史K线 - 获取不同时间周期的K线数据
  • 公司信息 - 获取上市公司基本资料
  • WebSocket推送 - 实时行情推送

二、印尼市场标识

在调用API前,需要了解印尼市场的标识参数:

  • 国家ID: 42 (印尼的国家编号)
  • 交易所: 雅加达证券交易所(IDX)
  • 主要指数: 雅加达综合指数(JCI)

三、核心API接口详解

3.1 获取印尼股票列表

接口地址: GET /stock/stocks

请求参数:

GET https://api.stocktv.top/stock/stocks?countryId=42&pageSize=50&page=1&key=您的API_KEY

参数说明:

  • countryId=42 - 印尼国家编号
  • pageSize=50 - 每页返回数量
  • page=1 - 页码
  • key - API访问密钥

响应示例:

{
  "code": 200,
  "message": "操作成功",
  "data": {
    "records": [
      {
        "id": 41602,
        "name": "Bank Central Asia",
        "symbol": "BBCA",
        "last": 9250,
        "chg": 50,
        "chgPct": 0.54,
        "volume": 1241700,
        "marketCap": "2024700000000",
        "sector": "Financials",
        "industry": "Banking",
        "url": "/equities/bank-central-asia"
      },
      // 更多股票...
    ],
    "total": 683,
    "size": 50,
    "current": 1,
    "pages": 14
  }
}

3.2 获取印尼指数数据

接口地址: GET /stock/indices

请求参数:

GET https://api.stocktv.top/stock/indices?countryId=42&key=您的API_KEY

响应示例:

{
  "code": 200,
  "message": "操作成功",
  "data": [
    {
      "id": 17940,
      "name": "Jakarta Composite Index",
      "symbol": "JCI",
      "last": 7296.83,
      "high": 7312.45,
      "low": 7254.67,
      "chg": 42.16,
      "chgPct": 0.58,
      "time": 1725002394,
      "url": "/indices/jakarta-composite"
    },
    {
      "id": 17941,
      "name": "LQ45 Index",
      "symbol": "LQ45",
      "last": 985.32,
      "chg": 8.45,
      "chgPct": 0.86,
      "time": 1725002394
    }
    // 更多指数...
  ]
}

3.3 获取指数K线数据

接口地址: GET /stock/kline

请求参数:

GET https://api.stocktv.top/stock/kline?pid=17940&interval=P1D&key=您的API_KEY

参数说明:

  • pid=17940 - 雅加达综合指数的产品ID
  • interval=P1D - 时间周期(日线)
  • 可选周期: PT5M(5分钟), PT15M(15分钟), PT1H(1小时), P1D(日线), P1W(周线), P1M(月线)

响应示例:

{
  "code": 200,
  "message": "操作成功",
  "data": [
    {
      "time": 1722384000000,
      "open": 7254.67,
      "high": 7312.45,
      "low": 7248.92,
      "close": 7296.83,
      "volume": 4521800000,
      "vo": 32845600000000
    },
    {
      "time": 1722297600000,
      "open": 7236.45,
      "high": 7268.92,
      "low": 7215.28,
      "close": 7254.67,
      "volume": 4125600000,
      "vo": 29874500000000
    }
    // 更多K线数据...
  ]
}

3.4 通过ID查询特定指数

接口地址: GET /stock/indicesById

请求参数:

GET https://api.stocktv.top/stock/indicesById?id=17940&key=您的API_KEY

四、代码实战示例

4.1 Python获取雅加达综合指数数据

import requests
import pandas as pd
from datetime import datetime

class IndonesiaStockAPI:
    def __init__(self, api_key):
        self.base_url = "https://api.stocktv.top"
        self.api_key = api_key
        self.headers = {
            'Content-Type': 'application/json'
        }
    
    def get_jci_index(self):
        """获取雅加达综合指数实时数据"""
        url = f"{self.base_url}/stock/indices?countryId=42&key={self.api_key}"
        try:
            response = requests.get(url, headers=self.headers)
            data = response.json()
            
            if data['code'] == 200:
                # 查找雅加达综合指数
                for index in data['data']:
                    if index['symbol'] == 'JCI':
                        return index
            return None
        except Exception as e:
            print(f"获取指数数据失败: {e}")
            return None
    
    def get_jci_kline(self, interval='P1D', limit=100):
        """获取JCI历史K线数据"""
        # 首先获取JCI的PID
        jci_data = self.get_jci_index()
        if not jci_data:
            return None
        
        pid = jci_data['id']
        url = f"{self.base_url}/stock/kline?pid={pid}&interval={interval}&key={self.api_key}"
        
        try:
            response = requests.get(url, headers=self.headers)
            data = response.json()
            
            if data['code'] == 200:
                # 转换为DataFrame
                df = pd.DataFrame(data['data'])
                df['date'] = pd.to_datetime(df['time'], unit='ms')
                df.set_index('date', inplace=True)
                return df
            return None
        except Exception as e:
            print(f"获取K线数据失败: {e}")
            return None

# 使用示例
if __name__ == "__main__":
    api = IndonesiaStockAPI("您的API_KEY")
    
    # 获取实时指数
    jci_data = api.get_jci_index()
    if jci_data:
        print(f"雅加达综合指数: {jci_data['last']}")
        print(f"涨跌: {jci_data['chg']} ({jci_data['chgPct']}%)")
    
    # 获取历史K线
    jci_kline = api.get_jci_kline(interval='P1D', limit=30)
    if jci_kline is not None:
        print("\n最近5个交易日数据:")
        print(jci_kline[['open', 'high', 'low', 'close', 'volume']].head())

4.2 JavaScript实时监控示例

// 印尼股市实时监控面板
class IndonesiaStockMonitor {
    constructor(apiKey) {
        this.apiKey = apiKey;
        this.baseUrl = 'https://api.stocktv.top';
        this.wsUrl = 'wss://ws-api.stocktv.top/connect';
        this.socket = null;
    }
    
    // 初始化监控面板
    async init() {
        await this.loadIndices();
        this.connectWebSocket();
        this.setupAutoRefresh();
    }
    
    // 加载指数数据
    async loadIndices() {
        try {
            const response = await fetch(`${this.baseUrl}/stock/indices?countryId=42&key=${this.apiKey}`);
            const data = await response.json();
            
            if (data.code === 200) {
                this.displayIndices(data.data);
            }
        } catch (error) {
            console.error('加载指数数据失败:', error);
        }
    }
    
    // 显示指数数据
    displayIndices(indices) {
        const container = document.getElementById('indices-container');
        container.innerHTML = '';
        
        indices.forEach(index => {
            const changeClass = index.chg >= 0 ? 'positive' : 'negative';
            const changeIcon = index.chg >= 0 ? '↑' : '↓';
            
            const indexElement = `
                <div class="index-card">
                    <h3>${index.name} (${index.symbol})</h3>
                    <div class="price">${index.last.toLocaleString()}</div>
                    <div class="change ${changeClass}">
                        ${changeIcon} ${Math.abs(index.chg)} (${Math.abs(index.chgPct)}%)
                    </div>
                    <div class="time">${this.formatTime(index.time)}</div>
                </div>
            `;
            
            container.innerHTML += indexElement;
        });
    }
    
    // 连接WebSocket获取实时数据
    connectWebSocket() {
        this.socket = new WebSocket(`${this.wsUrl}?key=${this.apiKey}`);
        
        this.socket.onopen = () => {
            console.log('WebSocket连接已建立');
            // 订阅印尼指数
            this.socket.send(JSON.stringify({
                action: 'subscribe',
                symbols: ['PID:17940'] // JCI的PID
            }));
        };
        
        this.socket.onmessage = (event) => {
            const data = JSON.parse(event.data);
            this.updateRealTimeData(data);
        };
        
        this.socket.onerror = (error) => {
            console.error('WebSocket错误:', error);
        };
    }
    
    // 更新实时数据
    updateRealTimeData(data) {
        if (data.pid === 17940) { // JCI的PID
            const jciElement = document.querySelector('.index-card:first-child');
            if (jciElement) {
                const priceElement = jciElement.querySelector('.price');
                const changeElement = jciElement.querySelector('.change');
                const timeElement = jciElement.querySelector('.time');
                
                priceElement.textContent = data.last_numeric.toLocaleString();
                
                const changeClass = data.pc >= 0 ? 'positive' : 'negative';
                const changeIcon = data.pc >= 0 ? '↑' : '↓';
                
                changeElement.className = `change ${changeClass}`;
                changeElement.innerHTML = `${changeIcon} ${Math.abs(data.pc)} (${Math.abs(data.pcp)}%)`;
                
                timeElement.textContent = this.formatTime(data.timestamp);
            }
        }
    }
    
    // 设置自动刷新
    setupAutoRefresh() {
        // 每分钟刷新一次指数数据
        setInterval(() => {
            this.loadIndices();
        }, 60000);
    }
    
    // 时间格式化
    formatTime(timestamp) {
        return new Date(timestamp * 1000).toLocaleTimeString();
    }
}

// 页面加载完成后初始化
document.addEventListener('DOMContentLoaded', () => {
    const monitor = new IndonesiaStockMonitor('您的API_KEY');
    monitor.init();
});

4.3 对应的HTML结构

<!DOCTYPE html>
<html>
<head>
    <title>印尼股市实时监控</title>
    <style>
        .index-card {
            border: 1px solid #ddd;
            border-radius: 8px;
            padding: 15px;
            margin: 10px;
            background: #f9f9f9;
        }
        .price {
            font-size: 24px;
            font-weight: bold;
            margin: 10px 0;
        }
        .change.positive {
            color: green;
        }
        .change.negative {
            color: red;
        }
        .time {
            color: #666;
            font-size: 12px;
        }
        #indices-container {
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
            gap: 15px;
        }
    </style>
</head>
<body>
    <h1>印尼雅加达综合指数实时监控</h1>
    <div id="indices-container">
        <!-- 指数数据将在这里动态显示 -->
    </div>
    
    <script src="indonesia-stock-monitor.js"></script>
</body>
</html>

五、注意事项

  1. API密钥安全: 不要在前端代码中硬编码API密钥,建议通过后端代理调用
  2. 频率限制: 遵守API的调用频率限制,避免频繁请求
  3. 错误处理: 完善错误处理机制,处理网络异常和API限制
  4. 数据缓存: 对不经常变化的数据实施缓存策略,减少API调用
  5. 时区处理: 注意印尼位于东七区(UTC+7),时间显示需要相应调整

六、总结

开发者可以轻松获取印尼雅加达综合指数及相关股票的实时行情和历史数据。这些数据可以用于:

  1. 构建印尼股市实时监控系统
  2. 开发量化交易策略
  3. 进行技术分析和基本面研究
  4. 创建金融数据可视化面板
  5. 开发移动端股市应用

印尼作为东南亚最大的经济体之一,其股市数据对于区域投资者和研究人员具有重要价值。通过API接口获取这些数据,可以为投资决策和市场研究提供有力支持。

提示:本文示例代码仅供参考,实际使用时请替换为有效的API密钥,并遵守API提供商的使用条款。

posted @ 2025-09-29 16:13  CryptoPP  阅读(18)  评论(0)    收藏  举报