股票实时数据接口实现
除了订阅接口是Websocket API,其余接口为Http API接口且均支持GET和POST方法,下面以GET请求示例。包括股票实时盘口数据、实时K线数据、实时一分钟数据、实时分时数据等。API接口分为订阅数据、实时行情数据、财务数据三个部分。
·
API接口分为订阅数据、实时行情数据、财务数据三个部分。
包括股票实时盘口数据、实时K线数据、实时一分钟数据、实时分时数据等。
除了订阅接口是Websocket API,其余接口为Http API接口且均支持GET和POST方法,下面以GET请求示例。
package org.xtick;
import com.google.common.collect.ImmutableList;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import jakarta.websocket.*;
import org.apache.catalina.util.StringUtil;
import org.apache.commons.lang3.StringUtils;
import org.xtick.bean.MinutePacket;
import org.xtick.bean.TickPacket;
import org.xtick.bean.TickSubcribeInfo;
import org.xtick.constant.XTickConst;
import org.xtick.util.JsonUtil;
import org.xtick.util.XTickUtil;
import java.io.ByteArrayInputStream;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
/**
* WebSocket客户端,用于连接XTick的WebSocket服务。
* 官网:http://www.xtick.top/
*/
@ClientEndpoint
public class XTickWebSocketClient {
private URI endpointURI;
private static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS");
private LinkedBlockingQueue<Object> queue = new LinkedBlockingQueue<>(100000);
private ThreadPoolExecutor taskThreadPool = new ThreadPoolExecutor(3, 3, 60, TimeUnit.SECONDS, new LinkedBlockingDeque<>(1000), new ThreadFactoryBuilder().setNameFormat("xtick-task-%d").build());
private Consumer<String> dataConsumer = result -> {
Object packet;
if (StringUtils.isNotBlank(result)) {
if (result.contains("1m")) {
packet = JsonUtil.jsonToObj(result, MinutePacket.class);
} else {
packet = JsonUtil.jsonToObj(result, TickPacket.class);
}
if (Objects.nonNull(packet)) {//数据包加入队列中,后续业务模块调用处理
queue.offer(packet);
}
}
};
private XTickWebSocketClient(URI endpointURI) {
try {
this.endpointURI = endpointURI;
connectToServer(endpointURI, null);
} catch (Exception e) {
System.err.println("Failed to connect to WebSocket server" + e.getMessage());
}
}
private void connectToServer(URI endpointURI, CloseReason reason) {
if (Objects.isNull(reason) || !reason.getCloseCode().equals(CloseReason.CloseCodes.NORMAL_CLOSURE)) {
try {
WebSocketContainer container = ContainerProvider.getWebSocketContainer();
container.setDefaultMaxBinaryMessageBufferSize(1 * 1024 * 1024);
container.setDefaultMaxTextMessageBufferSize(1 * 1024 * 1024);
container.setDefaultMaxSessionIdleTimeout(1 * 60 * 60 * 1000L);
container.connectToServer(this, endpointURI);
XTickUtil.sleepSeconds(1);
} catch (Exception e) {
System.err.println("Failed to connect to WebSocket server" + e.getMessage());
XTickUtil.sleepSeconds(10);
connectToServer(endpointURI, reason);
}
}
}
@OnOpen
public void onOpen(Session session) {
System.out.println("Connected to WebSocket server");
}
@OnClose
public void onClose(Session session, CloseReason reason) {
System.out.println("Disconnected from WebSocket server. Reason: " + reason.toString());
connectToServer(endpointURI, reason);
}
@OnMessage
public void onMessage(String data) {
System.out.println("Received message: " + data);
}
@OnMessage
public void onMessage(byte[] data) {
XTickUtil.processData(new ByteArrayInputStream(data), dataConsumer);
}
@OnError
public void onError(Session session, Throwable throwable) {
System.err.println("WebSocket连接发生错误.error=" + throwable.getMessage());
}
public void exec() {
taskThreadPool.execute(() -> {
while (true) {
try {
Object data = queue.take();
if (data instanceof TickPacket) { //处理业务逻辑....
TickPacket packet = (TickPacket) data;
System.out.println(String.format("%s,received tick data.[authCode=%s,period=%s,size=%s]", LocalDateTime.now().format(formatter), packet.getAuthCode(), packet.getPeriod(), packet.getData().size()));
} else {
MinutePacket packet = (MinutePacket) data;
System.out.println(String.format("%s,received minute data.[authCode=%s,period=%s,size=%s]", LocalDateTime.now().format(formatter), packet.getAuthCode(), packet.getPeriod(), packet.getData().size()));
}
} catch (Exception e) {
System.err.println("Failed to process data." + e.getMessage());
}
}
});
}
public static void main(String[] args) throws UnsupportedEncodingException {
//List<String> authCodes = ImmutableList.of("time.SZ", "time.SH", "time.BJ", "time.HK", "tick.SZ", "tick.SH", "tick.BJ", "tick.HK");
List<String> authCodes = ImmutableList.of("tick.BJ");//新用户,可以订阅北交所的tick行情数据
String user = URLEncoder.encode(JsonUtil.toJson(TickSubcribeInfo.builder().token(XTickConst.token).authCodes(authCodes).build()), StandardCharsets.UTF_8.toString());
XTickWebSocketClient wsClient = new XTickWebSocketClient(URI.create(String.format("ws://ws.xtick.top/ws/%s", user)));
wsClient.exec();
}
}
实时行情数据:
package org.xtick;
import com.google.common.collect.ImmutableMap;
import org.xtick.bean.Minute;
import org.xtick.bean.Tick;
import org.xtick.bean.finance.*;
import org.xtick.constant.MethodType;
import org.xtick.constant.XTickConst;
import org.xtick.http.HttpClientRest;
import org.xtick.util.JsonUtil;
import java.io.IOException;
import java.time.LocalDate;
import java.util.List;
import java.util.Map;
/**
* 行情实时数据、财务报表数据获取API接口。
* 官网:http://www.xtick.top/
*/
public class XTickStockApiClient {
/**
* 获取财务数据
*/
public String getFinancialData(int type, String code, String report, String startDate, String endDate, String token, MethodType method) throws IOException {
String url = "http://api.xtick.top/doc/financial";
Map<String, Object> para = ImmutableMap.<String, Object>builder().put("type", type).put("zip", true).put("code", code).put("report", report).put("startDate", startDate).put("endDate", endDate).put("token", token).build();
return method.equals(MethodType.GET) ? HttpClientRest.getIntance().get(url, para) : HttpClientRest.getIntance().post(url, para);
}
/**
* 获取市场行情数据数据
*/
public String getMarketData(int type, String code, String period, String fq, String startDate, String endDate, String token, MethodType method) throws IOException {
String url = "http://api.xtick.top/doc/market";
Map<String, Object> para = ImmutableMap.<String, Object>builder().put("type", type).put("zip", true).put("code", code).put("period", period).put("fq", fq).put("startDate", startDate).put("endDate", endDate).put("token", token).build();
return method.equals(MethodType.GET) ? HttpClientRest.getIntance().get(url, para) : HttpClientRest.getIntance().post(url, para);
}
public void DemoFinancialData() throws IOException {
int type = 1;//沪深京A股Type=1,港股Type=3
String code = "000001";
String startDate = "2020-04-25";
String endDate = LocalDate.now().toString();
//获取财务指标数据
String report = "Pershareindex";
String result = getFinancialData(type, code, report, startDate, endDate, XTickConst.token, MethodType.GET);
List<XTickFinancePershareIndex> financePershareIndexDatas = JsonUtil.jsonToList(result, XTickFinancePershareIndex.class);
System.out.println(String.format("code=%s,report=%s,date=%s,financial data size=%s", code, report, startDate, financePershareIndexDatas.size()));
report = "Balance";
result = getFinancialData(type, code, report, startDate, endDate, XTickConst.token, MethodType.GET);
List<XTickFinanceBalance> financeBalanceDatas = JsonUtil.jsonToList(result, XTickFinanceBalance.class);
System.out.println(String.format("code=%s,report=%s,date=%s,financial data size=%s", code, report, startDate, financeBalanceDatas.size()));
report = "CashFlow";
result = getFinancialData(type, code, report, startDate, endDate, XTickConst.token, MethodType.GET);
List<XTickFinanceCashFlow> financeCashFlowDatas = JsonUtil.jsonToList(result, XTickFinanceCashFlow.class);
System.out.println(String.format("code=%s,report=%s,date=%s,financial data size=%s", code, report, startDate, financeCashFlowDatas.size()));
report = "Capital";
result = getFinancialData(type, code, report, startDate, endDate, XTickConst.token, MethodType.GET);
List<XTickFinanceCapital> financeCapitalDatas = JsonUtil.jsonToList(result, XTickFinanceCapital.class);
System.out.println(String.format("code=%s,report=%s,date=%s,financial data size=%s", code, report, startDate, financeCapitalDatas.size()));
report = "Holdernum";
result = getFinancialData(type, code, report, startDate, endDate, XTickConst.token, MethodType.GET);
List<XTickFinanceHoldernum> financeHoldernumDatas = JsonUtil.jsonToList(result, XTickFinanceHoldernum.class);
System.out.println(String.format("code=%s,report=%s,date=%s,financial data size=%s", code, report, startDate, financeHoldernumDatas.size()));
report = "Top10holder";
result = getFinancialData(type, code, report, startDate, endDate, XTickConst.token, MethodType.GET);
List<XTickFinanceTop10holder> financeTop10holderDatas = JsonUtil.jsonToList(result, XTickFinanceTop10holder.class);
System.out.println(String.format("code=%s,report=%s,date=%s,financial data size=%s", code, report, startDate, financeTop10holderDatas.size()));
report = "Top10flowholder";
result = getFinancialData(type, code, report, startDate, endDate, XTickConst.token, MethodType.GET);
List<XTickFinanceTop10flowholder> financeTop10flowholderDatas = JsonUtil.jsonToList(result, XTickFinanceTop10flowholder.class);
System.out.println(String.format("code=%s,report=%s,date=%s,financial data size=%s", code, report, startDate, financeTop10flowholderDatas.size()));
}
public void DemoForMarketData() throws IOException {
int type = 1;//沪深京A股Type=1,港股Type=3
String code = "000001";
String startDate = "2025-04-25";
String endDate = LocalDate.now().toString();
String result = getMarketData(type, code, "tick", "", startDate, startDate, XTickConst.token, MethodType.GET);
List<Tick> ticks = JsonUtil.jsonToList(result, Tick.class);//获取tick数据
System.out.println(String.format("code=%s,period=tick,date=%s,history data size=%s", code, startDate, ticks.size()));
for (String period : XTickConst.historyKlinePeriods) {//获取K线数据
for (String fq : XTickConst.dividends) {
result = getMarketData(type, code, period, fq, startDate, endDate, XTickConst.token, MethodType.GET);
List<Minute> klines = JsonUtil.jsonToList(result, Minute.class);
System.out.println(String.format("code=%s,period=%s,fq=%s,startDate=%s,endDate=%s,history data size=%s", code, period, fq, startDate, endDate, klines.size()));
}
}
}
public static void main(String[] args) throws IOException {
XTickStockApiClient client = new XTickStockApiClient();
client.DemoFinancialData();//获取财务数据代码示例
//client.DemoForMarketData();//获取历史数据代码示例
}
}
火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。
更多推荐
所有评论(0)