Java 实现台股 TWSE/TPEx 行情采集(个股 + K 线)

摘要

在亚太金融行情系统、量化后台开发中,经常需要对接中国台湾地区证券市场,包含 TWSE 上市、TPEx 上柜股票数据。本文基于 OkHttp 封装一套生产可用的采集工具,实现个股实时行情、历史 K 线获取,搭配 SpringBoot 定时任务完成周期性同步,包含连接池复用、Gzip 压缩、完整异常捕获,数据源采用脉动行情数据 api。

一、业务场景

台股分为 TWSE 上市市场与 TPEx 上柜市场,大量亚太区域业务系统需要定时拉取个股价格用于展示、估值、数据归档。 直接手写 HTTP 请求容易遇到几个典型问题:连接未复用造成端口泄露、缺少超时控制、未开启传输压缩、没有异常兜底,线上容易出现偶发卡死。

示例个股编码: 1101 台泥、1102 亞泥、1103 嘉泥、1104 環泥、1108 幸福、1109 信大、1110 東泥。 TWSE、TPEx 市场直接传入数字股票代码即可调用,不需要额外前缀。

二、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>

三、完整行情工具类

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

import java.util.concurrent.TimeUnit;

/**
 * 台股行情采集工具
 * 支持 TWSE上市、TPEx上柜个股
 * demo编码:1101 台泥
 */
public class TwStockCollectUtil {

    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 DEMO_CODE = "1101";

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

    /**
     * 获取单只台股实时行情
     * @param code 股票数字编码
     * @return 行情json对象
     */
    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线
     * @param code 股票编码
     * @param cycle 周期 1m/5m/15m/30m/1h/1d
     * @param rows 返回数据行数
     * @return K线原始字符串
     */
    public static String getStockKline(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 quoteResp = getRealQuote(DEMO_CODE);
        System.out.println("台股1101(台泥)实时行情:\n" + quoteResp);

        String klineData = getStockKline(DEMO_CODE, "1d", 200);
        System.out.println("\n1101 日K数据:\n" + klineData);
    }
}

四、SpringBoot 定时同步任务

java 复制代码
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import com.alibaba.fastjson2.JSONObject;

@Component
@EnableScheduling
public class TwStockSyncJob {

    /**
     * 定时拉取台股行情
     * 注意:生产环境建议跟随台股交易时段启停任务,非交易时段无行情更新
     */
    @Scheduled(fixedRate = 30000)
    public void syncStockQuote() {
        JSONObject result = TwStockCollectUtil.getRealQuote("1101");
        if (result == null) {
            return;
        }
        // 业务逻辑:解析JSON、入库、价格告警、日志留存
        System.out.println("台股行情定时同步完成");
    }
}

五、返回核心字段说明

字段 释义
StockCode 股票编码
Price 最新成交价
Open 开盘价
LastClose 昨日收盘价
High 日内最高价
Low 日内最低价
BP1 买一价格
SP1 卖一价格
Diff 涨跌额
DiffRate 涨跌幅百分比
TotalVol 当日成交量
Time 行情更新时间

六、开发注意事项

  1. 请求头必须携带Accept‑Encoding: gzip,开启压缩减少网络开销;
  2. OkHttpClient 务必使用全局单例,频繁新建实例会造成 TCP 端口耗尽;
  3. 支持批量查询,code 参数传入多个股票编码,英文逗号分隔,一次性拉取多只个股;
  4. 控制请求频率,短时间大量调用会触发接口限流;
  5. 台股存在固定交易时间,休市阶段价格不会变动,业务层需要做相应判断;
  6. TWSE 上市、TPEx 上柜股票统一使用数字编码,不需要增加市场前缀。

七、总结

本文实现 TWSE 上市、TPEx 上柜台股的实时行情与 K 线数据采集,结合定时任务可以快速搭建行情同步后台。切换不同个股仅修改数字编码即可,无需改动工具逻辑,适合亚太行情展示、数据归档、量化分析类项目。

相关推荐
爱学习的小邓同学1 小时前
Golang --- (1)第一个Golang程序
开发语言·后端·golang
zx_741484812 小时前
【Python 入门】面向对象基础:类、对象、成员变量与构造方法
开发语言·python
月华路2 小时前
G1 GC 对数组与大对象(Humongous)的处理
java·jvm·算法
liangshanbo12153 小时前
虚拟列表深度面试题整理
java·开发语言·前端
ZISHU_9873 小时前
用 TLabel 给 SynTouch BioTac 数据做语义标注:从原始信号到结构化标注
开发语言·人工智能·python·数据·机器人触觉
略略略咯咯3 小时前
C#Unity
开发语言·unity·c#
gugucoding3 小时前
59. 【Java】Spring Boot 入门:第一个 Web 应用
java·开发语言·spring boot
lilian2334 小时前
Harmony os 技术实战|拼豆制图43:压缩字符矩阵上线前如何拦住错位图纸
开发语言·前端·华为·矩阵·harmonyos
进击ing小白4 小时前
Qt 无边框窗口进阶指南
开发语言·qt