Java对接StockTV印度股票API一、环境准备与基础配置1. 添加依赖在pom.xml中添加必要的依赖dependencies !-- HTTP客户端 -- dependency groupIdorg.apache.httpcomponents/groupId artifactIdhttpclient/artifactId version4.5.13/version /dependency !-- JSON处理 -- dependency groupIdcom.fasterxml.jackson.core/groupId artifactIdjackson-databind/artifactId version2.15.2/version /dependency !-- 如果需要WebSocket -- dependency groupIdorg.java-websocket/groupId artifactIdJava-WebSocket/artifactId version1.5.3/version /dependency /dependencies2. 基础配置类package com.stocktv.india; import com.fasterxml.jackson.databind.ObjectMapper; import org.apache.http.HttpEntity; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.util.EntityUtils; import java.io.IOException; import java.util.HashMap; import java.util.Map; public class StockTVIndiaAPI { private static final String BASE_URL https://api.stocktv.top; private static final String API_KEY 您的API_KEY; // 请替换为实际的Key private static final ObjectMapper objectMapper new ObjectMapper(); private static final int INDIA_COUNTRY_ID 14; // 印度的countryId /** * 发送HTTP GET请求 */ private static String sendGetRequest(String endpoint, MapString, String params) throws IOException { StringBuilder urlBuilder new StringBuilder(BASE_URL endpoint); params.put(key, API_KEY); if (!params.isEmpty()) { urlBuilder.append(?); for (Map.EntryString, String entry : params.entrySet()) { urlBuilder.append(entry.getKey()) .append() .append(java.net.URLEncoder.encode(entry.getValue(), UTF-8)) .append(); } urlBuilder.deleteCharAt(urlBuilder.length() - 1); // 移除最后一个 } try (CloseableHttpClient httpClient HttpClients.createDefault()) { HttpGet httpGet new HttpGet(urlBuilder.toString()); try (CloseableHttpResponse response httpClient.execute(httpGet)) { HttpEntity entity response.getEntity(); if (entity ! null) { return EntityUtils.toString(entity); } } } return null; } /** * 解析JSON响应 */ private static T T parseResponse(String json, ClassT clazz) throws IOException { return objectMapper.readValue(json, clazz); } }二、核心API接口实现1. 获取印度股票市场列表package com.stocktv.india; import com.fasterxml.jackson.annotation.JsonProperty; import java.util.List; import java.util.Map; public class MarketListResponse { JsonProperty(code) private int code; JsonProperty(message) private String message; JsonProperty(data) private MarketData data; // 数据类 public static class MarketData { JsonProperty(records) private ListStockRecord records; JsonProperty(total) private int total; JsonProperty(size) private int size; JsonProperty(current) private int current; JsonProperty(pages) private int pages; // Getters public ListStockRecord getRecords() { return records; } public int getTotal() { return total; } public int getSize() { return size; } public int getCurrent() { return current; } public int getPages() { return pages; } } // 股票记录类 public static class StockRecord { JsonProperty(id) private Long id; // pid JsonProperty(name) private String name; // 股票名称 JsonProperty(symbol) private String symbol; // 股票代码 JsonProperty(last) private Double last; // 最新价 JsonProperty(chg) private Double chg; // 涨跌额 JsonProperty(chgPct) private Double chgPct; // 涨跌百分比 JsonProperty(high) private Double high; // 最高价 JsonProperty(low) private Double low; // 最低价 JsonProperty(volume) private Long volume; // 成交量 JsonProperty(open) private Boolean open; // 是否开市 JsonProperty(countryId) private Integer countryId; // 国家ID JsonProperty(countryNameTranslated) private String countryNameTranslated; // 国家名称 JsonProperty(flag) private String flag; // 国家简称 JsonProperty(exchangeId) private Integer exchangeId; // 交易所ID JsonProperty(lastClose) private Double lastClose; // 前收盘价 // Getters public Long getId() { return id; } public String getName() { return name; } public String getSymbol() { return symbol; } public Double getLast() { return last; } public Double getChg() { return chg; } public Double getChgPct() { return chgPct; } public Double getHigh() { return high; } public Double getLow() { return low; } public Long getVolume() { return volume; } public Boolean getOpen() { return open; } public Integer getCountryId() { return countryId; } public String getCountryNameTranslated() { return countryNameTranslated; } public String getFlag() { return flag; } public Integer getExchangeId() { return exchangeId; } public Double getLastClose() { return lastClose; } } // Getters public int getCode() { return code; } public String getMessage() { return message; } public MarketData getData() { return data; } }package com.stocktv.india; import java.io.IOException; import java.util.HashMap; import java.util.Map; public class IndiaStockService { private static final int INDIA_COUNTRY_ID 14; /** * 获取印度股票市场列表 */ public static MarketListResponse getIndiaStockList(int page, int pageSize) throws IOException { MapString, String params new HashMap(); params.put(countryId, String.valueOf(INDIA_COUNTRY_ID)); params.put(page, String.valueOf(page)); params.put(pageSize, String.valueOf(pageSize)); String response StockTVIndiaAPI.sendGetRequest(/stock/stocks, params); return StockTVIndiaAPI.parseResponse(response, MarketListResponse.class); } /** * 示例获取印度股票列表并打印 */ public static void main(String[] args) { try { MarketListResponse response getIndiaStockList(1, 10); if (response.getCode() 200 response.getData() ! null) { System.out.println(印度股票列表 (共 response.getData().getTotal() 只股票):); System.out.println(); for (MarketListResponse.StockRecord stock : response.getData().getRecords()) { System.out.printf(股票: %-30s 代码: %-10s 最新价: %8.2f 涨跌: %6.2f%%\n, stock.getName(), stock.getSymbol(), stock.getLast(), stock.getChgPct()); } } else { System.out.println(请求失败: response.getMessage()); } } catch (IOException e) { e.printStackTrace(); } } }2. 查询特定印度股票public class QueryStockResponse { JsonProperty(code) private int code; JsonProperty(message) private String message; JsonProperty(data) private ListMarketListResponse.StockRecord data; // Getters public int getCode() { return code; } public String getMessage() { return message; } public ListMarketListResponse.StockRecord getData() { return data; } } public class IndiaStockQueryService { /** * 查询印度股票通过PID、名称或代码 */ public static QueryStockResponse queryIndiaStock(Long pid, String symbol, String name) throws IOException { MapString, String params new HashMap(); if (pid ! null) { params.put(id, pid.toString()); } if (symbol ! null !symbol.isEmpty()) { params.put(symbol, symbol); } if (name ! null !name.isEmpty()) { params.put(name, name); } String response StockTVIndiaAPI.sendGetRequest(/stock/queryStocks, params); QueryStockResponse result StockTVIndiaAPI.parseResponse(response, QueryStockResponse.class); // 筛选印度股票根据countryId14或flagIN if (result.getCode() 200 result.getData() ! null) { ListMarketListResponse.StockRecord filteredList result.getData().stream() .filter(stock - stock.getCountryId() ! null stock.getCountryId() INDIA_COUNTRY_ID) .collect(Collectors.toList()); // 创建新的响应对象 QueryStockResponse filteredResponse new QueryStockResponse(); filteredResponse.setCode(result.getCode()); filteredResponse.setMessage(result.getMessage()); filteredResponse.setData(filteredList); return filteredResponse; } return result; } }3. 获取印度K线数据public class KlineData { JsonProperty(time) private Long time; // 时间戳 JsonProperty(open) private Double open; // 开盘价 JsonProperty(high) private Double high; // 最高价 JsonProperty(low) private Double low; // 最低价 JsonProperty(close) private Double close; // 收盘价 JsonProperty(volume) private Double volume; // 成交量 JsonProperty(vo) private Double vo; // 成交额 // Getters public Long getTime() { return time; } public Double getOpen() { return open; } public Double getHigh() { return high; } public Double getLow() { return low; } public Double getClose() { return close; } public Double getVolume() { return volume; } public Double getVo() { return vo; } } public class KlineResponse { JsonProperty(code) private int code; JsonProperty(message) private String message; JsonProperty(data) private ListKlineData data; // Getters public int getCode() { return code; } public String getMessage() { return message; } public ListKlineData getData() { return data; } } public class IndiaKlineService { /** * 获取印度股票K线数据 * param pid 股票PID * param interval 时间间隔: PT5M, PT15M, PT1H, PT5H, P1D, P1W, P1M */ public static KlineResponse getIndiaStockKline(Long pid, String interval) throws IOException { MapString, String params new HashMap(); params.put(pid, pid.toString()); params.put(interval, interval); String response StockTVIndiaAPI.sendGetRequest(/stock/kline, params); return StockTVIndiaAPI.parseResponse(response, KlineResponse.class); } /** * 示例获取日K线数据 */ public static void printDailyKline(Long pid) { try { KlineResponse response getIndiaStockKline(pid, P1D); if (response.getCode() 200 response.getData() ! null !response.getData().isEmpty()) { System.out.println(K线数据 (日线):); System.out.println(); // 显示最近5天的数据 int count Math.min(response.getData().size(), 5); for (int i response.getData().size() - count; i response.getData().size(); i) { KlineData kline response.getData().get(i); Date date new Date(kline.getTime()); SimpleDateFormat sdf new SimpleDateFormat(yyyy-MM-dd); System.out.printf(日期: %s 开:%.2f 高:%.2f 低:%.2f 收:%.2f 量:%.0f\n, sdf.format(date), kline.getOpen(), kline.getHigh(), kline.getLow(), kline.getClose(), kline.getVolume()); } } } catch (IOException e) { e.printStackTrace(); } } }4. 获取印度市场指数public class IndicesResponse { JsonProperty(code) private int code; JsonProperty(message) private String message; JsonProperty(data) private ListIndexData data; public static class IndexData { JsonProperty(id) private Long id; JsonProperty(name) private String name; JsonProperty(symbol) private String symbol; JsonProperty(last) private Double last; JsonProperty(chg) private Double chg; JsonProperty(chgPct) private Double chgPct; JsonProperty(flag) private String flag; JsonProperty(isOpen) private Boolean isOpen; // Getters public Long getId() { return id; } public String getName() { return name; } public String getSymbol() { return symbol; } public Double getLast() { return last; } public Double getChg() { return chg; } public Double getChgPct() { return chgPct; } public String getFlag() { return flag; } public Boolean getIsOpen() { return isOpen; } } // Getters public int getCode() { return code; } public String getMessage() { return message; } public ListIndexData getData() { return data; } } public class IndiaIndicesService { /** * 获取印度市场指数 */ public static IndicesResponse getIndiaIndices() throws IOException { MapString, String params new HashMap(); params.put(countryId, String.valueOf(INDIA_COUNTRY_ID)); String response StockTVIndiaAPI.sendGetRequest(/stock/indices, params); return StockTVIndiaAPI.parseResponse(response, IndicesResponse.class); } }5. 获取印度IPO新股日历public class IpoResponse { JsonProperty(code) private int code; JsonProperty(message) private String message; JsonProperty(data) private ListIpoData data; public static class IpoData { JsonProperty(id) private Long id; JsonProperty(ipoListing) private Long ipoListing; // 上市时间戳 JsonProperty(country) private String country; JsonProperty(company) private String company; JsonProperty(exchange) private String exchange; JsonProperty(ipoPrice) private String ipoPrice; JsonProperty(last) private String last; JsonProperty(symbol) private String symbol; JsonProperty(date) private String date; JsonProperty(pid) private Long pid; // Getters public Long getId() { return id; } public Long getIpoListing() { return ipoListing; } public String getCountry() { return country; } public String getCompany() { return company; } public String getExchange() { return exchange; } public String getIpoPrice() { return ipoPrice; } public String getLast() { return last; } public String getSymbol() { return symbol; } public String getDate() { return date; } public Long getPid() { return pid; } } // Getters public int getCode() { return code; } public String getMessage() { return message; } public ListIpoData getData() { return data; } } public class IndiaIpoService { /** * 获取印度IPO信息 * param type 1未上市, 2已上市 */ public static IpoResponse getIndiaIpo(Integer type) throws IOException { MapString, String params new HashMap(); params.put(countryId, String.valueOf(INDIA_COUNTRY_ID)); if (type ! null (type 1 || type 2)) { params.put(type, type.toString()); } String response StockTVIndiaAPI.sendGetRequest(/stock/getIpo, params); return StockTVIndiaAPI.parseResponse(response, IpoResponse.class); } }6. 获取印度涨跌排行榜public class UpDownListResponse { JsonProperty(code) private int code; JsonProperty(message) private String message; JsonProperty(data) private ListMarketListResponse.StockRecord data; // Getters public int getCode() { return code; } public String getMessage() { return message; } public ListMarketListResponse.StockRecord getData() { return data; } } public class IndiaRankService { /** * 获取印度股票排行榜 * param type 1涨幅榜 2跌幅榜 3涨停榜 4跌停榜 */ public static UpDownListResponse getIndiaStockRank(int type) throws IOException { MapString, String params new HashMap(); params.put(countryId, String.valueOf(INDIA_COUNTRY_ID)); params.put(type, String.valueOf(type)); String response StockTVIndiaAPI.sendGetRequest(/stock/updownList, params); return StockTVIndiaAPI.parseResponse(response, UpDownListResponse.class); } /** * 示例打印涨幅榜TOP 10 */ public static void printTopGainers() { try { UpDownListResponse response getIndiaStockRank(1); if (response.getCode() 200 response.getData() ! null) { System.out.println(印度股票涨幅榜 TOP 10:); System.out.println(); int count Math.min(response.getData().size(), 10); for (int i 0; i count; i) { MarketListResponse.StockRecord stock response.getData().get(i); System.out.printf(%2d. %-30s %-10s %7.2f%%\n, i 1, stock.getName(), stock.getSymbol(), stock.getChgPct()); } } } catch (IOException e) { e.printStackTrace(); } } }三、WebSocket实时数据核心package com.stocktv.india.websocket; import org.java_websocket.client.WebSocketClient; import org.java_websocket.handshake.ServerHandshake; import org.json.JSONObject; import java.net.URI; import java.util.ArrayList; import java.util.List; import java.util.Timer; import java.util.TimerTask; public class IndiaStockWebSocketClient extends WebSocketClient { private static final String WS_URL wss://ws-api.stocktv.top/connect?key您的API_KEY; private ListLong subscribedPids new ArrayList(); public IndiaStockWebSocketClient() { super(URI.create(WS_URL)); } Override public void onOpen(ServerHandshake handshakedata) { System.out.println(WebSocket连接已建立); // 连接成功后发送订阅消息 if (!subscribedPids.isEmpty()) { subscribeToPids(subscribedPids); } // 启动心跳定时器 startHeartbeat(); } Override public void onMessage(String message) { // 解析实时数据 JSONObject data new JSONObject(message); String pid data.optString(pid); String lastPrice data.optString(last_numeric); String change data.optString(pc); String changePercent data.optString(pcp); String volume data.optString(turnover_numeric); System.out.printf(实时数据 - PID: %s, 最新价: %s, 涨跌额: %s, 涨跌幅: %s%%, 成交量: %s\n, pid, lastPrice, change, changePercent, volume); } Override public void onClose(int code, String reason, boolean remote) { System.out.println(WebSocket连接关闭: reason); } Override public void onError(Exception ex) { System.err.println(WebSocket错误: ex.getMessage()); } /** * 订阅股票PID */ public void subscribeToPids(ListLong pids) { this.subscribedPids pids; if (isOpen()) { JSONObject subscribeMsg new JSONObject(); subscribeMsg.put(action, subscribe); ListString pidStrings new ArrayList(); for (Long pid : pids) { pidStrings.add(pid.toString()); } subscribeMsg.put(pids, pidStrings); send(subscribeMsg.toString()); System.out.println(已发送订阅请求: subscribeMsg.toString()); } } /** * 启动心跳定时器 */ private void startHeartbeat() { Timer timer new Timer(true); timer.scheduleAtFixedRate(new TimerTask() { Override public void run() { if (isOpen()) { send(); // 发送空消息作为心跳 System.out.println(发送心跳...); } } }, 0, 30000); // 每30秒发送一次心跳 } /** * 使用示例 */ public static void main(String[] args) throws Exception { IndiaStockWebSocketClient client new IndiaStockWebSocketClient(); // 连接到WebSocket服务器 client.connectBlocking(); // 阻塞连接 // 等待连接建立 Thread.sleep(1000); // 订阅印度股票示例PID ListLong pids new ArrayList(); pids.add(7310L); // 示例PID pids.add(17976L); // 示例PID client.subscribeToPids(pids); // 保持连接 Thread.sleep(60000); // 保持连接60秒 client.close(); } }四、完整使用示例package com.stocktv.india; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.Date; public class IndiaStockAPIDemo { public static void main(String[] args) { try { // 1. 获取印度股票列表 System.out.println( 印度股票列表 ); MarketListResponse stockList IndiaStockService.getIndiaStockList(1, 10); if (stockList.getCode() 200) { for (MarketListResponse.StockRecord stock : stockList.getData().getRecords()) { System.out.printf(%s (%s): %.2f 涨跌: %.2f%%\n, stock.getName(), stock.getSymbol(), stock.getLast(), stock.getChgPct()); } } // 2. 获取印度市场指数 System.out.println(\n 印度市场指数 ); IndicesResponse indices IndiaIndicesService.getIndiaIndices(); if (indices.getCode() 200) { for (IndicesResponse.IndexData index : indices.getData()) { System.out.printf(%s (%s): %.2f 涨跌: %.2f%%\n, index.getName(), index.getSymbol(), index.getLast(), index.getChgPct()); } } // 3. 获取印度IPO信息 System.out.println(\n 印度IPO新股 ); IpoResponse ipoList IndiaIpoService.getIndiaIpo(1); // 未上市IPO if (ipoList.getCode() 200 ipoList.getData() ! null) { for (IpoResponse.IpoData ipo : ipoList.getData()) { Date listingDate new Date(ipo.getIpoListing() * 1000); SimpleDateFormat sdf new SimpleDateFormat(yyyy-MM-dd); System.out.printf(公司: %s, 发行价: %s, 上市日期: %s\n, ipo.getCompany(), ipo.getIpoPrice(), sdf.format(listingDate)); } } // 4. 获取涨跌排行榜 System.out.println(\n 印度股票涨幅榜 ); IndiaRankService.printTopGainers(); // 5. 获取K线数据假设有股票PID System.out.println(\n 印度股票K线数据 ); IndiaKlineService.printDailyKline(7310L); // 示例PID } catch (IOException e) { System.err.println(API调用失败: e.getMessage()); e.printStackTrace(); } } }五、重要注意事项API Key所有请求都需要在URL参数中添加key您的API_KEY国家ID印度固定为countryId14实时数据使用WebSocket接口获取实时行情错误处理始终检查响应中的code字段200表示成功并发限制合理控制请求频率避免过度调用六、数据结构说明从文档中的示例数据可以看到印度股票数据包含以下关键字段基础信息id(PID),name,symbol,countryId(14),flag(IN)行情数据last,chg,chgPct,high,low,volume时间信息time,open(是否开市)技术指标technicalDay,technicalHour等基本面数据fundamentalMarketCap,fundamentalRevenue等七、最佳实践建议