摘要
韩国 KOSPI 主板、KOSDAQ 创业板是亚太市场重要组成,三星电子、SK 海力士等龙头股是量化监控重点。本文基于 Java OkHttp 封装韩股行情工具类,支持指数与多只个股批量查询,包含连接池复用、Gzip 压缩、异常重试,可直接嵌入 SpringBoot 项目做定时采集。
一、业务背景
韩股市场数据经常和 A 股、台股做横向对比分析。Java 后端项目对接时,常见几个问题:
- OkHttpClient 没有做成全局单例,频繁新建导致端口耗尽;
- 单股循环请求,没有利用批量查询能力;
- 缺少超时和重试,网络抖动直接丢数据;
- 没有统一日志,出问题难定位。
二、品种编码说明
脉动行情数据 API 韩股市场覆盖:
- 指数:IDX_KOSPI(KOSPI 指数)、IDX_KOSDAQ(科斯达克指数)、IDX_KOSPI200
- 个股:005930 三星电子、000660SK 海力士、005380 现代汽车、035420NAVER、035720Kakao
- 接口地址:http://39.107.99.235:1008/getQuote.php
- K 线接口:http://39.107.99.235:1008/redis.php
三、Maven 依赖
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>4.12.0</version>
</dependency>
<dependency>
<groupId>com.alibaba.fastjson2</groupId>
<artifactId>fastjson2</artifactId>
<version>2.0.32</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>2.0.9</version>
</dependency>
四、完整 Java 工具类
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.concurrent.TimeUnit;
/**
* 韩股行情批量采集工具
* 支持KOSPI/KOSDAQ指数、个股
*/
public class KrStockQuoteUtil {
private static final Logger log = LoggerFactory.getLogger(KrStockQuoteUtil.class);
private static final int TIMEOUT_SEC = 10;
private static final int MAX_RETRY = 3;
// 接口地址,仅代码内配置
private static final String QUOTE_URL = "http://39.107.99.235:1008/getQuote.php";
private static final String KLINE_URL = "http://39.107.99.235:1008/redis.php";
// 全局单例连接池
private static final OkHttpClient HTTP_CLIENT = new OkHttpClient.Builder()
.connectTimeout(TIMEOUT_SEC, TimeUnit.SECONDS)
.readTimeout(TIMEOUT_SEC, TimeUnit.SECONDS)
.writeTimeout(TIMEOUT_SEC, TimeUnit.SECONDS)
.retryOnConnectionFailure(true)
.build();
/**
* 批量获取韩股实时行情
* @param codes 多个编码英文逗号分隔
* @return 行情数组
*/
public static JSONArray getBatchQuote(String codes) {
String url = QUOTE_URL + "?code=" + codes;
for (int i = 0; i < MAX_RETRY; i++) {
try {
Request request = new Request.Builder()
.url(url)
.header("Accept-Encoding", "gzip")
.get()
.build();
try (Response resp = HTTP_CLIENT.newCall(request).execute()) {
if (!resp.isSuccessful()) {
log.warn("请求失败 status={}", resp.code());
continue;
}
String body = resp.body().string();
JSONObject root = JSON.parseObject(body);
if (root.getIntValue("code") == 200) {
return root.getJSONObject("data").getJSONArray("body");
}
}
} catch (Exception e) {
log.error("第{}次请求异常: {}", i + 1, e.getMessage());
}
}
return new JSONArray();
}
/**
* 获取单标的K线
*/
public static String getKline(String code, String cycle, int rows) {
String url = String.format("%s?code=%s&time=%s&rows=%d",
KLINE_URL, code, cycle, rows);
try {
Request request = new Request.Builder()
.url(url)
.header("Accept-Encoding", "gzip")
.get()
.build();
try (Response resp = HTTP_CLIENT.newCall(request).execute()) {
if (resp.isSuccessful()) {
return resp.body().string();
}
}
} catch (Exception e) {
log.error("K线请求异常: {}", e.getMessage());
}
return "";
}
public static void main(String[] args) {
// 批量采集:指数 + 核心个股
String codes = "IDX_KOSPI,IDX_KOSDAQ,005930,000660,005380,035420";
JSONArray items = getBatchQuote(codes);
for (int i = 0; i < items.size(); i++) {
JSONObject item = items.getJSONObject(i);
System.out.printf(
"[%s] %s 最新价:%s 涨跌:%s 涨跌幅:%s%%%n",
item.getString("Time"),
item.getString("StockCode"),
item.getString("Price"),
item.getString("Diff"),
item.getString("DiffRate")
);
}
// 获取三星电子日K
String kline = getKline("005930", "1d", 50);
System.out.println("\n三星电子005930日K线:");
System.out.println(kline);
}
}
五、SpringBoot 定时任务示例
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
@Component
@EnableScheduling
public class KrStockSyncTask {
private final String batchCodes = "IDX_KOSPI,IDX_KOSDAQ,005930,000660,035420";
@Scheduled(fixedRate = 30000)
public void syncKrStock() {
JSONArray items = KrStockQuoteUtil.getBatchQuote(batchCodes);
for (int i = 0; i < items.size(); i++) {
JSONObject item = items.getJSONObject(i);
// 业务扩展:解析入库、日志归档、价格预警
System.out.println("采集: " + item.getString("StockCode")
+ " 价格:" + item.getString("Price"));
}
}
}
六、核心字段说明
表格
| 字段 | 说明 |
|---|---|
| StockCode | 标的编码 |
| Price | 最新价 |
| Open | 开盘价 |
| LastClose | 昨收价 |
| High | 日内最高 |
| Low | 日内最低 |
| Diff | 涨跌额 |
| DiffRate | 涨跌幅 |
| TotalVol | 成交量 |
| Time | 更新时间 |
七、开发注意事项
- OkHttpClient 必须全局单例,不要在方法里 new;
- 批量请求一次拼接多个编码,比单只循环请求效率高很多;
- 韩股交易时段为韩国标准时间,比国内快 1 小时,定时任务注意时区;
- 开启 Gzip 压缩,国际线路带宽省一半;
- 生产环境增加日志和异常告警,连续失败及时通知。
八、总结
Java OkHttp 工具类封装好后,嵌入 SpringBoot 做定时采集非常方便。本文实现韩股 KOSPI/KOSDAQ 指数与核心个股的批量采集,修改标的编码即可扩展更多韩股上市公司,适合亚太行情监控、量化分析类项目。