lib/taobao-sdk-java.jarBinary files differ
pom.xml
@@ -29,6 +29,8 @@ <fastjson.version>1.2.61</fastjson.version> <netty.version>4.1.33.Final</netty.version> <dom4j.version>1.6.1</dom4j.version> <okhttp.version>3.6.0</okhttp.version> <aliyun-oss.version>3.8.0</aliyun-oss.version> </properties> <dependencies> @@ -165,6 +167,10 @@ <artifactId>fastjson</artifactId> <version>${fastjson.version}</version> </dependency> <dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> </dependency> <dependency> <groupId>org.apache.httpcomponents</groupId> @@ -182,6 +188,60 @@ <artifactId>netty-all</artifactId> <version>${netty.version}</version> </dependency> <dependency> <groupId>com.squareup.okhttp3</groupId> <artifactId>okhttp</artifactId> <version>${okhttp.version}</version> </dependency> <dependency> <groupId>com.aliyun.oss</groupId> <artifactId>aliyun-sdk-oss</artifactId> <version>${aliyun-oss.version}</version> </dependency> <dependency> <groupId>com.huobi.sdk</groupId> <artifactId>huobi-client</artifactId> <version>1.0.8-SNAPSHOT</version> <scope>system</scope> <systemPath>${basedir}/lib/huobi-client-1.0.8-SNAPSHOT.jar</systemPath> </dependency> <!-- submail邮件 start --> <dependency> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> <version>1.1.1</version> </dependency> <dependency> <groupId>commons-collections</groupId> <artifactId>commons-collections</artifactId> <version>3.2.1</version> </dependency> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> <version>3.3.2</version> </dependency> <dependency> <groupId>net.sf.ezmorph</groupId> <artifactId>ezmorph</artifactId> <version>1.0.3</version> </dependency> <dependency> <groupId>net.sf.json-lib</groupId> <artifactId>json-lib</artifactId> <version>2.2.3</version> <classifier>jdk15</classifier> </dependency> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpmime</artifactId> <version>4.3.5</version> </dependency> <!-- submail邮件 end --> </dependencies> <build> src/main/java/com/xcong/excoin/modules/symbols/Entity/PlatformSymbolsContractEntity.java
New file @@ -0,0 +1,21 @@ package com.xcong.excoin.modules.symbols.Entity; import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data; import java.io.Serializable; /** * @author wzy * @date 2020-05-26 **/ @Data @TableName("platform_symbols_contract") public class PlatformSymbolsContractEntity implements Serializable { private static final long serialVersionUID = -1L; private Long id; private String name; } src/main/java/com/xcong/excoin/modules/symbols/dao/PlatformSymbolsContractDao.java
New file @@ -0,0 +1,11 @@ package com.xcong.excoin.modules.symbols.dao; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.xcong.excoin.modules.symbols.Entity.PlatformSymbolsContractEntity; /** * * @author wzy */ public interface PlatformSymbolsContractDao extends BaseMapper<PlatformSymbolsContractEntity> { } src/main/java/com/xcong/excoin/modules/symbols/service/SymbolsService.java
New file @@ -0,0 +1,12 @@ package com.xcong.excoin.modules.symbols.service; /** * @author wzy * @date 2020-05-26 **/ public interface SymbolsService { public void updateSymbolsKine(String time); } src/main/java/com/xcong/excoin/modules/symbols/service/impl/SymbolsServiceImpl.java
New file @@ -0,0 +1,84 @@ package com.xcong.excoin.modules.symbols.service.impl; import com.alibaba.fastjson.JSONObject; import com.huobi.client.model.Candlestick; import com.xcong.excoin.common.enumerates.SymbolEnum; import com.xcong.excoin.modules.symbols.service.SymbolsService; import com.xcong.excoin.utils.RedisUtils; import com.xcong.excoin.utils.api.ApiClient; import com.xcong.excoin.utils.api.response.Kline; import com.xcong.excoin.utils.api.response.KlineResponse; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import javax.annotation.Resource; import java.math.BigDecimal; import java.util.ArrayList; import java.util.List; /** * @author wzy * @date 2020-05-26 **/ @Slf4j @Service public class SymbolsServiceImpl implements SymbolsService { @Resource private RedisUtils redisUtils; private static final String API_KEY = "3938f004-bfe31905-f7581c1a-6abe0"; private static final String API_SECRET = "a0f7a154-ghxertfvbf-6ce2d90c-a0bab"; private static volatile ApiClient client; private static ApiClient getClient() { if (client == null) { synchronized (ApiClient.class) { if (client == null) { client = new ApiClient(API_KEY, API_SECRET); } } } return client; } @Override public void updateSymbolsKine(String time) { synchronized (this) { //更新币币交易K线历史数据 for (SymbolEnum symbol : SymbolEnum.values()) { log.info(symbol.getValue()); String[] symbols = symbol.getValue().toLowerCase().split("/"); ApiClient client = new ApiClient(API_KEY, API_SECRET); KlineResponse kline = client.kline(symbols[0] + symbols[1], time, 1000 + ""); log.info("{}", JSONObject.toJSONString(kline)); if (kline != null) { if ("ok".equalsIgnoreCase(kline.getStatus())) { List<Kline> klines = (List<Kline>) kline.data; List<Candlestick> list = new ArrayList<Candlestick>(); Candlestick candlestick = null; for (Kline kline1 : klines) { candlestick = new Candlestick(); candlestick.setAmount(BigDecimal.valueOf(kline1.getAmount())); candlestick.setClose(BigDecimal.valueOf(kline1.getClose())); candlestick.setCount(kline1.getCount()); candlestick.setHigh(BigDecimal.valueOf(kline1.getHigh())); candlestick.setLow(BigDecimal.valueOf(kline1.getLow())); candlestick.setVolume(BigDecimal.valueOf(kline1.getVol())); candlestick.setTimestamp(kline1.getId() * 1000); candlestick.setOpen(BigDecimal.valueOf(kline1.getOpen())); list.add(candlestick); } if (klines.size() > 0) { // redisUtils.set("KINE_" + symbol.getValue() + "_" + time, list); } } } } } } } src/main/java/com/xcong/excoin/quartz/job/KlineDataUpdateJob.java
New file @@ -0,0 +1,151 @@ package com.xcong.excoin.quartz.job; import com.xcong.excoin.modules.symbols.service.SymbolsService; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import javax.annotation.Resource; /** * k线数据更新任务 * * @author wzy * @date 2020-05-26 **/ @Component public class KlineDataUpdateJob { @Resource private SymbolsService symbolsService; private static boolean min1 = true; private static boolean min5 = true; private static boolean min30 = true; private static boolean min60 = true; private static boolean hour4 = true; private static boolean day1 = true; private static boolean week = true; /** * 定时更新每一分钟的K线数据 */ @Scheduled(cron = "0/1 * * * * ? ") public void updateSymbolsKineOneMin() { if (min1) { min1 = false; try { symbolsService.updateSymbolsKine("1min"); } catch (Exception e) { // e.printStackTrace(); } finally { min1 = true; } } } /** * 定时更新每十分钟的K线数据 */ @Scheduled(cron = "0/10 * * * * ? ") public void updateSymbolsKineFiveMin() { if (min5) { min5 = false; try { symbolsService.updateSymbolsKine("5min"); } catch (Exception e) { //e.printStackTrace(); } finally { min5 = true; } } } /** * 定时更新每30分钟的K线数据 */ @Scheduled(cron = "0/120 * * * * ? ") public void updateSymbolsKineMin() { if (min30) { min30 = false; try { symbolsService.updateSymbolsKine("30min"); } catch (Exception e) { //e.printStackTrace(); } finally { min30 = true; } } } /** * 定时更新1小时的K线数据 */ @Scheduled(cron = "* 0/2 * * * ? ") public void updateSymbolsKineOneHour() { if (min60) { min60 = false; try { symbolsService.updateSymbolsKine("60min"); } catch (Exception e) { //e.printStackTrace(); } finally { min60 = true; } } } /** * 定时更新4小时的K线数据 */ @Scheduled(cron = "* 0/1 * * * ? ") public void updateSymbolsKineFourHour() { if (hour4) { hour4 = false; try { symbolsService.updateSymbolsKine("4hour"); } catch (Exception e) { //e.printStackTrace(); } finally { hour4 = true; } } } /** * 定时更新1天的K线数据 */ @Scheduled(cron = "* 0/1 * * * ? ") public void updateSymbolsKineOneDay() { if (day1) { day1 = false; try { symbolsService.updateSymbolsKine("1day"); } catch (Exception e) { //e.printStackTrace(); } finally { day1 = true; } } } /** * 定时更新1周的K线数据 */ @Scheduled(cron = "* 0/1 * * * ? ") public void updateSymbolsKineOneWeek() { if (week) { week = false; try { symbolsService.updateSymbolsKine("1week"); } catch (Exception e) { // e.printStackTrace(); } finally { week = true; } } } } src/main/java/com/xcong/excoin/utils/api/ApiClient.java
New file @@ -0,0 +1,607 @@ package com.xcong.excoin.utils.api; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.PropertyNamingStrategy; import com.fasterxml.jackson.databind.SerializationFeature; import com.xcong.excoin.utils.api.request.CreateOrderRequest; import com.xcong.excoin.utils.api.request.IntrustOrdersDetailRequest; import com.xcong.excoin.utils.api.response.*; import okhttp3.*; import okhttp3.OkHttpClient.Builder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; import javax.xml.bind.DatatypeConverter; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.net.MalformedURLException; import java.net.URL; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; import java.security.InvalidKeyException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.time.Instant; import java.time.ZoneId; import java.time.format.DateTimeFormatter; import java.util.*; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; /** * API client. * * @Date 2018/1/14 * @Time 16:02 */ public class ApiClient { static final int CONN_TIMEOUT = 50; static final int READ_TIMEOUT = 50; static final int WRITE_TIMEOUT = 50; // static final String API_URL = "https://api.huobi.pro:443"; // static final String API_URL = "https://api.huobi.pro"; // static final String API_URL = "https://api.hbdm.com"; // static final String API_URL = "https://api.huobi.br.com"; // static final String API_URL = "https://api.btcgateway.pro"; static final String API_URL = "https://api.hadax.com"; static final String API_HOST = getHost(); static final MediaType JSON = MediaType.parse("application/json"); static final OkHttpClient client = createOkHttpClient(); final String accessKeyId; final String accessKeySecret; final String assetPassword; /** * 创建一个ApiClient实例 * * @param accessKeyId AccessKeyId * @param accessKeySecret AccessKeySecret */ public ApiClient(String accessKeyId, String accessKeySecret) { this.accessKeyId = accessKeyId; this.accessKeySecret = accessKeySecret; this.assetPassword = null; } /** * 创建一个ApiClient实例 * * @param accessKeyId AccessKeyId * @param accessKeySecret AccessKeySecret * @param assetPassword AssetPassword */ public ApiClient(String accessKeyId, String accessKeySecret, String assetPassword) { this.accessKeyId = accessKeyId; this.accessKeySecret = accessKeySecret; this.assetPassword = assetPassword; } /** * 查询交易对 * * @return List of symbols. */ public List<Symbol> getSymbols() { ApiResponse<List<Symbol>> resp = get("/v1/common/symbols", null, new TypeReference<ApiResponse<List<Symbol>>>() { }); return resp.checkAndReturn(); } /** * 查询所有账户信息 * * @return List of accounts. */ public List<Account> getAccounts() { ApiResponse<List<Account>> resp = get("/v1/account/accounts", null, new TypeReference<ApiResponse<List<Account>>>() { }); return resp.checkAndReturn(); } /** * 创建订单 * * @param request CreateOrderRequest object. * @return Order id. */ public Long createOrder(CreateOrderRequest request) { ApiResponse<Long> resp = post("/v1/order/orders/place", request, new TypeReference<ApiResponse<Long>>() { }); return resp.checkAndReturn(); } /** * 执行订单 * * @param orderId The id of created order. * @return Order id. */ public String placeOrder(long orderId) { ApiResponse<String> resp = post("/v1/order/orders/" + orderId + "/place", null, new TypeReference<ApiResponse<String>>() { }); return resp.checkAndReturn(); } // ----------------------------------------行情API------------------------------------------- /** * GET /market/history/kline 获取K线数据 * * @param symbol * @param period * @param size * @return */ @SuppressWarnings({"unchecked", "rawtypes"}) public KlineResponse kline(String symbol, String period, String size) { HashMap map = new HashMap(); map.put("symbol", symbol); map.put("period", period); map.put("size", size); KlineResponse resp = get("/market/history/kline", map, new TypeReference<KlineResponse<List<Kline>>>() { }); return resp; } /** * GET /market/detail/merged 获取聚合行情(Ticker) * * @param symbol * @return */ @SuppressWarnings({"rawtypes", "unchecked"}) public MergedResponse merged(String symbol) { HashMap map = new HashMap(); map.put("symbol", symbol); MergedResponse resp = get("/market/detail/merged", map, new TypeReference<MergedResponse<List<Merged>>>() { }); return resp; } /** * GET /market/depth 获取 Market Depth 数据 * * @return */ @SuppressWarnings({"rawtypes", "unchecked"}) public DepthResponse depth(String symbol, String type, String depth) { HashMap map = new HashMap(); map.put("symbol", symbol); map.put("type", type); map.put("depth", depth); DepthResponse resp = get("/market/depth", map, new TypeReference<DepthResponse<List<Depth>>>() { }); return resp; } /** * GET /market/trade 获取 Trade Detail 数据 * * @param symbol * @return */ @SuppressWarnings({"rawtypes", "unchecked"}) public TradeResponse trade(String symbol) { HashMap map = new HashMap(); map.put("symbol", symbol); TradeResponse resp = get("/market/trade", map, new TypeReference<TradeResponse>() { }); return resp; } /** * GET /market/history/trade 批量获取最近的交易记录 * * @param symbol * @param size * @return */ @SuppressWarnings({"rawtypes", "unchecked"}) public HistoryTradeResponse historyTrade(String symbol, String size) { // System.out.println("symbol = "+symbol+" size = "+size); HashMap map = new HashMap(); map.put("symbol", symbol); map.put("size", size); HistoryTradeResponse resp = get("/market/history/trade", map, new TypeReference<HistoryTradeResponse>() { }); return resp; } /** * GET /market/detail 获取 Market Detail 24小时成交量数据 * * @param symbol * @return */ @SuppressWarnings({"unchecked", "rawtypes"}) public DetailResponse detail(String symbol) { HashMap map = new HashMap(); map.put("symbol", symbol); DetailResponse resp = get("/market/detail", map, new TypeReference<DetailResponse<Details>>() { }); return resp; } /** * GET /v1/common/symbols 查询系统支持的所有交易对及精度 * * @param symbol * @return */ @SuppressWarnings({"rawtypes", "unchecked"}) public SymbolsResponse symbols(String symbol) { HashMap map = new HashMap(); map.put("symbol", symbol); SymbolsResponse resp = get("/v1/common/symbols", map, new TypeReference<SymbolsResponse<Symbols>>() { }); return resp; } /** * GET /v1/common/currencys 查询系统支持的所有币种 * * @param symbol * @return */ @SuppressWarnings({"rawtypes", "unchecked"}) public CurrencysResponse currencys(String symbol) { HashMap map = new HashMap(); map.put("symbol", symbol); CurrencysResponse resp = get("/v1/common/currencys", map, new TypeReference<CurrencysResponse>() { }); return resp; } /** * GET /v1/common/timestamp 查询系统当前时间 * * @return */ public TimestampResponse timestamp() { TimestampResponse resp = get("/v1/common/timestamp", null, new TypeReference<TimestampResponse>() { }); return resp; } /** * GET /v1/account/accounts 查询当前用户的所有账户(即account-id) * * @return */ @SuppressWarnings({"rawtypes"}) public AccountsResponse accounts() { AccountsResponse resp = get("/v1/account/accounts", null, new TypeReference<AccountsResponse<List<Accounts>>>() { }); return resp; } /** * GET /v1/account/accounts/{account-id}/balance 查询指定账户的余额 * * @param accountId * @return */ @SuppressWarnings({"rawtypes"}) public BalanceResponse balance(String accountId) { BalanceResponse resp = get("/v1/account/accounts/" + accountId + "/balance", null, new TypeReference<BalanceResponse<Balance>>() { }); return resp; } /** * POST /v1/order/orders/{order-id}/submitcancel 申请撤销一个订单请求 * * @param orderId * @return */ public SubmitcancelResponse submitcancel(String orderId) { SubmitcancelResponse resp = post("/v1/order/orders/" + orderId + "/submitcancel", null, new TypeReference<SubmitcancelResponse>() { }); return resp; } /** * POST /v1/order/orders/batchcancel 批量撤销订单 * * @param orderList * @return */ @SuppressWarnings({"rawtypes", "unchecked"}) public BatchcancelResponse submitcancels(List orderList) { Map<String, List> parameterMap = new HashMap(); parameterMap.put("order-ids", orderList); BatchcancelResponse resp = post("/v1/order/orders/batchcancel", parameterMap, new TypeReference<BatchcancelResponse<Batchcancel<List, List<BatchcancelBean>>>>() { }); return resp; } /** * GET /v1/order/orders/{order-id} 查询某个订单详情 * * @param orderId * @return */ @SuppressWarnings({"rawtypes"}) public OrdersDetailResponse ordersDetail(String orderId) { OrdersDetailResponse resp = get("/v1/order/orders/" + orderId, null, new TypeReference<OrdersDetailResponse>() { }); return resp; } /** * GET /v1/order/orders/{order-id}/matchresults 查询某个订单的成交明细 * * @param orderId * @return */ @SuppressWarnings({"rawtypes"}) public MatchresultsOrdersDetailResponse matchresults(String orderId) { MatchresultsOrdersDetailResponse resp = get("/v1/order/orders/" + orderId + "/matchresults", null, new TypeReference<MatchresultsOrdersDetailResponse>() { }); return resp; } @SuppressWarnings({"rawtypes", "unchecked"}) public IntrustDetailResponse intrustOrdersDetail(IntrustOrdersDetailRequest req) { HashMap map = new HashMap(); map.put("symbol", req.symbol); map.put("states", req.states); if (req.startDate != null) { map.put("startDate", req.startDate); } if (req.startDate != null) { map.put("start-date", req.startDate); } if (req.endDate != null) { map.put("end-date", req.endDate); } if (req.types != null) { map.put("types", req.types); } if (req.from != null) { map.put("from", req.from); } if (req.direct != null) { map.put("direct", req.direct); } if (req.size != null) { map.put("size", req.size); } IntrustDetailResponse resp = get("/v1/order/orders/", map, new TypeReference<IntrustDetailResponse<List<IntrustDetail>>>() { }); return resp; } // public IntrustDetailResponse getALlOrdersDetail(String orderId) { // IntrustDetailResponse resp = get("/v1/order/orders/"+orderId, null,new TypeReference<IntrustDetailResponse>() {}); // return resp; // } // send a GET request. <T> T get(String uri, Map<String, String> params, TypeReference<T> ref) { if (params == null) { params = new HashMap<>(); } return call("GET", uri, null, params, ref); } // send a POST request. <T> T post(String uri, Object object, TypeReference<T> ref) { return call("POST", uri, object, new HashMap<String, String>(), ref); } // call api by endpoint. <T> T call(String method, String uri, Object object, Map<String, String> params, TypeReference<T> ref) { ApiSignature sign = new ApiSignature(); sign.createSignature(this.accessKeyId, this.accessKeySecret, method, API_HOST, uri, params); try { Request.Builder builder = null; if ("POST".equals(method)) { RequestBody body = RequestBody.create(JSON, JsonUtil.writeValue(object)); builder = new Request.Builder().url(API_URL + uri + "?" + toQueryString(params)).post(body); } else { builder = new Request.Builder().url(API_URL + uri + "?" + toQueryString(params)).get(); } if (this.assetPassword != null) { builder.addHeader("AuthData", authData()); } Request request = builder.build(); Response response = client.newCall(request).execute(); String s = response.body().string(); //System.out.println("-----s:"+JsonUtil.writeValue(s)); return JsonUtil.readValue(s, ref); } catch (IOException e) { // throw new ApiException(e); e.printStackTrace(); return null; } } String authData() { MessageDigest md = null; try { md = MessageDigest.getInstance("MD5"); } catch (NoSuchAlgorithmException e) { throw new RuntimeException(e); } md.update(this.assetPassword.getBytes(StandardCharsets.UTF_8)); md.update("hello, moto".getBytes(StandardCharsets.UTF_8)); Map<String, String> map = new HashMap<>(); map.put("assetPwd", DatatypeConverter.printHexBinary(md.digest()).toLowerCase()); try { return ApiSignature.urlEncode(JsonUtil.writeValue(map)); } catch (IOException e) { throw new RuntimeException("Get json failed: " + e.getMessage()); } } // Encode as "a=1&b=%20&c=&d=AAA" String toQueryString(Map<String, String> params) { return String.join("&", params.entrySet().stream().map((entry) -> { return entry.getKey() + "=" + ApiSignature.urlEncode(entry.getValue()); }).collect(Collectors.toList())); } // create OkHttpClient: static OkHttpClient createOkHttpClient() { return new Builder().connectTimeout(CONN_TIMEOUT, TimeUnit.SECONDS) .readTimeout(READ_TIMEOUT, TimeUnit.SECONDS).writeTimeout(WRITE_TIMEOUT, TimeUnit.SECONDS) .build(); } static String getHost() { String host = null; try { host = new URL(API_URL).getHost(); } catch (MalformedURLException e) { System.err.println("parse API_URL error,system exit!,please check API_URL:" + API_URL); System.exit(0); } return host; } } /** * API签名,签名规范: * <p> * http://docs.aws.amazon.com/zh_cn/general/latest/gr/signature-version-2.html * * @Date 2018/1/14 * @Time 16:02 */ class ApiSignature { final Logger log = LoggerFactory.getLogger(getClass()); static final DateTimeFormatter DT_FORMAT = DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ss"); static final ZoneId ZONE_GMT = ZoneId.of("Z"); /** * 创建一个有效的签名。该方法为客户端调用,将在传入的params中添加AccessKeyId、Timestamp、SignatureVersion、SignatureMethod、Signature参数。 * * @param appKey AppKeyId. * @param appSecretKey AppKeySecret. * @param method 请求方法,"GET"或"POST" * @param host 请求域名,例如"be.huobi.com" * @param uri 请求路径,注意不含?以及后的参数,例如"/v1/api/info" * @param params 原始请求参数,以Key-Value存储,注意Value不要编码 */ public void createSignature(String appKey, String appSecretKey, String method, String host, String uri, Map<String, String> params) { StringBuilder sb = new StringBuilder(1024); sb.append(method.toUpperCase()).append('\n') // GET .append(host.toLowerCase()).append('\n') // Host .append(uri).append('\n'); // /path params.remove("Signature"); params.put("AccessKeyId", appKey); params.put("SignatureVersion", "2"); params.put("SignatureMethod", "HmacSHA256"); params.put("Timestamp", gmtNow()); // build signature: SortedMap<String, String> map = new TreeMap<>(params); for (Map.Entry<String, String> entry : map.entrySet()) { String key = entry.getKey(); String value = entry.getValue(); sb.append(key).append('=').append(urlEncode(value)).append('&'); } // remove last '&': sb.deleteCharAt(sb.length() - 1); // sign: Mac hmacSha256 = null; try { hmacSha256 = Mac.getInstance("HmacSHA256"); SecretKeySpec secKey = new SecretKeySpec(appSecretKey.getBytes(StandardCharsets.UTF_8), "HmacSHA256"); hmacSha256.init(secKey); } catch (NoSuchAlgorithmException e) { throw new RuntimeException("No such algorithm: " + e.getMessage()); } catch (InvalidKeyException e) { throw new RuntimeException("Invalid key: " + e.getMessage()); } String payload = sb.toString(); byte[] hash = hmacSha256.doFinal(payload.getBytes(StandardCharsets.UTF_8)); String actualSign = Base64.getEncoder().encodeToString(hash); params.put("Signature", actualSign); if (log.isDebugEnabled()) { log.debug("Dump parameters:"); for (Map.Entry<String, String> entry : params.entrySet()) { log.debug(" key: " + entry.getKey() + ", value: " + entry.getValue()); } } } /** * 使用标准URL Encode编码。注意和JDK默认的不同,空格被编码为%20而不是+。 * * @param s String字符串 * @return URL编码后的字符串 */ public static String urlEncode(String s) { try { return URLEncoder.encode(s, "UTF-8").replaceAll("\\+", "%20"); } catch (UnsupportedEncodingException e) { throw new IllegalArgumentException("UTF-8 encoding not supported!"); } } /** * Return epoch seconds */ long epochNow() { return Instant.now().getEpochSecond(); } String gmtNow() { return Instant.ofEpochSecond(epochNow()).atZone(ZONE_GMT).format(DT_FORMAT); } } class JsonUtil { public static String writeValue(Object obj) throws IOException { return objectMapper.writeValueAsString(obj); } public static <T> T readValue(String s, TypeReference<T> ref) throws IOException { return objectMapper.readValue(s, ref); } static final ObjectMapper objectMapper = createObjectMapper(); static ObjectMapper createObjectMapper() { final ObjectMapper mapper = new ObjectMapper(); mapper.setPropertyNamingStrategy(PropertyNamingStrategy.KEBAB_CASE); mapper.setSerializationInclusion(JsonInclude.Include.ALWAYS); // disabled features: mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES); mapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS); mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); return mapper; } } src/main/java/com/xcong/excoin/utils/api/ApiException.java
New file @@ -0,0 +1,33 @@ package com.xcong.excoin.utils.api; /** * ApiException if api returns error. * * @Date 2018/1/14 * @Time 16:02 */ public class ApiException extends RuntimeException { /** * */ private static final long serialVersionUID = 8196662756375909063L; final String errCode; public ApiException(String errCode, String errMsg) { super(errMsg); this.errCode = errCode; } public ApiException(Exception e) { super(e); this.errCode = e.getClass().getName(); } public String getErrCode() { return this.errCode; } } src/main/java/com/xcong/excoin/utils/api/request/CreateOrderRequest.java
New file @@ -0,0 +1,52 @@ package com.xcong.excoin.utils.api.request; public class CreateOrderRequest { public static interface OrderType { /** * 限价买入 */ static final String BUY_LIMIT = "buy-limit"; /** * 限价卖出 */ static final String SELL_LIMIT = "sell-limit"; /** * 市价买入 */ static final String BUY_MARKET = "buy-market"; /** * 市价卖出 */ static final String SELL_MARKET = "sell-market"; } /** * 交易对,必填,例如:"ethcny", */ public String symbol; /** * 账户ID,必填,例如:"12345" */ public String accountId; /** * 当订单类型为buy-limit,sell-limit时,表示订单数量, 当订单类型为buy-market时,表示订单总金额, 当订单类型为sell-market时,表示订单总数量 */ public String amount; /** * 订单价格,仅针对限价单有效,例如:"1234.56" */ public String price = "0.0"; /** * 订单类型,取值范围"buy-market,sell-market,buy-limit,sell-limit" */ public String type; /** * 订单来源,例如:"api" */ public String source = "com/huobi/client/api"; } src/main/java/com/xcong/excoin/utils/api/request/DepthRequest.java
New file @@ -0,0 +1,26 @@ package com.xcong.excoin.utils.api.request; public class DepthRequest { //交易对 public String symbol; //Depth 类型 step0, step1, step2, step3, step4, step5(合并深度0-5);step0时,不合并深度 public String type; public String getSymbol() { return symbol; } public void setSymbol(String symbol) { this.symbol = symbol; } public String getType() { return type; } public void setType(String type) { this.type = type; } } src/main/java/com/xcong/excoin/utils/api/request/IntrustOrdersDetailRequest.java
New file @@ -0,0 +1,62 @@ package com.xcong.excoin.utils.api.request; public class IntrustOrdersDetailRequest { public static interface OrderType { /** * 限价买入 */ static final String BUY_LIMIT = "buy-limit"; /** * 限价卖出 */ static final String SELL_LIMIT = "sell-limit"; /** * 市价买入 */ static final String BUY_MARKET = "buy-market"; /** * 市价卖出 */ static final String SELL_MARKET = "sell-market"; } public static interface OrderStates { /** * pre-submitted 准备提交 */ static final String PRE_SUBMITTED = "pre-submitted"; /** * submitted 已提交 */ static final String SUBMITTED = "submitted"; /** * partial-filled 部分成交 */ static final String PARTIAL_FILLED = "partial-filled"; /** * partial-canceled 部分成交撤销 */ static final String PARTIAL_CANCELED = "partial-canceled"; /** * filled 完全成交 */ static final String FILLED = "filled"; /** * canceled 已撤销 */ static final String CANCELED = "canceled"; } public String symbol; //true string 交易对 btcusdt, bccbtc, rcneth ... public String types; //false string 查询的订单类型组合,使用','分割 buy-market:市价买, sell-market:市价卖, buy-limit:限价买, sell-limit:限价卖 public String startDate; //false string 查询开始日期, 日期格式yyyy-mm-dd public String endDate; //false string 查询结束日期, 日期格式yyyy-mm-dd public String states; //true string 查询的订单状态组合,使用','分割 pre-submitted 准备提交, submitted 已提交, partial-filled 部分成交, // partial-canceled 部分成交撤销, filled 完全成交, canceled 已撤销 public String from; //false string 查询起始 ID public String direct; //false string 查询方向 prev 向前,next 向后 public String size; //false string 查询记录大小 } src/main/java/com/xcong/excoin/utils/api/response/Account.java
New file @@ -0,0 +1,8 @@ package com.xcong.excoin.utils.api.response; public class Account { public long id; public String type; public String state; } src/main/java/com/xcong/excoin/utils/api/response/Accounts.java
New file @@ -0,0 +1,48 @@ package com.xcong.excoin.utils.api.response; public class Accounts { /** * id : 100009 * type : spot * state : working * user-id : 1000 */ private int id; private String type; private String state; private int userid; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getType() { return type; } public void setType(String type) { this.type = type; } public String getState() { return state; } public void setState(String state) { this.state = state; } public int getUserid() { return userid; } public void setUserid(int userid) { this.userid = userid; } } src/main/java/com/xcong/excoin/utils/api/response/AccountsResponse.java
New file @@ -0,0 +1,56 @@ package com.xcong.excoin.utils.api.response; import com.xcong.excoin.utils.api.ApiException; public class AccountsResponse<T> { /** * status : ok * data : [{"id":100009,"type":"spot","state":"working","user-id":1000}] */ private String status; public String errCode; public String errMsg; private T data; public T checkAndReturn() { if ("ok".equals(status)) { return data; } throw new ApiException(errCode, errMsg); } public String getStatus() { return status; } public void setStatus(String status) { this.status = status; } public T getData() { return data; } public void setData(T data) { this.data = data; } public String getErrCode() { return errCode; } public void setErrCode(String errCode) { this.errCode = errCode; } public String getErrMsg() { return errMsg; } public void setErrMsg(String errMsg) { this.errMsg = errMsg; } } src/main/java/com/xcong/excoin/utils/api/response/ApiResponse.java
New file @@ -0,0 +1,19 @@ package com.xcong.excoin.utils.api.response; import com.xcong.excoin.utils.api.ApiException; public class ApiResponse<T> { public String status; public String errCode; public String errMsg; public T data; public T checkAndReturn() { if ("ok".equals(status)) { return data; } throw new ApiException(errCode, errMsg); } } src/main/java/com/xcong/excoin/utils/api/response/Balance.java
New file @@ -0,0 +1,57 @@ package com.xcong.excoin.utils.api.response; public class Balance<T> { /** * id : 100009 * type : spot * state : working * list : [{"currency":"usdt","type":"trade","balance":"500009195917.4362872650"}] * user-id : 1000 */ private String id; private String type; private String state; private String userid; private T list; public String getId() { return id; } public void setId(String id) { this.id = id; } public String getType() { return type; } public void setType(String type) { this.type = type; } public String getState() { return state; } public void setState(String state) { this.state = state; } public String getUserid() { return userid; } public void setUserid(String userid) { this.userid = userid; } public T getList() { return list; } public void setList(T list) { this.list = list; } } src/main/java/com/xcong/excoin/utils/api/response/BalanceBean.java
New file @@ -0,0 +1,37 @@ package com.xcong.excoin.utils.api.response; public class BalanceBean { /** * currency : usdt * type : trade * balance : 500009195917.4362872650 */ private String currency; private String type; private String balance; public String getCurrency() { return currency; } public void setCurrency(String currency) { this.currency = currency; } public String getType() { return type; } public void setType(String type) { this.type = type; } public String getBalance() { return balance; } public void setBalance(String balance) { this.balance = balance; } } src/main/java/com/xcong/excoin/utils/api/response/BalanceResponse.java
New file @@ -0,0 +1,47 @@ package com.xcong.excoin.utils.api.response; public class BalanceResponse<T> { /** * status : ok * data : {"id":"100009","type":"spot","state":"working","list":[{"currency":"usdt","type":"trade","balance":"500009195917.4362872650"}],"user-id":"1000"} */ private String status; public String errCode; public String errMsg; private T data; public String getStatus() { return status; } public void setStatus(String status) { this.status = status; } public T getData() { return data; } public void setData(T data) { this.data = data; } public String getErrCode() { return errCode; } public void setErrCode(String errCode) { this.errCode = errCode; } public String getErrMsg() { return errMsg; } public void setErrMsg(String errMsg) { this.errMsg = errMsg; } } src/main/java/com/xcong/excoin/utils/api/response/Batchcancel.java
New file @@ -0,0 +1,22 @@ package com.xcong.excoin.utils.api.response; public class Batchcancel<T1, T2> { private T1 success; private T2 failed; public T1 getSuccess() { return success; } public void setSuccess(T1 success) { this.success = success; } public T2 getFailed() { return failed; } public void setFailed(T2 failed) { this.failed = failed; } } src/main/java/com/xcong/excoin/utils/api/response/BatchcancelBean.java
New file @@ -0,0 +1,34 @@ package com.xcong.excoin.utils.api.response; /** @Author ISME @Date 2018/1/14 @Time 17:53 */ public class BatchcancelBean { /** err-msg : 记录无效 order-id : 2 err-code : base-record-invalid */ private String errMsg; private String orderId; private String errCode; public String getErrMsg() { return errMsg; } public void setErrMsg(String errMsg) { this.errMsg = errMsg; } public String getOrderId() { return orderId; } public void setOrderId(String orderId) { this.orderId = orderId; } public String getErrCode() { return errCode; } public void setErrCode(String errCode) { this.errCode = errCode; } } src/main/java/com/xcong/excoin/utils/api/response/BatchcancelResponse.java
New file @@ -0,0 +1,47 @@ package com.xcong.excoin.utils.api.response; public class BatchcancelResponse<T> { /** * status : ok * data : {"success":["1","3"],"failed":[{"err-msg":"记录无效","order-id":"2","err-code":"base-record-invalid"}]} */ private String status; public String errCode; public String errMsg; private T data; public String getStatus() { return status; } public void setStatus(String status) { this.status = status; } public String getErrCode() { return errCode; } public void setErrCode(String errCode) { this.errCode = errCode; } public String getErrMsg() { return errMsg; } public void setErrMsg(String errMsg) { this.errMsg = errMsg; } public T getData() { return data; } public void setData(T data) { this.data = data; } } src/main/java/com/xcong/excoin/utils/api/response/Currencys.java
New file @@ -0,0 +1,4 @@ package com.xcong.excoin.utils.api.response; public class Currencys { } src/main/java/com/xcong/excoin/utils/api/response/CurrencysResponse.java
New file @@ -0,0 +1,55 @@ package com.xcong.excoin.utils.api.response; import java.util.List; /** * @Author ISME * @Date 2018/1/14 * @Time 15:46 */ public class CurrencysResponse { /** * status : ok * data : ["usdt","eth","etc"] */ private String status; public String errCode; public String errMsg; private List<String> data; public String getStatus() { return status; } public void setStatus(String status) { this.status = status; } public List<String> getData() { return data; } public void setData(List<String> data) { this.data = data; } public String getErrCode() { return errCode; } public void setErrCode(String errCode) { this.errCode = errCode; } public String getErrMsg() { return errMsg; } public void setErrMsg(String errMsg) { this.errMsg = errMsg; } } src/main/java/com/xcong/excoin/utils/api/response/Depth.java
New file @@ -0,0 +1,57 @@ package com.xcong.excoin.utils.api.response; import java.math.BigDecimal; import java.util.List; /** * @Author ISME * @Date 2018/1/14 * @Time 14:39 */ public class Depth { /** * id : 1489464585407 * ts : 1489464585407 * bids : [[7964,0.0678],[7963,0.9162]] * asks : [[7979,0.0736],[8020,13.6584]] */ private String id; private String ts; private List<List<BigDecimal>> bids; private List<List<BigDecimal>> asks; public String getId() { return id; } public void setId(String id) { this.id = id; } public String getTs() { return ts; } public void setTs(String ts) { this.ts = ts; } public List<List<BigDecimal>> getBids() { return bids; } public void setBids(List<List<BigDecimal>> bids) { this.bids = bids; } public List<List<BigDecimal>> getAsks() { return asks; } public void setAsks(List<List<BigDecimal>> asks) { this.asks = asks; } } src/main/java/com/xcong/excoin/utils/api/response/DepthResponse.java
New file @@ -0,0 +1,78 @@ package com.xcong.excoin.utils.api.response; public class DepthResponse<T> { /** * status : ok * ch : market.btcusdt.depth.step1 * ts : 1489472598812 * tick : {"id":"1489464585407","ts":"1489464585407","bids":[[7964,0.0678],[7963,0.9162]],"asks":[[7979,0.0736],[8020,13.6584]]} */ private String status; private String ch; private String ts; public String errCode; public String errMsg; /** * tick 说明: * "tick": { * "id": 消息id, * "ts": 消息生成时间,单位:毫秒, * "bids": 买盘,[price(成交价), amount(成交量)], 按price降序, * "asks": 卖盘,[price(成交价), amount(成交量)], 按price升序 * } */ private Depth tick; public String getStatus() { return status; } public void setStatus(String status) { this.status = status; } public String getCh() { return ch; } public void setCh(String ch) { this.ch = ch; } public String getTs() { return ts; } public void setTs(String ts) { this.ts = ts; } public Depth getTick() { return tick; } public void setTick(Depth tick) { this.tick = tick; } public String getErrCode() { return errCode; } public void setErrCode(String errCode) { this.errCode = errCode; } public String getErrMsg() { return errMsg; } public void setErrMsg(String errMsg) { this.errMsg = errMsg; } } src/main/java/com/xcong/excoin/utils/api/response/DetailResponse.java
New file @@ -0,0 +1,67 @@ package com.xcong.excoin.utils.api.response; public class DetailResponse<T> { /** * status : ok * ch : market.btcusdt.detail * ts : 1489473538996 * tick : {"amount":4316.4346,"open":8090.54,"close":7962.62,"high":8119,"ts":1489464451000,"id":1489464451,"count":9595,"low":7875,"vol":3.449727690576E7} */ private String status; private String ch; private long ts; public String errCode; public String errMsg; private T tick; public String getStatus() { return status; } public void setStatus(String status) { this.status = status; } public String getCh() { return ch; } public void setCh(String ch) { this.ch = ch; } public long getTs() { return ts; } public void setTs(long ts) { this.ts = ts; } public String getErrCode() { return errCode; } public void setErrCode(String errCode) { this.errCode = errCode; } public String getErrMsg() { return errMsg; } public void setErrMsg(String errMsg) { this.errMsg = errMsg; } public T getTick() { return tick; } public void setTick(T tick) { this.tick = tick; } } src/main/java/com/xcong/excoin/utils/api/response/Details.java
New file @@ -0,0 +1,98 @@ package com.xcong.excoin.utils.api.response; public class Details { /** * amount : 4316.4346 * open : 8090.54 * close : 7962.62 * high : 8119 * ts : 1489464451000 * id : 1489464451 * count : 9595 * low : 7875 * vol : 3.449727690576E7 */ private double amount; private double open; private double close; private int high; private long ts; private long id; private int count; private int low; private double vol; public double getAmount() { return amount; } public void setAmount(double amount) { this.amount = amount; } public double getOpen() { return open; } public void setOpen(double open) { this.open = open; } public double getClose() { return close; } public void setClose(double close) { this.close = close; } public int getHigh() { return high; } public void setHigh(int high) { this.high = high; } public long getTs() { return ts; } public void setTs(long ts) { this.ts = ts; } public long getId() { return id; } public void setId(long id) { this.id = id; } public int getCount() { return count; } public void setCount(int count) { this.count = count; } public int getLow() { return low; } public void setLow(int low) { this.low = low; } public double getVol() { return vol; } public void setVol(double vol) { this.vol = vol; } } src/main/java/com/xcong/excoin/utils/api/response/HistoryTrade.java
New file @@ -0,0 +1,57 @@ package com.xcong.excoin.utils.api.response; public class HistoryTrade { /** * id : 17592256642623 * amount : 0.04 * price : 1997 * direction : buy * ts : 1502448920106 */ private long id; private double amount; private int price; private String direction; private long ts; public long getId() { return id; } public void setId(long id) { this.id = id; } public double getAmount() { return amount; } public void setAmount(double amount) { this.amount = amount; } public int getPrice() { return price; } public void setPrice(int price) { this.price = price; } public String getDirection() { return direction; } public void setDirection(String direction) { this.direction = direction; } public long getTs() { return ts; } public void setTs(long ts) { this.ts = ts; } } src/main/java/com/xcong/excoin/utils/api/response/HistoryTradeResponse.java
New file @@ -0,0 +1,67 @@ package com.xcong.excoin.utils.api.response; public class HistoryTradeResponse<T> { /** * status : ok * ch : market.ethusdt.trade.detail * ts : 1502448925216 * data : [{"id":31459998,"ts":1502448920106,"data":[{"id":17592256642623,"amount":0.04,"price":1997,"direction":"buy","ts":1502448920106}]}] */ private String status; private String ch; private long ts; public String errCode; public String errMsg; private T data; public String getStatus() { return status; } public void setStatus(String status) { this.status = status; } public String getCh() { return ch; } public void setCh(String ch) { this.ch = ch; } public long getTs() { return ts; } public void setTs(long ts) { this.ts = ts; } public T getData() { return data; } public void setData(T data) { this.data = data; } public String getErrCode() { return errCode; } public void setErrCode(String errCode) { this.errCode = errCode; } public String getErrMsg() { return errMsg; } public void setErrMsg(String errMsg) { this.errMsg = errMsg; } } src/main/java/com/xcong/excoin/utils/api/response/HistoryTradess.java
New file @@ -0,0 +1,37 @@ package com.xcong.excoin.utils.api.response; public class HistoryTradess { /** * id : 31459998 * ts : 1502448920106 * data : [{"id":17592256642623,"amount":0.04,"price":1997,"direction":"buy","ts":1502448920106}] */ private long id; private long ts; private HistoryTrade data; public long getId() { return id; } public void setId(long id) { this.id = id; } public long getTs() { return ts; } public void setTs(long ts) { this.ts = ts; } public HistoryTrade getData() { return data; } public void setData(HistoryTrade data) { this.data = data; } } src/main/java/com/xcong/excoin/utils/api/response/IntrustDetail.java
New file @@ -0,0 +1,194 @@ package com.xcong.excoin.utils.api.response; import com.google.gson.annotations.SerializedName; /** * @Author ISME * @Date 2018/1/14 * @Time 19:20 */ public class IntrustDetail { /** * id : 59378 * symbol : ethusdt * account-id : 100009 * amount : 10.1000000000 * price : 100.1000000000 * created-at : 1494901162595 * type : buy-limit * field-amount : 10.1000000000 * field-cash-amount : 1011.0100000000 * field-fees : 0.0202000000 * finished-at : 1494901400468 * user-id : 1000 * source : api * state : filled * canceled-at : 0 * exchange : huobi * batch : */ private long id; private String symbol; @SerializedName("account-id") private int accountid; private String amount; private String price; @SerializedName("created-at") private long createdat; private String type; @SerializedName("field-amount") private String fieldamount; @SerializedName("field-cash-amount") private String fieldcashamount; @SerializedName("field-fees") private String fieldfees; @SerializedName("finished-at") private long finishedat; @SerializedName("user-id") private int userid; private String source; private String state; @SerializedName("canceled-at") private int canceledat; private String exchange; private String batch; public long getId() { return id; } public void setId(long id) { this.id = id; } public String getSymbol() { return symbol; } public void setSymbol(String symbol) { this.symbol = symbol; } public int getAccountid() { return accountid; } public void setAccountid(int accountid) { this.accountid = accountid; } public String getAmount() { return amount; } public void setAmount(String amount) { this.amount = amount; } public String getPrice() { return price; } public void setPrice(String price) { this.price = price; } public long getCreatedat() { return createdat; } public void setCreatedat(long createdat) { this.createdat = createdat; } public String getType() { return type; } public void setType(String type) { this.type = type; } public String getFieldamount() { return fieldamount; } public void setFieldamount(String fieldamount) { this.fieldamount = fieldamount; } public String getFieldcashamount() { return fieldcashamount; } public void setFieldcashamount(String fieldcashamount) { this.fieldcashamount = fieldcashamount; } public String getFieldfees() { return fieldfees; } public void setFieldfees(String fieldfees) { this.fieldfees = fieldfees; } public long getFinishedat() { return finishedat; } public void setFinishedat(long finishedat) { this.finishedat = finishedat; } public int getUserid() { return userid; } public void setUserid(int userid) { this.userid = userid; } public String getSource() { return source; } public void setSource(String source) { this.source = source; } public String getState() { return state; } public void setState(String state) { this.state = state; } public int getCanceledat() { return canceledat; } public void setCanceledat(int canceledat) { this.canceledat = canceledat; } public String getExchange() { return exchange; } public void setExchange(String exchange) { this.exchange = exchange; } public String getBatch() { return batch; } public void setBatch(String batch) { this.batch = batch; } } src/main/java/com/xcong/excoin/utils/api/response/IntrustDetailResponse.java
New file @@ -0,0 +1,47 @@ package com.xcong.excoin.utils.api.response; public class IntrustDetailResponse<T> { /** * status : ok * data : [{"id":59378,"symbol":"ethusdt","account-id":100009,"amount":"10.1000000000","price":"100.1000000000","created-at":1494901162595,"type":"buy-limit","field-amount":"10.1000000000","field-cash-amount":"1011.0100000000","field-fees":"0.0202000000","finished-at":1494901400468,"user-id":1000,"source":"api","state":"filled","canceled-at":0,"exchange":"huobi","batch":""}] */ private String status; public String errCode; public String errMsg; private T data; public String getStatus() { return status; } public void setStatus(String status) { this.status = status; } public T getData() { return data; } public void setData(T data) { this.data = data; } public String getErrCode() { return errCode; } public void setErrCode(String errCode) { this.errCode = errCode; } public String getErrMsg() { return errMsg; } public void setErrMsg(String errMsg) { this.errMsg = errMsg; } } src/main/java/com/xcong/excoin/utils/api/response/Kline.java
New file @@ -0,0 +1,68 @@ package com.xcong.excoin.utils.api.response; public class Kline { private long id; private float amount; private int count; private float open; private float close; private float low; private float high; private float vol; public long getId() { return id; } public void setId(long id) { this.id = id; } public float getAmount() { return amount; } public void setAmount(float amount) { this.amount = amount; } public int getCount() { return count; } public void setCount(int count) { this.count = count; } public float getOpen() { return open; } public void setOpen(float open) { this.open = open; } public float getClose() { return close; } public void setClose(float close) { this.close = close; } public float getLow() { return low; } public void setLow(float low) { this.low = low; } public float getHigh() { return high; } public void setHigh(float high) { this.high = high; } public float getVol() { return vol; } public void setVol(float vol) { this.vol = vol; } @Override public String toString() { return "Kline [id=" + id + ", amount=" + amount + ", count=" + count + ", open=" + open + ", close=" + close + ", low=" + low + ", high=" + high + ", vol=" + vol + "]"; } } src/main/java/com/xcong/excoin/utils/api/response/KlineResponse.java
New file @@ -0,0 +1,55 @@ package com.xcong.excoin.utils.api.response; import com.xcong.excoin.utils.api.ApiException; public class KlineResponse<T> { private String status; /** * 接口名 */ private String ch; /** * 时间格式 */ private String ts; public String errCode; public String errMsg; /** * 数据 */ public T data; public T checkAndReturn() { if ("ok".equals(status)) { return data; } throw new ApiException(errCode, errMsg); } public String getStatus() { return status; } public void setStatus(String status) { this.status = status; } public String getCh() { return ch; } public void setCh(String ch) { this.ch = ch; } public String getTs() { return ts; } public void setTs(String ts) { this.ts = ts; } } src/main/java/com/xcong/excoin/utils/api/response/KlineReturn.java
New file @@ -0,0 +1,66 @@ package com.xcong.excoin.utils.api.response; public class KlineReturn { private long time; private float open; private float high; private float low; private float close; private float volume; private float amount; // private int count; public float getOpen() { return open; } public void setOpen(float open) { this.open = open; } public float getClose() { return close; } public void setClose(float close) { this.close = close; } public float getLow() { return low; } public void setLow(float low) { this.low = low; } public float getHigh() { return high; } public void setHigh(float high) { this.high = high; } public long getTime() { return time; } public void setTime(long time) { this.time = time; } public float getVolume() { return volume; } public void setVolume(float volume) { this.volume = volume; } public float getAmount() { return amount; } public void setAmount(float amount) { this.amount = amount; } @Override public String toString() { return "KlineReturn [time=" + time + ", open=" + open + ", high=" + high + ", low=" + low + ", close=" + close + ", volume=" + volume + "]"; } } src/main/java/com/xcong/excoin/utils/api/response/MatchresultsOrdersDetail.java
New file @@ -0,0 +1,112 @@ package com.xcong.excoin.utils.api.response; public class MatchresultsOrdersDetail { /** * id : 29553 * order-id : 59378 * match-id : 59335 * symbol : ethusdt * type : buy-limit * source : api * price : 100.1000000000 * filled-amount : 9.1155000000 * filled-fees : 0.0182310000 * created-at : 1494901400435 */ private long id; @com.google.gson.annotations.SerializedName("order-id") private long orderid; @com.google.gson.annotations.SerializedName("match-id") private long matchid; private String symbol; private String type; private String source; private String price; @com.google.gson.annotations.SerializedName("filled-amount") private String filledamount; @com.google.gson.annotations.SerializedName("filled-fees") private String filledfees; @com.google.gson.annotations.SerializedName("created-at") private long createdat; public long getId() { return id; } public void setId(long id) { this.id = id; } public long getOrderid() { return orderid; } public void setOrderid(long orderid) { this.orderid = orderid; } public long getMatchid() { return matchid; } public void setMatchid(long matchid) { this.matchid = matchid; } public String getSymbol() { return symbol; } public void setSymbol(String symbol) { this.symbol = symbol; } public String getType() { return type; } public void setType(String type) { this.type = type; } public String getSource() { return source; } public void setSource(String source) { this.source = source; } public String getPrice() { return price; } public void setPrice(String price) { this.price = price; } public String getFilledamount() { return filledamount; } public void setFilledamount(String filledamount) { this.filledamount = filledamount; } public String getFilledfees() { return filledfees; } public void setFilledfees(String filledfees) { this.filledfees = filledfees; } public long getCreatedat() { return createdat; } public void setCreatedat(long createdat) { this.createdat = createdat; } } src/main/java/com/xcong/excoin/utils/api/response/MatchresultsOrdersDetailResponse.java
New file @@ -0,0 +1,47 @@ package com.xcong.excoin.utils.api.response; public class MatchresultsOrdersDetailResponse<T> { /** * status : ok * data : [{"id":29553,"order-id":59378,"match-id":59335,"symbol":"ethusdt","type":"buy-limit","source":"api","price":"100.1000000000","filled-amount":"9.1155000000","filled-fees":"0.0182310000","created-at":1494901400435}] */ private String status; public String errCode; public String errMsg; private T data; public String getStatus() { return status; } public void setStatus(String status) { this.status = status; } public T getData() { return data; } public void setData(T data) { this.data = data; } public String getErrCode() { return errCode; } public void setErrCode(String errCode) { this.errCode = errCode; } public String getErrMsg() { return errMsg; } public void setErrMsg(String errMsg) { this.errMsg = errMsg; } } src/main/java/com/xcong/excoin/utils/api/response/Merged.java
New file @@ -0,0 +1,121 @@ package com.xcong.excoin.utils.api.response; import java.util.List; public class Merged { /** * id : 1499225271 * ts : 1499225271000 * close : 1885 * open : 1960 * high : 1985 * low : 1856 * amount : 81486.2926 * count : 42122 * vol : 1.57052744857082E8 * ask : [1885,21.8804] * bid : [1884,1.6702] */ private long id; private long ts; private int close; private int open; private int high; private int low; private double amount; private int count; private double vol; private List<Integer> ask; private List<Integer> bid; public long getId() { return id; } public void setId(long id) { this.id = id; } public long getTs() { return ts; } public void setTs(long ts) { this.ts = ts; } public int getClose() { return close; } public void setClose(int close) { this.close = close; } public int getOpen() { return open; } public void setOpen(int open) { this.open = open; } public int getHigh() { return high; } public void setHigh(int high) { this.high = high; } public int getLow() { return low; } public void setLow(int low) { this.low = low; } public double getAmount() { return amount; } public void setAmount(double amount) { this.amount = amount; } public int getCount() { return count; } public void setCount(int count) { this.count = count; } public double getVol() { return vol; } public void setVol(double vol) { this.vol = vol; } public List<Integer> getAsk() { return ask; } public void setAsk(List<Integer> ask) { this.ask = ask; } public List<Integer> getBid() { return bid; } public void setBid(List<Integer> bid) { this.bid = bid; } } src/main/java/com/xcong/excoin/utils/api/response/MergedResponse.java
New file @@ -0,0 +1,77 @@ package com.xcong.excoin.utils.api.response; import com.xcong.excoin.utils.api.ApiException; public class MergedResponse<T> { /** * status : ok * ch : market.ethusdt.detail.merged * ts : 1499225276950 * tick : {"id":1499225271,"ts":1499225271000,"close":1885,"open":1960,"high":1985,"low":1856,"amount":81486.2926,"count":42122,"vol":1.57052744857082E8,"ask":[1885,21.8804],"bid":[1884,1.6702]} */ private String status; private String ch; private long ts; public String errCode; public String errMsg; public Object tick; public Object checkAndReturn() { if ("ok".equals(status)) { return tick; } throw new ApiException(errCode, errMsg); } public String getStatus() { return status; } public void setStatus(String status) { this.status = status; } public String getCh() { return ch; } public void setCh(String ch) { this.ch = ch; } public long getTs() { return ts; } public void setTs(long ts) { this.ts = ts; } public String getErrCode() { return errCode; } public void setErrCode(String errCode) { this.errCode = errCode; } public String getErrMsg() { return errMsg; } public void setErrMsg(String errMsg) { this.errMsg = errMsg; } public Object getTick() { return tick; } public void setTick(Object tick) { this.tick = tick; } } src/main/java/com/xcong/excoin/utils/api/response/OrdersDetail.java
New file @@ -0,0 +1,178 @@ package com.xcong.excoin.utils.api.response; public class OrdersDetail { /** * id : 59378 * symbol : ethusdt * account-id : 100009 * amount : 10.1000000000 * price : 100.1000000000 * created-at : 1494901162595 * type : buy-limit * field-amount : 10.1000000000 * field-cash-amount : 1011.0100000000 * field-fees : 0.0202000000 * finished-at : 1494901400468 * user-id : 1000 * source : api * state : filled * canceled-at : 0 * exchange : huobi * batch : */ private long id; private String symbol; private int accountid; private String amount; private String price; private long createdat; private String type; private String fieldamount; private String fieldcashamount; private String fieldfees; private long finishedat; private int userid; private String source; private String state; private long canceledat; private String exchange; private String batch; public long getId() { return id; } public void setId(long id) { this.id = id; } public String getSymbol() { return symbol; } public void setSymbol(String symbol) { this.symbol = symbol; } public int getAccountid() { return accountid; } public void setAccountid(int accountid) { this.accountid = accountid; } public String getAmount() { return amount; } public void setAmount(String amount) { this.amount = amount; } public String getPrice() { return price; } public void setPrice(String price) { this.price = price; } public long getCreatedat() { return createdat; } public void setCreatedat(long createdat) { this.createdat = createdat; } public String getType() { return type; } public void setType(String type) { this.type = type; } public String getFieldamount() { return fieldamount; } public void setFieldamount(String fieldamount) { this.fieldamount = fieldamount; } public String getFieldcashamount() { return fieldcashamount; } public void setFieldcashamount(String fieldcashamount) { this.fieldcashamount = fieldcashamount; } public String getFieldfees() { return fieldfees; } public void setFieldfees(String fieldfees) { this.fieldfees = fieldfees; } public long getFinishedat() { return finishedat; } public void setFinishedat(long finishedat) { this.finishedat = finishedat; } public int getUserid() { return userid; } public void setUserid(int userid) { this.userid = userid; } public String getSource() { return source; } public void setSource(String source) { this.source = source; } public String getState() { return state; } public void setState(String state) { this.state = state; } public long getCanceledat() { return canceledat; } public void setCanceledat(long canceledat) { this.canceledat = canceledat; } public String getExchange() { return exchange; } public void setExchange(String exchange) { this.exchange = exchange; } public String getBatch() { return batch; } public void setBatch(String batch) { this.batch = batch; } } src/main/java/com/xcong/excoin/utils/api/response/OrdersDetailResponse.java
New file @@ -0,0 +1,50 @@ package com.xcong.excoin.utils.api.response; public class OrdersDetailResponse<T> { /** * status : ok * data : {"id":59378,"symbol":"ethusdt","account-id":100009,"amount":"10.1000000000","price":"100.1000000000","created-at":1494901162595,"type":"buy-limit","field-amount":"10.1000000000","field-cash-amount":"1011.0100000000","field-fees":"0.0202000000","finished-at":1494901400468,"user-id":1000,"source":"api","state":"filled","canceled-at":0,"exchange":"huobi","batch":""} */ private String status; public String errCode; public String errMsg; private T data; public String getStatus() { return status; } public void setStatus(String status) { this.status = status; } public T getData() { return data; } public void setData(T data) { this.data = data; } public static class DataBean { } public String getErrCode() { return errCode; } public void setErrCode(String errCode) { this.errCode = errCode; } public String getErrMsg() { return errMsg; } public void setErrMsg(String errMsg) { this.errMsg = errMsg; } } src/main/java/com/xcong/excoin/utils/api/response/Place.java
New file @@ -0,0 +1,4 @@ package com.xcong.excoin.utils.api.response; public class Place { } src/main/java/com/xcong/excoin/utils/api/response/SubmitcancelResponse.java
New file @@ -0,0 +1,47 @@ package com.xcong.excoin.utils.api.response; public class SubmitcancelResponse { /** * status : ok * data : 59378 */ private String status; public String errCode; public String errMsg; private String data; public String getStatus() { return status; } public void setStatus(String status) { this.status = status; } public String getData() { return data; } public void setData(String data) { this.data = data; } public String getErrCode() { return errCode; } public void setErrCode(String errCode) { this.errCode = errCode; } public String getErrMsg() { return errMsg; } public void setErrMsg(String errMsg) { this.errMsg = errMsg; } } src/main/java/com/xcong/excoin/utils/api/response/Symbol.java
New file @@ -0,0 +1,9 @@ package com.xcong.excoin.utils.api.response; public class Symbol { public String baseCurrency; public String quoteCurrency; public String symbol; } src/main/java/com/xcong/excoin/utils/api/response/Symbols.java
New file @@ -0,0 +1,98 @@ package com.xcong.excoin.utils.api.response; public class Symbols { /** * amount : 4316.4346 * open : 8090.54 * close : 7962.62 * high : 8119 * ts : 1489464451000 * id : 1489464451 * count : 9595 * low : 7875 * vol : 3.449727690576E7 */ private double amount; private double open; private double close; private int high; private long ts; private long id; private int count; private int low; private double vol; public double getAmount() { return amount; } public void setAmount(double amount) { this.amount = amount; } public double getOpen() { return open; } public void setOpen(double open) { this.open = open; } public double getClose() { return close; } public void setClose(double close) { this.close = close; } public int getHigh() { return high; } public void setHigh(int high) { this.high = high; } public long getTs() { return ts; } public void setTs(long ts) { this.ts = ts; } public long getId() { return id; } public void setId(long id) { this.id = id; } public int getCount() { return count; } public void setCount(int count) { this.count = count; } public int getLow() { return low; } public void setLow(int low) { this.low = low; } public double getVol() { return vol; } public void setVol(double vol) { this.vol = vol; } } src/main/java/com/xcong/excoin/utils/api/response/SymbolsResponse.java
New file @@ -0,0 +1,67 @@ package com.xcong.excoin.utils.api.response; public class SymbolsResponse<T> { /** * status : ok * ch : market.btcusdt.detail * ts : 1489473538996 * tick : {"amount":4316.4346,"open":8090.54,"close":7962.62,"high":8119,"ts":1489464451000,"id":1489464451,"count":9595,"low":7875,"vol":3.449727690576E7} */ private String status; private String ch; private long ts; public String errCode; public String errMsg; private T tick; public String getStatus() { return status; } public void setStatus(String status) { this.status = status; } public String getCh() { return ch; } public void setCh(String ch) { this.ch = ch; } public long getTs() { return ts; } public void setTs(long ts) { this.ts = ts; } public String getErrCode() { return errCode; } public void setErrCode(String errCode) { this.errCode = errCode; } public String getErrMsg() { return errMsg; } public void setErrMsg(String errMsg) { this.errMsg = errMsg; } public T getTick() { return tick; } public void setTick(T tick) { this.tick = tick; } } src/main/java/com/xcong/excoin/utils/api/response/TimestampResponse.java
New file @@ -0,0 +1,45 @@ package com.xcong.excoin.utils.api.response; import java.text.SimpleDateFormat; import java.util.Date; /** * @Author ISME * @Date 2018/1/14 * @Time 15:53 */ public class TimestampResponse { /** * status : ok * data : 1494900087029 */ private String status; private long data; @SuppressWarnings("unused") private String dateTime; public String getStatus() { return status; } public void setStatus(String status) { this.status = status; } public long getData() { return data; } public void setData(long data) { this.data = data; } public String getDateTime() { SimpleDateFormat sdf = new SimpleDateFormat("YYYY-MM-dd hh:mm:ss"); Date date = new Date(data); return sdf.format(date); } } src/main/java/com/xcong/excoin/utils/api/response/Trade.java
New file @@ -0,0 +1,38 @@ package com.xcong.excoin.utils.api.response; public class Trade<T> { /** * id : 600848670 * ts : 1489464451000 * data : [{"id":600848670,"price":7962.62,"amount":0.0122,"direction":"buy","ts":1489464451000}] */ private long id; private long ts; private T data; public long getId() { return id; } public void setId(long id) { this.id = id; } public long getTs() { return ts; } public void setTs(long ts) { this.ts = ts; } public T getData() { return data; } public void setData(T data) { this.data = data; } } src/main/java/com/xcong/excoin/utils/api/response/TradeBean.java
New file @@ -0,0 +1,60 @@ package com.xcong.excoin.utils.api.response; public class TradeBean { /** * id : 600848670 * price : 7962.62 * amount : 0.0122 * direction : buy * ts : 1489464451000 */ private long id; private double price; private double amount; private String direction; private long ts; public long getId() { return id; } public void setId(long id) { this.id = id; } public double getPrice() { return price; } public void setPrice(double price) { this.price = price; } public double getAmount() { return amount; } public void setAmount(double amount) { this.amount = amount; } public String getDirection() { return direction; } public void setDirection(String direction) { this.direction = direction; } public long getTs() { return ts; } public void setTs(long ts) { this.ts = ts; } } src/main/java/com/xcong/excoin/utils/api/response/TradeResponse.java
New file @@ -0,0 +1,70 @@ package com.xcong.excoin.utils.api.response; public class TradeResponse { /** * status : ok * ch : market.btcusdt.trade.detail * ts : 1489473346905 * tick : {"id":600848670,"ts":1489464451000,"data":[{"id":600848670,"price":7962.62,"amount":0.0122,"direction":"buy","ts":1489464451000}]} */ private String status; private String ch; private long ts; public String errCode; public String errMsg; @SuppressWarnings("rawtypes") private Trade tick; public String getStatus() { return status; } public void setStatus(String status) { this.status = status; } public String getCh() { return ch; } public void setCh(String ch) { this.ch = ch; } public long getTs() { return ts; } public void setTs(long ts) { this.ts = ts; } public String getErrCode() { return errCode; } public void setErrCode(String errCode) { this.errCode = errCode; } public String getErrMsg() { return errMsg; } public void setErrMsg(String errMsg) { this.errMsg = errMsg; } @SuppressWarnings("rawtypes") public Trade getTick() { return tick; } @SuppressWarnings("rawtypes") public void setTick(Trade tick) { this.tick = tick; } } src/main/java/com/xcong/excoin/utils/mail/RequestEncoder.java
New file @@ -0,0 +1,71 @@ package com.xcong.excoin.utils.mail; import java.security.MessageDigest; import java.util.Iterator; import java.util.Map; import java.util.Set; /** * 处理请求数据 * @author submail * */ public class RequestEncoder { private static final char[] HEX_DIGITS = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; public static final String MD5 = "MD5"; public static final String SHA1 = "SHA1"; /** * 编码的字符串 * * @param algorithm * @param str * @return String */ public static String encode(String algorithm, String str) { if (str == null) { return null; } try { MessageDigest messageDigest = MessageDigest.getInstance(algorithm); messageDigest.update(str.getBytes("UTF-8")); return getFormattedText(messageDigest.digest()); } catch (Exception e) { throw new RuntimeException(e); } } /** *获取原始字节并将其格式化。 * @param bytes * the raw bytes from the digest. * @return the formatted bytes. */ private static String getFormattedText(byte[] bytes) { int len = bytes.length; StringBuilder buf = new StringBuilder(len * 2); for (int j = 0; j < len; j++) { buf.append(HEX_DIGITS[(bytes[j] >> 4) & 0x0f]); buf.append(HEX_DIGITS[bytes[j] & 0x0f]); } return buf.toString(); } public static String formatRequest(Map<String, Object> data){ Set<String> keySet = data.keySet(); Iterator<String> it = keySet.iterator(); StringBuffer sb = new StringBuffer(); while(it.hasNext()){ String key = it.next(); Object value = data.get(key); if(value instanceof String){ sb.append(key + "=" + value + "&"); } } if(sb.length() != 0){ return sb.substring(0, sb.length() - 1); } return null; } } src/main/java/com/xcong/excoin/utils/mail/SubMailSend.java
New file @@ -0,0 +1,133 @@ package com.xcong.excoin.utils.mail; import net.sf.json.JSONObject; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.entity.ContentType; import org.apache.http.entity.mime.MultipartEntityBuilder; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClientBuilder; import org.apache.http.protocol.HTTP; import org.apache.http.util.EntityUtils; import java.io.IOException; import java.util.Map; import java.util.TreeMap; /** * 邮件发送 * * @author wzy * @date 2020-05-27 **/ public class SubMailSend { /** * 时间戳接口配置 */ public static final String TIMESTAMP = "https://api.mysubmail.com/service/timestamp"; /** * API 请求接口配置 */ private static final String URL = "https://api.mysubmail.com/mail/xsend"; public static final String TYPE_MD5 = "md5"; public static final String TYPE_SHA1 = "sha1"; public static boolean sendMail(String to, String code) { TreeMap<String, Object> requestData = new TreeMap<String, Object>(); JSONObject vars = new JSONObject(); vars.put("code", code); String appid = "16082"; String appkey = "f34c792a1112c16c190ed7190d386c4f"; String project = "fMBQk1"; String signtype = ""; String from = "ex@submail.excoin.site"; requestData.put("appid", appid); requestData.put("project", project); requestData.put("to", to); requestData.put("from", from); if (!vars.isEmpty()) { requestData.put("vars", vars.toString()); } MultipartEntityBuilder builder = MultipartEntityBuilder.create(); @SuppressWarnings("deprecation") ContentType contentType = ContentType.create(HTTP.PLAIN_TEXT_TYPE, HTTP.UTF_8); for (Map.Entry<String, Object> entry : requestData.entrySet()) { String key = entry.getKey(); Object value = entry.getValue(); if (value instanceof String) { builder.addTextBody(key, String.valueOf(value), contentType); } } if (signtype.equals(TYPE_MD5) || signtype.equals(TYPE_SHA1)) { String timestamp = getTimestamp(); requestData.put("timestamp", timestamp); requestData.put("sign_type", signtype); String signStr = appid + appkey + RequestEncoder.formatRequest(requestData) + appid + appkey; builder.addTextBody("timestamp", timestamp); builder.addTextBody("sign_type", signtype); builder.addTextBody("signature", RequestEncoder.encode(signtype, signStr), contentType); } else { builder.addTextBody("signature", appkey, contentType); } HttpPost httpPost = new HttpPost(URL); httpPost.addHeader("charset", "UTF-8"); httpPost.setEntity(builder.build()); try { CloseableHttpClient closeableHttpClient = HttpClientBuilder.create().build(); HttpResponse response = closeableHttpClient.execute(httpPost); HttpEntity httpEntity = response.getEntity(); if (httpEntity != null) { String jsonStr = EntityUtils.toString(httpEntity, "UTF-8"); if ("success".equals(JSONObject.fromObject(jsonStr).getString("status"))) { return true; } } } catch (ClientProtocolException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return false; } /** * 获取时间戳 * * @return */ private static String getTimestamp() { CloseableHttpClient closeableHttpClient = HttpClientBuilder.create().build(); HttpGet httpget = new HttpGet(TIMESTAMP); try { HttpResponse response = closeableHttpClient.execute(httpget); HttpEntity httpEntity = response.getEntity(); String jsonStr = EntityUtils.toString(httpEntity, "UTF-8"); if (jsonStr != null) { JSONObject json = JSONObject.fromObject(jsonStr); return json.getString("timestamp"); } closeableHttpClient.close(); } catch (ClientProtocolException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return null; } public static void main(String[] args) { System.out.println(sendMail("123@123.com", "123456")); } } src/main/resources/logback-spring.xml
@@ -3,6 +3,7 @@ <contextName>logback</contextName> <!-- name的值是变量的名称,value的值时变量定义的值。通过定义的值会被插入到logger上下文中。定义变量后,可以使“${}”来使用变量。 --> <property name="log.path" value="logs" /> <statusListener class="ch.qos.logback.core.status.NopStatusListener" /> <!-- 彩色日志 --> <!-- 彩色日志依赖的渲染类 --> src/main/resources/mapper/platform/PlatformSymbolsContractDao.xml
New file @@ -0,0 +1,5 @@ <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.xcong.excoin.modules.symbols.dao.PlatformSymbolsContractDao"> </mapper> src/test/java/com/xcong/excoin/HuobiTest.java
New file @@ -0,0 +1,39 @@ package com.xcong.excoin; import com.alibaba.fastjson.JSONObject; import com.huobi.client.SubscriptionClient; import com.huobi.client.SubscriptionOptions; import com.huobi.client.model.Candlestick; import com.huobi.client.model.enums.CandlestickInterval; import lombok.extern.slf4j.Slf4j; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; /** * @author wzy * @date 2020-05-22 **/ @Slf4j @SpringBootTest public class HuobiTest { @Test public void websocketTest() { } public static void main(String[] args) { System.out.println("========价格更新开启======="); SubscriptionOptions subscriptionOptions = new SubscriptionOptions(); //3秒重试 subscriptionOptions.setConnectionDelayOnFailure(5); subscriptionOptions.setUri("wss://api.hadax.com/ws"); SubscriptionClient subscriptionClient = SubscriptionClient.create("", "", subscriptionOptions); // subscriptionClient.subscribeTradeEvent("btcusdt,ethusdt,xrpusdt,ltcusdt,bchusdt,eosusdt,etcusdt", tradeEvent -> { // log.info("{}", JSONObject.toJSONString(tradeEvent)); // }); subscriptionClient.subscribeCandlestickEvent("btcusdt,ethusdt,eosusdt,etcusdt,ltcusdt,bchusdt,xrpusdt", CandlestickInterval.DAY1, (candlestickEvent) -> { log.info("{}", JSONObject.toJSONString(candlestickEvent)); }); } } src/test/java/com/xcong/excoin/SmsTest.java
New file @@ -0,0 +1,14 @@ package com.xcong.excoin; import cn.hutool.core.text.UnicodeUtil; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; /** * @author wzy * @date 2020-05-26 **/ @SpringBootTest public class SmsTest { } src/test/java/com/xcong/excoin/SymbolsTest.java
New file @@ -0,0 +1,23 @@ package com.xcong.excoin; import com.xcong.excoin.modules.symbols.service.SymbolsService; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; import javax.annotation.Resource; /** * @author wzy * @date 2020-05-26 **/ @SpringBootTest public class SymbolsTest { @Resource private SymbolsService symbolsService; @Test public void symbolsTest() { symbolsService.updateSymbolsKine("1min"); } }