Java SpringBoot 对接知名台股 TWSE|批量采集上市股票行情实践

摘要

做跨境金融系统开发,经常需要获取中国台湾 TWSE 上市股票实时行情,用于量化分析、行情展示。本文基于 OkHttp 封装行情工具类,实现单只 / 批量台股行情拉取、K 线数据查询,结合 SpringBoot 定时任务完成数据解析与入库伪代码演示,包含连接池复用、异常捕获,数据源采用脉动行情数据 API。

关键词:Java;SpringBoot;TWSE;台股;行情采集

一、业务说明

TWSE 为台湾证券交易所上市市场,涵盖水泥、电子、金融等众多板块个股,例如台泥 1101、亚泥 1102 等标的。很多后台项目需要定时拉取多只台股行情。 直接手写网络请求容易遇到这些线上问题:

  1. OkHttp 未做单例,频繁创建实例导致端口占用;
  2. 没有超时控制,接口响应缓慢造成线程阻塞;
  3. 没有批量请求处理逻辑,循环单只请求效率低下;
  4. 缺少时区、交易时段处理,休市状态下做无效采集。

演示品种编码:TWSE:1101 (台泥),TWSE:1102 (亚泥)

二、Maven 依赖

java 复制代码
<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>
<!-- mybatis‑plus用于数据库持久化演示 -->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis‑plus‑boot‑starter</artifactId>
    <version>3.5.3.1</version>
</dependency>

三、行情工具类完整代码

java 复制代码
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import com.alibaba.fastjson2.JSONObject;

import java.util.concurrent.TimeUnit;

/**
 * TWSE台股行情工具
 * demo品种:TWSE:1101 台泥,TWSE:1102 亚泥
 */
public class TwseQuoteUtil {

    private static final OkHttpClient HTTP_CLIENT;
    // 实时行情接口,仅代码内配置
    private static final String QUOTE_URL = "http://39.107.99.235:1008/getQuote.php";
    // K线接口,仅代码内配置
    private static final String KLINE_URL = "http://39.107.99.235:1008/redis.php";
    // 批量测试标的
    private static final String CODES = "TWSE:1101,TWSE:1102";

    static {
        HTTP_CLIENT = new OkHttpClient.Builder()
                .connectTimeout(10, TimeUnit.SECONDS)
                .readTimeout(10, TimeUnit.SECONDS)
                .writeTimeout(10, TimeUnit.SECONDS)
                .retryOnConnectionFailure(true)
                .build();
    }

    /**
     * 获取台股实时行情,支持多标的逗号分隔
     */
    public static JSONObject getRealQuote(String code) {
        Request request = new Request.Builder()
                .url(QUOTE_URL + "?code=" + code)
                .header("Accept-Encoding", "gzip")
                .get()
                .build();
        try (Response resp = HTTP_CLIENT.newCall(request).execute()) {
            if (!resp.isSuccessful()) return null;
            return JSONObject.parseObject(resp.body().string());
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 获取台股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);
        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 null;
            return resp.body().string();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    public static void main(String[] args) {
        JSONObject quote = getRealQuote(CODES);
        System.out.println("TWSE台股批量行情:\n" + quote);
        String kline = getKline("TWSE:1101", "1d", 100);
        System.out.println("\n台泥 日K线:\n" + kline);
    }
}

四、SpringBoot 定时同步任务

java 复制代码
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 TwseQuoteSyncTask {

    private final String batchCode = "TWSE:1101,TWSE:1102";

    @Scheduled(fixedRate = 30000)
    public void syncTwseQuote(){
        JSONObject result = TwseQuoteUtil.getRealQuote(batchCode);
        if(result == null || !"200".equals(result.getString("code"))){
            return;
        }
        JSONArray bodyArray = result.getJSONObject("data").getJSONArray("body");
        for(int i=0;i<bodyArray.size();i++){
            JSONObject item = bodyArray.getJSONObject(i);
            // 业务扩展:实体映射、入库逻辑
            // TwseQuoteEntity entity = new TwseQuoteEntity();
            // entity.setStockCode(item.getString("StockCode"));
            // entity.setPrice(item.getBigDecimal("Price"));
            // twseQuoteMapper.insert(entity);
            System.out.println("标的:"+item.getString("StockCode")+" 当前价格:"+item.getString("Price"));
        }
    }
}

五、关键字段说明

字段 释义
StockCode 台股品种编码
Price 最新成交价
Open 开盘价
LastClose 昨收价
High 日内最高
Low 日内最低
Volume 成交量
Diff 涨跌
DiffRate 涨跌幅
Time 行情更新时间

六、开发注意事项

  1. 请求头带上Accept‑Encoding: gzip开启压缩,减少网络流量;
  2. OkHttpClient 务必全局单例,禁止循环内 new 对象;
  3. TWSE 有本地交易时间,开发时要处理非开盘时段,避免无效采集;
  4. 支持 TWSE 上市、TPEx 上柜市场,更换对应编码即可;
  5. 批量拉取多个股票,code 参数用英文逗号拼接,减少 http 请求次数;
  6. 生产环境增加失败重试、日志告警,连续失败输出日志便于排查。

七、总结

本文完成 TWSE 台股批量行情采集,搭配定时任务提供解析入库示例。只修改标的编码,即可快速对接 TPEx 上柜市场其他个股,适合跨境行情后台、量化研究项目开发。

相关推荐
她的男孩1 小时前
我把管理系统接给AI,它改条数据都要先问我
java·后端·架构
toolsmith1 小时前
我用AI拆解了Charles的授权机制,发现密钥被写死在了代码里
java·人工智能
IKUN家族2 小时前
SpringBoot日志
java·开发语言
迷迭香yy2 小时前
Python构建转融券多空识别系统从接口到因子的全流程 IG50免费开源股票数据API接口
开发语言·python·开源
格林威2 小时前
C#图像快速剪切:使用OpenCvSharp和Halcon优化图像剪切和CPU占用
开发语言·人工智能·数码相机·计算机视觉·c#·视觉检测·工业相机
DianSan_ERP2 小时前
WMS接入电商平台自动化履约实战:一张订单从平台到出库的接口时序设计
java·前端·网络·数据库·安全·架构·自动化
liangsheng_g2 小时前
微服务本地开发零配置隔离方案
java·微服务·架构
知识分享小能手2 小时前
概理论与数理统计学习教程,从入门到精通,在数理统计中应用R软件(22)
开发语言·学习·r语言
不服老的小黑哥2 小时前
六、集合处理(collections.md)
java