├── README.md
├── doc
└── images
│ ├── qqGroup.png
│ ├── xtick.png
│ └── xticklogo.png
├── pom.xml
└── src
└── main
└── java
└── org
└── xtick
├── XTickStockApiClient.java
├── XTickWebSocketClient.java
├── bean
├── CommonPacket.java
├── Minute.java
├── MinutePacket.java
├── Tick.java
├── TickPacket.java
├── TickSubcribeInfo.java
└── finance
│ ├── XTickFinanceBalance.java
│ ├── XTickFinanceCapital.java
│ ├── XTickFinanceCashFlow.java
│ ├── XTickFinanceHoldernum.java
│ ├── XTickFinanceIncome.java
│ ├── XTickFinancePershareIndex.java
│ ├── XTickFinanceTop10flowholder.java
│ └── XTickFinanceTop10holder.java
├── constant
├── MethodType.java
└── XTickConst.java
├── http
├── HttpClientRest.java
├── Retry.java
└── Supplier.java
└── util
├── JsonUtil.java
└── XTickUtil.java
/README.md:
--------------------------------------------------------------------------------
1 | # XTick
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 | XTick提供实时行情报价数据接入解决方案。
11 |
12 |
13 | ## 项目介绍
14 |
15 | XTick行情API提供了全面、准确、稳定的行情数据,帮助开发者和研究者构建创新的交易和分析工具,满足金融行业的需求,进行深入的市场分析和模型验证。
16 |
您的支持,是我们继续维护好XTick项目的动力。
17 |
18 |
19 |
20 |
21 |
22 |
23 | ## API接口文档
24 | API接口分为订阅数据、历史数据两大块。
25 | 除了订阅接口是Websocket API,其余接口为Http API接口且均支持GET和POST方法,下面以GET请求示例。
26 |
27 | 2.1 订阅数据接口
28 | 在GitHub上,已实现Java版本和Python版本的订阅代码,请先下载代码直接调用。
29 | 订阅数据按照证券交易所订阅推送,包括上交所、深交所、北交所、港交所(只支持部分股票)。
30 | 数据为实时推送,发数据非常快,客户端接受到数据后,最好做异步处理,将接受数据和数据处理分开,避免接受数据阻塞。
31 | 1. 订阅方法:
32 | 订阅数据:订阅为Websocket API,请在Github上下载开源项目,参考XTickWebSocketClient.java中已实现的订阅功能。
33 | 入参1:authCodes 枚举取值如下:
34 | - tick.SZ - 订阅深交所A股的tick数据。
35 | - tick.SH - 订阅上交所A股的tick数据。
36 | - tick.BJ - 订阅北交所A股的tick数据。
37 | - tick.HK - 订阅港交所港股的tick数据。
38 | - time.SZ - 订阅深交所A股的k线数据,包括time、1m。
39 | - time.SH - 订阅上交所A股的k线数据,包括time、1m。
40 | - time.BJ - 订阅北交所A股的k线数据,包括time、1m。
41 | - time.HK - 订阅港交所港股的k线数据,包括time、1m。
42 | 入参2:token 登录XTick网站,注册获取
43 |
44 | 取消订阅:http://api.xtick.top/doc/unsubscribe?token=043fbdcba7f3f3ab332ffff123456789
45 | 入参:token 登录XTick网站,注册获取
46 |
47 | 2.2 行情数据接口
48 | 1. 请求方法:
49 | 请求地址:http://api.xtick.top/doc/market?type=1&code=000001&period=tick&fq=none&startDate=2025-03-25&endDate=2025-03-25&token=043fbdcba7f3f3ab332ffff123456789
50 | 备注:行情数据支持交易日内盘内实时更新。
51 | 入参1:type 股票类别
52 | 沪深京A股type=1,港股type=3,沪深ETF type=20;
53 | 入参2:code 股票代码
54 | 比如平安银行为000001
55 | 入参3:period 用于表示要获取的周期,枚举取值如下:
56 | - tick - 分笔数据
57 | - 1m - 1分钟线
58 | - 5m - 5分钟线
59 | - 15m - 15分钟线
60 | - 30m - 30分钟线
61 | - 1h - 1小时线
62 | - 1d - 日线
63 | - 1w - 周线
64 | - 1mon - 月线
65 | - 1q - 季度线
66 | - 1hy - 半年线
67 | - 1y - 年线
68 | 参数4:fq 除权方式,用于K线数据复权计算,对tick等其他周期数据无效,枚举取值如下:
69 | - none 不复权
70 | - front 前复权
71 | - back 后复权
72 | - front_ratio 等比前复权
73 | - back_ratio 等比后复权
74 | 参数5:时间范围,用于指定数据请求范围,表示的范围是[startDate , endDate]区间(包含前后边界)。
75 | 特别说明:period为tick类型,则单次请求时间跨度最大为一天,即startDate和endDate日期需设置为同一天。
76 | period为分钟类型(包括1m、5m、15m、30m、1h),则单次请求时间跨度最大为一月,即endDate - startDate不超过30天。
77 | - startDate - 起始时间,日期格式:2025-03-25
78 | - endDate- 结束时间,日期格式:2025-03-25
79 | 入参6:token 登录XTick网站,注册获取
80 |
81 | 2.3 财务数据接口
82 | 1. 请求方法:
83 | 请求地址:http://api.xtick.top/doc/financial?type=1&code=000001&report=Pershareindex&startDate=2020-03-25&endDate=2025-03-25&token=043fbdcba7f3f3ab332ffff123456789
84 | 入参1:type 股票类别
85 | 沪深京A股type=1,港股type=3;
86 | 入参2:code 股票代码
87 | 比如平安银行为000001
88 | 入参3:report 用于表示要获取的财务报表,枚举取值如下:
89 | - Balance - 资产负债表
90 | - Income - 利润表
91 | - CashFlow - 现金流量表
92 | - Capital - 股本表
93 | - Holdernum - 股东数
94 | - Top10holder - 十大股东
95 | - Top10flowholder - 十大流通股东
96 | - Pershareindex - 每股指标
97 | 参数4:时间范围,用于指定数据请求范围,表示的范围是[startDate , endDate]区间(包含前后边界)。
98 | - startDate - 起始时间,日期格式:2025-03-25
99 | - endDate- 结束时间,日期格式:2025-03-25
100 | 入参5:token 登录XTick网站,注册获取
101 |
102 | ## 项目地址
103 |
104 | 目前项目托管在 Gitee 和 Github 平台上中,欢迎大家 Star 和 Fork 支持~
105 |
106 | ### Java SDK :
107 |
108 | Gitee地址:https://github.com/xticktop/xtick
109 | Github地址:https://github.com/xticktop/xtick
110 |
111 | ## 关注&交流
112 |
113 | 为了方便小伙伴们沟通交流,创建了QQ群 (加群备注:XTick)
114 | ,目前项目还存在很多不足之处,欢迎各位大佬进群进行交流,为了防止广告进入,希望加群的时候能添加备注,谢谢~
115 | 如遇问题联系作者,邮箱:xticktop@163.com
116 | [网站说明文档](https://ccn9lag3l54q.feishu.cn/wiki/ABenwEvDOiShYrkaLAJcFY5gnZf)
117 |
118 | | QQ群【推荐】 |
119 | |------------------------------------------------------------------------------------------|
120 | |
|
121 |
122 |
123 |
124 |
125 |
126 |
127 |
--------------------------------------------------------------------------------
/doc/images/qqGroup.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xticktop/DemoXtickJava/96c14a8bf968e501cac1c75a93ad4a0311659973/doc/images/qqGroup.png
--------------------------------------------------------------------------------
/doc/images/xtick.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xticktop/DemoXtickJava/96c14a8bf968e501cac1c75a93ad4a0311659973/doc/images/xtick.png
--------------------------------------------------------------------------------
/doc/images/xticklogo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xticktop/DemoXtickJava/96c14a8bf968e501cac1c75a93ad4a0311659973/doc/images/xticklogo.png
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 |
7 | org.example
8 | DemoXtickJava
9 | 1.0-SNAPSHOT
10 |
11 |
12 | 8
13 | 8
14 | UTF-8
15 |
16 |
17 |
18 | org.projectlombok
19 | lombok
20 | 1.18.32
21 |
22 |
23 | com.google.code.gson
24 | gson
25 | 2.8.6
26 |
27 |
28 | com.google.guava
29 | guava
30 | 32.1.0-jre
31 |
32 |
33 |
34 | org.springframework.boot
35 | spring-boot-starter-websocket
36 | 3.2.12
37 |
38 |
39 | org.apache.httpcomponents
40 | httpclient
41 | 4.5.13
42 |
43 |
44 | org.apache.commons
45 | commons-lang3
46 | 3.12.0
47 |
48 |
49 | com.google.guava
50 | guava
51 | 33.3.1-jre
52 |
53 |
54 | com.squareup.okhttp3
55 | okhttp
56 | 4.12.0
57 | compile
58 |
59 |
60 | commons-io
61 | commons-io
62 | 2.11.0
63 | compile
64 |
65 |
66 |
67 |
--------------------------------------------------------------------------------
/src/main/java/org/xtick/XTickStockApiClient.java:
--------------------------------------------------------------------------------
1 | package org.xtick;
2 |
3 | import com.google.common.collect.ImmutableMap;
4 | import org.xtick.bean.Minute;
5 | import org.xtick.bean.Tick;
6 | import org.xtick.bean.finance.*;
7 | import org.xtick.constant.MethodType;
8 | import org.xtick.constant.XTickConst;
9 | import org.xtick.http.HttpClientRest;
10 | import org.xtick.util.JsonUtil;
11 |
12 | import java.io.IOException;
13 | import java.time.LocalDate;
14 | import java.util.List;
15 | import java.util.Map;
16 |
17 | /**
18 | * 行情实时数据、财务报表数据获取API接口。
19 | * 官网:http://www.xtick.top/
20 | */
21 | public class XTickStockApiClient {
22 | /**
23 | * 获取财务数据
24 | */
25 | public String getFinancialData(int type, String code, String report, String startDate, String endDate, String token, MethodType method) throws IOException {
26 | String url = "http://api.xtick.top/doc/financial";
27 | Map para = ImmutableMap.builder().put("type", type).put("zip", true).put("code", code).put("report", report).put("startDate", startDate).put("endDate", endDate).put("token", token).build();
28 | return method.equals(MethodType.GET) ? HttpClientRest.getIntance().get(url, para) : HttpClientRest.getIntance().post(url, para);
29 | }
30 |
31 | /**
32 | * 获取市场行情数据数据
33 | */
34 | public String getMarketData(int type, String code, String period, String fq, String startDate, String endDate, String token, MethodType method) throws IOException {
35 | String url = "http://api.xtick.top/doc/market";
36 | Map para = ImmutableMap.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();
37 | return method.equals(MethodType.GET) ? HttpClientRest.getIntance().get(url, para) : HttpClientRest.getIntance().post(url, para);
38 | }
39 |
40 | public void DemoForFinancialData() throws IOException {
41 | int type = 1;//沪深京A股Type=1,港股Type=3,ETF Type=20
42 | String code = "000001";
43 | String startDate = "2020-04-25";
44 | String endDate = LocalDate.now().toString();
45 | //获取财务指标数据
46 | String report = "Pershareindex";
47 | String result = getFinancialData(type, code, report, startDate, endDate, XTickConst.token, MethodType.GET);
48 | List financePershareIndexDatas = JsonUtil.jsonToList(result, XTickFinancePershareIndex.class);
49 | System.out.println(String.format("code=%s,report=%s,date=%s,financial data size=%s", code, report, startDate, financePershareIndexDatas.size()));
50 |
51 | report = "Balance";
52 | result = getFinancialData(type, code, report, startDate, endDate, XTickConst.token, MethodType.GET);
53 | List financeBalanceDatas = JsonUtil.jsonToList(result, XTickFinanceBalance.class);
54 | System.out.println(String.format("code=%s,report=%s,date=%s,financial data size=%s", code, report, startDate, financeBalanceDatas.size()));
55 |
56 | report = "CashFlow";
57 | result = getFinancialData(type, code, report, startDate, endDate, XTickConst.token, MethodType.GET);
58 | List financeCashFlowDatas = JsonUtil.jsonToList(result, XTickFinanceCashFlow.class);
59 | System.out.println(String.format("code=%s,report=%s,date=%s,financial data size=%s", code, report, startDate, financeCashFlowDatas.size()));
60 |
61 | report = "Capital";
62 | result = getFinancialData(type, code, report, startDate, endDate, XTickConst.token, MethodType.GET);
63 | List financeCapitalDatas = JsonUtil.jsonToList(result, XTickFinanceCapital.class);
64 | System.out.println(String.format("code=%s,report=%s,date=%s,financial data size=%s", code, report, startDate, financeCapitalDatas.size()));
65 |
66 | report = "Holdernum";
67 | result = getFinancialData(type, code, report, startDate, endDate, XTickConst.token, MethodType.GET);
68 | List financeHoldernumDatas = JsonUtil.jsonToList(result, XTickFinanceHoldernum.class);
69 | System.out.println(String.format("code=%s,report=%s,date=%s,financial data size=%s", code, report, startDate, financeHoldernumDatas.size()));
70 |
71 | report = "Top10holder";
72 | result = getFinancialData(type, code, report, startDate, endDate, XTickConst.token, MethodType.GET);
73 | List financeTop10holderDatas = JsonUtil.jsonToList(result, XTickFinanceTop10holder.class);
74 | System.out.println(String.format("code=%s,report=%s,date=%s,financial data size=%s", code, report, startDate, financeTop10holderDatas.size()));
75 |
76 | report = "Top10flowholder";
77 | result = getFinancialData(type, code, report, startDate, endDate, XTickConst.token, MethodType.GET);
78 | List financeTop10flowholderDatas = JsonUtil.jsonToList(result, XTickFinanceTop10flowholder.class);
79 | System.out.println(String.format("code=%s,report=%s,date=%s,financial data size=%s", code, report, startDate, financeTop10flowholderDatas.size()));
80 | }
81 |
82 | public void DemoForMarketData() throws IOException {
83 | int type = 1;//沪深京A股Type=1,港股Type=3
84 | String code = "000001";
85 | String startDate = "2025-04-25";
86 | String endDate = LocalDate.now().toString();
87 | String result = getMarketData(type, code, "tick", "", startDate, startDate, XTickConst.token, MethodType.GET);
88 | List ticks = JsonUtil.jsonToList(result, Tick.class);//获取tick数据
89 | System.out.println(String.format("code=%s,period=tick,date=%s,history data size=%s", code, startDate, ticks.size()));
90 | for (String period : XTickConst.historyKlinePeriods) {//获取K线数据
91 | for (String fq : XTickConst.dividends) {
92 | result = getMarketData(type, code, period, fq, startDate, endDate, XTickConst.token, MethodType.GET);
93 | List klines = JsonUtil.jsonToList(result, Minute.class);
94 | 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()));
95 | }
96 | }
97 | }
98 |
99 | public static void main(String[] args) throws IOException {
100 | XTickStockApiClient client = new XTickStockApiClient();
101 | String result = client.getMarketData(1, "000001", "1m", "none", LocalDate.now().minusMonths(1).toString(), LocalDate.now().toString(), XTickConst.token, MethodType.GET);
102 | List datas = JsonUtil.jsonToList(result, Minute.class);//获取1分钟数据
103 | System.out.println(datas);
104 | //client.DemoForFinancialData();//获取财务数据代码示例
105 | //client.DemoForMarketData();//获取历史数据代码示例
106 | }
107 | }
108 |
--------------------------------------------------------------------------------
/src/main/java/org/xtick/XTickWebSocketClient.java:
--------------------------------------------------------------------------------
1 | package org.xtick;
2 |
3 |
4 | import com.google.common.collect.ImmutableList;
5 | import com.google.common.util.concurrent.ThreadFactoryBuilder;
6 | import jakarta.websocket.*;
7 | import org.apache.catalina.util.StringUtil;
8 | import org.apache.commons.lang3.StringUtils;
9 | import org.xtick.bean.MinutePacket;
10 | import org.xtick.bean.TickPacket;
11 | import org.xtick.bean.TickSubcribeInfo;
12 | import org.xtick.constant.XTickConst;
13 | import org.xtick.util.JsonUtil;
14 | import org.xtick.util.XTickUtil;
15 |
16 | import java.io.ByteArrayInputStream;
17 | import java.io.UnsupportedEncodingException;
18 | import java.net.URI;
19 | import java.net.URLEncoder;
20 | import java.nio.charset.StandardCharsets;
21 | import java.time.LocalDateTime;
22 | import java.time.format.DateTimeFormatter;
23 | import java.util.List;
24 | import java.util.Objects;
25 | import java.util.concurrent.LinkedBlockingDeque;
26 | import java.util.concurrent.LinkedBlockingQueue;
27 | import java.util.concurrent.ThreadPoolExecutor;
28 | import java.util.concurrent.TimeUnit;
29 | import java.util.function.Consumer;
30 |
31 | /**
32 | * WebSocket客户端,用于连接XTick的WebSocket服务。
33 | * 官网:http://www.xtick.top/
34 | */
35 | @ClientEndpoint
36 | public class XTickWebSocketClient {
37 | private URI endpointURI;
38 | private static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS");
39 | private LinkedBlockingQueue