instruments = HuobiProMdOptionExchange.getContractInfo();
142 | HuobiProMdOptionExchange ex = new HuobiProMdOptionExchange();
143 | for (Instrument i : instruments) {
144 | Depth df = ex.getDepth(i.getName());
145 | log.info(HuobiProMdOptionExchange.getOptionDetailInfo(i.getName()).toString());
146 | // log.info(ex.getDepth(i.getName()).toString());
147 | }
148 |
149 | log.info(instruments.toString());
150 | }
151 | }
152 |
--------------------------------------------------------------------------------
/common/src/main/java/com/zyf/common/util/DateUtil.java:
--------------------------------------------------------------------------------
1 | package com.zyf.common.util;
2 |
3 | import java.text.ParseException;
4 | import java.text.SimpleDateFormat;
5 | import java.time.Instant;
6 | import java.time.LocalDate;
7 | import java.time.LocalDateTime;
8 | import java.time.ZoneId;
9 | import java.util.Date;
10 |
11 | /**
12 | * @author yuanfeng.z
13 | * @description 时间操作类
14 | * @date 2019/2/21 18:46
15 | */
16 | public class DateUtil {
17 | /**
18 | * 天(毫秒)
19 | */
20 | public static Double MS_DAY = 86400000d;
21 |
22 | /**
23 | * 时间格式
24 | */
25 | public static String yyyyMMddHHmmss = "yyyy-MM-dd HH:mm:ss";
26 |
27 | /**
28 | * 时间格式
29 | */
30 | public static String yyyyMMddTHHmmssSSSZ = "yyyy-MM-dd'T'HH:mm:ss.SSSZ";
31 |
32 | /**
33 | * 时间格式
34 | */
35 | public static String yyyyMMddHHmmssSSS = "yyyy-MM-dd HH:mm:ss:SSS";
36 |
37 | /**
38 | * 时间格式
39 | */
40 | public static String yyyyMMdd = "yyyyMMdd";
41 |
42 | /**
43 | * 时间间隔时间戳
44 | *
45 | * @param begin 开始时间
46 | * @param end 结束时间
47 | * @return
48 | */
49 | public static Double timeInterval(Date begin, Date end) {
50 | return ((end.getTime() - begin.getTime()) / MS_DAY);
51 | }
52 |
53 | /**
54 | * java.util.Date --> java.time.LocalDateTime
55 | *
56 | * @param date
57 | * @return
58 | */
59 | public static LocalDateTime dateToLocalDateTime(Date date) {
60 | Instant instant = date.toInstant();
61 | ZoneId zone = ZoneId.systemDefault();
62 | LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, zone);
63 | return localDateTime;
64 | }
65 |
66 | /**
67 | * java.util.Date --> java.time.LocalDate
68 | *
69 | * @param date
70 | * @return
71 | */
72 | public static LocalDate dateToLocalDate(Date date) {
73 | Instant instant = date.toInstant();
74 | ZoneId zoneId = ZoneId.systemDefault();
75 | LocalDate localDate = instant.atZone(zoneId).toLocalDate();
76 | return localDate;
77 | }
78 |
79 | /**
80 | * string to date
81 | *
82 | * @param str
83 | * @return
84 | */
85 | public static Date str2Date(String str) {
86 | Date date;
87 | try {
88 | SimpleDateFormat sdf = new SimpleDateFormat(yyyyMMddHHmmssSSS);
89 | date = sdf.parse(str);
90 | } catch (ParseException e) {
91 | System.out.println(e.getMessage());
92 | return null;
93 | }
94 | return date;
95 | }
96 |
97 | /**
98 | * string to date
99 | *
100 | * @param str
101 | * @return
102 | */
103 | public static Date str2Date(String str, String format) {
104 | Date date;
105 | try {
106 | SimpleDateFormat sdf = new SimpleDateFormat(format);
107 | date = sdf.parse(str);
108 | } catch (ParseException e) {
109 | System.out.println(e.getMessage());
110 | return null;
111 | }
112 | return date;
113 | }
114 |
115 | /**
116 | * string to timestamp
117 | *
118 | * @param str
119 | * @return
120 | */
121 | public static Long str2TimeStamp(String str) {
122 | return DateUtil.str2Date(str).getTime();
123 | }
124 |
125 | /**
126 | * string to timestamp
127 | *
128 | * @param str
129 | * @param format
130 | * @return
131 | */
132 | public static Long str2TimeStamp(String str, String format) {
133 | return DateUtil.str2Date(str, format).getTime();
134 | }
135 |
136 | /**
137 | * timestamp to date
138 | *
139 | * @param time 时间戳
140 | * @return
141 | */
142 | public static Date timestamp2Date(long time) {
143 | Date date;
144 | try {
145 | SimpleDateFormat sdf = new SimpleDateFormat(yyyyMMddHHmmssSSS);
146 | String str = sdf.format(time);
147 | date = sdf.parse(str);
148 | } catch (ParseException e) {
149 | System.out.println(e.getMessage());
150 | return null;
151 | }
152 | return date;
153 | }
154 |
155 | /**
156 | * timestamp to string
157 | *
158 | * @param time 时间戳
159 | * @return
160 | */
161 | public static String timestamp2Str(long time) {
162 | SimpleDateFormat sdf = new SimpleDateFormat(yyyyMMddHHmmssSSS);
163 | String str = sdf.format(time);
164 | return str;
165 | }
166 |
167 | /**
168 | * 获取时间的例子
169 | */
170 | public static void example() {
171 | LocalDateTime localDateTime = LocalDateTime.now();
172 | // 获取年
173 | localDateTime.getYear();
174 | // 获取月份
175 | localDateTime.getMonth();
176 | // 获取周里的第几天
177 | localDateTime.getDayOfWeek();
178 | // 获取月里面的第几天
179 | localDateTime.getDayOfMonth();
180 | // 获取年里面的第几天
181 | localDateTime.getDayOfYear();
182 | }
183 | }
184 |
--------------------------------------------------------------------------------
/common/src/main/java/com/zyf/common/util/BigDecimalUtil.java:
--------------------------------------------------------------------------------
1 | package com.zyf.common.util;
2 |
3 | import java.math.BigDecimal;
4 | import java.util.Arrays;
5 |
6 | /**
7 | * BigDecimal工具类
8 | */
9 | public class BigDecimalUtil {
10 | public static BigDecimal add(BigDecimal a, BigDecimal b) {
11 | return a.add(b);
12 | }
13 | public static BigDecimal add(BigDecimal... a) {
14 | if (null != a) {
15 | if (0 == a.length) { return null; }
16 | BigDecimal r = a[0];
17 | for (int i = 1; i < a.length; i++) { r = add(r, a[i]); }
18 | return r;
19 | }
20 | return null;
21 | }
22 |
23 | /**
24 | * 减法
25 | * @param a
26 | * @param b
27 | * @return
28 | */
29 | public static BigDecimal sub(BigDecimal a, BigDecimal b) {
30 | return a.subtract(b);
31 | }
32 | public static BigDecimal sub(BigDecimal... a) {
33 | if (null != a) {
34 | if (0 == a.length) { return null; }
35 | BigDecimal r = a[0];
36 | for (int i = 1; i < a.length; i++) { r = sub(r, a[i]); }
37 | return r;
38 | }
39 | return null;
40 | }
41 |
42 | public static BigDecimal mul(BigDecimal a, BigDecimal b) {
43 | return a.multiply(b);
44 | }
45 | public static BigDecimal div(BigDecimal a, BigDecimal b) {
46 | return div(a, b, 8);
47 | }
48 | public static BigDecimal div(BigDecimal a, BigDecimal b, int scale) {
49 | return a.divide(b, scale, BigDecimal.ROUND_DOWN);
50 | }
51 | private static BigDecimal NEG = new BigDecimal("-1");
52 | public static BigDecimal neg(BigDecimal a) {
53 | return NEG.multiply(a);
54 | }
55 |
56 | private static Boolean exist(BigDecimal a, BigDecimal b) {
57 | if (null != a) {
58 | if (null != b) {
59 | return null;
60 | } else {
61 | return false;
62 | }
63 | } else {
64 | if (null != b) {
65 | return null;
66 | } else {
67 | return true;
68 | }
69 | }
70 | }
71 |
72 | public static boolean equal(BigDecimal a, BigDecimal b) {
73 | Boolean result = exist(a, b);
74 | return null != result ? result : 0 == a.compareTo(b);
75 | }
76 | public static boolean less(BigDecimal a, BigDecimal b) {
77 | Boolean result = exist(a, b);
78 | return null != result ? result : a.compareTo(b) < 0;
79 | }
80 | public static boolean lessOrEqual(BigDecimal a, BigDecimal b) {
81 | Boolean result = exist(a, b);
82 | return null != result ? result : a.compareTo(b) <= 0;
83 | }
84 | public static boolean greater(BigDecimal a, BigDecimal b) {
85 | Boolean result = exist(a, b);
86 | return null != result ? result : 0 < a.compareTo(b);
87 | }
88 | public static boolean greaterOrEqual(BigDecimal a, BigDecimal b) {
89 | Boolean result = exist(a, b);
90 | return null != result ? result : 0 <= a.compareTo(b);
91 | }
92 |
93 | public static BigDecimal avg(BigDecimal... num) {
94 | BigDecimal count = new BigDecimal(num.length);
95 | return div(Arrays.stream(num).reduce(BigDecimal.ZERO, BigDecimal::add), count, 16);
96 | }
97 |
98 | public static BigDecimal max(BigDecimal... num) {
99 | return Arrays.stream(num).max(BigDecimal::compareTo).get();
100 | }
101 |
102 | public static BigDecimal min(BigDecimal... num) {
103 | return Arrays.stream(num).min(BigDecimal::compareTo).get();
104 | }
105 |
106 | /**
107 | * 求余
108 | * @param dividend 被除数
109 | * @param divisor 除数
110 | * @return BigDecimal[0]:商 BigDecimal[1]:余
111 | */
112 | public static BigDecimal[] divideAndRemainder(BigDecimal dividend, BigDecimal divisor) {
113 | if (divisor == null || BigDecimal.ZERO.equals(divisor)) {
114 | return new BigDecimal[2];
115 | }
116 | return dividend.divideAndRemainder(divisor);
117 | }
118 |
119 | public static BigDecimal usdUp(BigDecimal usd) {
120 | return usd.setScale(2, BigDecimal.ROUND_UP);
121 | }
122 |
123 | public static BigDecimal usdDown(BigDecimal usd) {
124 | return usd.setScale(2, BigDecimal.ROUND_DOWN);
125 | }
126 |
127 | public static BigDecimal btcUp(BigDecimal btc) {
128 | return btc.setScale(8, BigDecimal.ROUND_UP);
129 | }
130 |
131 | public static BigDecimal btcDown(BigDecimal btc) {
132 | return btc.setScale(8, BigDecimal.ROUND_DOWN);
133 | }
134 |
135 | /**
136 | *
137 | * 判断正负,正数直接返回,负数转正数返回
138 | *
139 | * */
140 | public static BigDecimal positive_number(BigDecimal decimal){
141 | int i=decimal.compareTo(BigDecimal.ZERO);
142 | if (i>=0){
143 | return decimal;
144 | }
145 | return decimal.negate();
146 | }
147 |
148 | /**
149 | *
150 | * 判断正负,正数返true,负数返false
151 | *
152 | * */
153 | public static Boolean plus_or_minus(BigDecimal decimal){
154 | return decimal.compareTo(BigDecimal.ZERO)>= 0;
155 | }
156 |
157 | }
158 |
159 |
--------------------------------------------------------------------------------
/trade/src/main/java/com/zyf/trade/proxy/TradeExchangeProxy.java:
--------------------------------------------------------------------------------
1 | package com.zyf.trade.proxy;
2 |
3 | import com.zyf.baseservice.ITradeExchange;
4 | import com.zyf.common.model.*;
5 | import com.zyf.common.model.enums.ExchangeEnum;
6 | import com.zyf.common.model.enums.SecuritiesTypeEnum;
7 | import com.zyf.common.util.CommomUtil;
8 | import com.zyf.trade.factory.TradeExchangeFactory;
9 | import lombok.EqualsAndHashCode;
10 | import lombok.Getter;
11 | import lombok.ToString;
12 |
13 | import java.math.BigDecimal;
14 | import java.util.List;
15 | import java.util.Map;
16 |
17 | /**
18 | * 交易代理类(统一异常处理)
19 | * @author yuanfeng.z
20 | * @date 2019/7/4 11:26
21 | */
22 | @Getter
23 | @ToString
24 | @EqualsAndHashCode
25 | public class TradeExchangeProxy {
26 | /**
27 | * 交易交易所对象
28 | */
29 | private ITradeExchange tradeExchange;
30 |
31 | /**
32 | * 交易所名称
33 | */
34 | private ExchangeEnum exchangeNameEnum;
35 |
36 | /**
37 | * 交易所名称
38 | */
39 | private String exchangeName;
40 |
41 | /**
42 | * 所有币种精度
43 | */
44 | Map precisionMap;
45 |
46 | public TradeExchangeProxy(ExchangeEnum exchangeName, SecuritiesTypeEnum type, String accessKey, String secretKey) {
47 | this.tradeExchange = TradeExchangeFactory.createTradeExchange(exchangeName, type, accessKey, secretKey);
48 | this.exchangeNameEnum = exchangeName;
49 | this.exchangeName = exchangeName.getValue();
50 | }
51 |
52 | public TradeExchangeProxy(String exchangeName, String type, String accessKey, String secretKey) {
53 | this(CommomUtil.toExchangeEnum(exchangeName), CommomUtil.toSecuritiesTypeEnum(type), accessKey, secretKey);
54 | }
55 |
56 | public ITradeExchange getE() {
57 | return this.tradeExchange;
58 | }
59 |
60 | /**
61 | * 获取账户信息
62 | * @param symbol
63 | * @return
64 | */
65 | public Account getAccount(String symbol) {
66 | Account account = this.tradeExchange.getAccount(symbol);
67 | return account;
68 | }
69 |
70 | /**
71 | * 市价买入
72 | * @param symbol 币对
73 | * @param cost 费用
74 | * @return 订单id
75 | */
76 | public String buyMarket(String symbol, BigDecimal cost) {
77 | String id = this.tradeExchange.buyMarket(symbol, cost);
78 | return id;
79 | }
80 |
81 | /**
82 | * 市价卖出
83 | * @param symbol 币对
84 | * @param quantity 卖出数量
85 | * @return 订单id
86 | */
87 | public String sellMarket(String symbol, BigDecimal quantity) {
88 | String id = this.tradeExchange.sellMarket(symbol, quantity);
89 | return id;
90 | }
91 |
92 | /**
93 | * 限价买入
94 | * @param symbol 币对
95 | * @param price 价格
96 | * @param quanatity 价格
97 | * @return 订单id
98 | */
99 | public String buyLimit(String symbol, BigDecimal price, BigDecimal quanatity) {
100 | String id = this.tradeExchange.buyLimit(symbol, price, quanatity);
101 | return id;
102 | }
103 |
104 | /**
105 | * 限价卖出
106 | * @param symbol 币对
107 | * @param price 价格
108 | * @param quanatity 价格
109 | * @return 订单id
110 | */
111 | public String sellLimit(String symbol, BigDecimal price, BigDecimal quanatity) {
112 | String id = this.tradeExchange.sellLimit(symbol, price, quanatity);
113 | return id;
114 | }
115 |
116 |
117 | /**
118 | * 根据订单id撤单
119 | * @param symbol 币对
120 | * @param orderId 订单id
121 | * @return
122 | */
123 | public Boolean cancelOrder(String symbol, String orderId) {
124 | Boolean b = this.tradeExchange.cancelOrder(symbol, orderId);
125 | return b;
126 | }
127 |
128 | /**
129 | * 批量撤单
130 | * @param symbol 币对
131 | * @param ids
132 | * @return
133 | */
134 | public Boolean cancelOrders(String symbol, List ids) {
135 | Boolean b = this.tradeExchange.cancelOrders(symbol, ids);
136 | return b;
137 | }
138 |
139 | /**
140 | * 获取所有的订单
141 | * @param symbol 币对
142 | * @return 订单列表
143 | */
144 | public List getOrders(String symbol) {
145 | List orders = this.tradeExchange.getOrders(symbol);
146 | return orders;
147 | }
148 |
149 | /**
150 | * 获取指定id的订单信息
151 | * @param symbol 币对
152 | * @param orderId 订单id
153 | * @return 订单
154 | */
155 | public Order getOrder(String symbol, String orderId) {
156 | Order orders = this.tradeExchange.getOrder(symbol, orderId);
157 | return orders;
158 | }
159 |
160 | /**
161 | * 获取成交明细
162 | * @param symbol
163 | * @param orderId
164 | * @return
165 | */
166 | public List getTrade(String symbol, String orderId) {
167 | List trades = this.tradeExchange.getTrades(symbol, orderId);
168 | return trades;
169 | }
170 |
171 | /**
172 | * 获取挂单
173 | * @param symbol
174 | * @return
175 | */
176 | public List getPendingOrders(String symbol) {
177 | List pendingOrders = this.tradeExchange.getPendingOrders(symbol);
178 | return pendingOrders;
179 | }
180 |
181 | /**
182 | * 获取所有持仓
183 | * @param symbol
184 | * @return
185 | */
186 | public List getPosition(String symbol) {
187 | List positions = this.tradeExchange.getPositions(symbol);
188 | return positions;
189 | }
190 | }
191 |
--------------------------------------------------------------------------------
/common/src/main/java/com/zyf/common/model/future/BitMEXInstrument.java:
--------------------------------------------------------------------------------
1 | package com.zyf.common.model.future;
2 |
3 | import lombok.Data;
4 |
5 | import java.math.BigDecimal;
6 | import java.util.Date;
7 |
8 | @Data
9 | public class BitMEXInstrument {
10 | private String symbol; // "XBTZ14",
11 | private String rootSymbol; // "XBT",
12 | private String state; // "Settled",
13 | private String typ; // "FXXXS",
14 | private Date listing; // "2014-11-21T20; //00; //00.000Z",
15 | private Date front; // "2014-11-28T12; //00; //00.000Z",
16 | private Date expiry; // "2014-12-26T12; //00; //00.000Z",
17 | private Date settle; // "2014-12-26T12; //00; //00.000Z",
18 | private String relistInterval; // null,
19 | private String inverseLeg; // "",
20 | private String sellLeg; // "",
21 | private String buyLeg; // "",
22 | private String optionStrikePcnt; // null,
23 | private String optionStrikeRound; // null,
24 | private String optionStrikePrice; // null,
25 | private String optionMultiplier; // null,
26 | private String positionCurrency; // "",
27 | private String underlying; // "XBT",
28 | private String quoteCurrency; // "USD",
29 | private String underlyingSymbol; // "XBT=",
30 | private String reference; // "BMEX",
31 | private String referenceSymbol; // ".XBT2H",
32 | private String calcInterval; // null,
33 | private String publishInterval; // null,
34 | private String publishTime; // null,
35 | private BigDecimal maxOrderQty; // 10000000,
36 | private BigDecimal maxPrice; // 1000000,
37 | private Integer lotSize; // 1,
38 | private BigDecimal tickSize; // 0.01,
39 | private BigDecimal multiplier; // 1000,
40 | private String settlCurrency; // "XBt",
41 | private BigDecimal underlyingToPositionMultiplier; // null,
42 | private BigDecimal underlyingToSettleMultiplier; // 100000000,
43 | private BigDecimal quoteToSettleMultiplier; // null,
44 | private Boolean isQuanto; // true,
45 | private Boolean isInverse; // false,
46 | private BigDecimal initMargin; // 0.3,
47 | private BigDecimal maintMargin; // 0.2,
48 | private BigDecimal riskLimit; // 25000000000,
49 | private BigDecimal riskStep; // 5000000000,
50 | private BigDecimal limit; // 0.2,
51 | private Boolean capped; // false,
52 | private Boolean taxed; // false,
53 | private Boolean deleverage; // false,
54 | private BigDecimal makerFee; // 0.00005,
55 | private BigDecimal takerFee; // 0.00005,
56 | private BigDecimal settlementFee; // 0.00005,
57 | private BigDecimal insuranceFee; // 0.00015,
58 | private String fundingBaseSymbol; // "",
59 | private String fundingQuoteSymbol; // "",
60 | private String fundingPremiumSymbol; // "",
61 | private Date fundingTimestamp; // null,
62 | private Long fundingInterval; // null,
63 | private BigDecimal fundingRate; // null,
64 | private BigDecimal indicativeFundingRate; // null,
65 | private Long rebalanceTimestamp; // null,
66 | private BigDecimal rebalanceInterval; // null,
67 | private Date openingTimestamp; // "2014-12-26T12; //00; //00.000Z",
68 | private Date closingTimestamp; // "2014-12-26T12; //00; //00.000Z",
69 | private Date sessionInterval; // "2000-01-01T08; //00; //00.000Z",
70 | private BigDecimal prevClosePrice; // 319,
71 | private BigDecimal limitDownPrice; // 255.2,
72 | private BigDecimal limitUpPrice; // 382.8,
73 | private BigDecimal bankruptLimitDownPrice; // null,
74 | private BigDecimal bankruptLimitUpPrice; // null,
75 | private BigDecimal prevTotalVolume; // 323564,
76 | private BigDecimal totalVolume; // 348271,
77 | private BigDecimal volume; // 0,
78 | private BigDecimal volume24h; // 0,
79 | private BigDecimal prevTotalTurnover; // 0,
80 | private BigDecimal totalTurnover; // 0,
81 | private BigDecimal turnover; // 0,
82 | private BigDecimal turnover24h; // 0,
83 | private BigDecimal prevPrice24h; // 323.33,
84 | private String vwap; // null,
85 | private BigDecimal highPrice; // null,
86 | private BigDecimal lowPrice; // null,
87 | private BigDecimal lastPrice; // 323.33,
88 | private BigDecimal lastPriceProtected; // 323.33,
89 | private String lastTickDirection; // "PlusTick",
90 | private BigDecimal lastChangePcnt; // 0,
91 | private BigDecimal bidPrice; // null,
92 | private BigDecimal midPrice; // null,
93 | private BigDecimal askPrice; // null,
94 | private BigDecimal impactBidPrice; // null,
95 | private BigDecimal impactMidPrice; // null,
96 | private BigDecimal impactAskPrice; // null,
97 | private Boolean hasLiquidity; // false,
98 | private BigDecimal openInterest; // 0,
99 | private BigDecimal openValue; // 0,
100 | private String fairMethod; // "",
101 | private BigDecimal fairBasisRate; // null,
102 | private BigDecimal fairBasis; // 0,
103 | private BigDecimal fairPrice; // 323.33,
104 | private String markMethod; // "LastPrice",
105 | private BigDecimal markPrice; // 323.33,
106 | private BigDecimal indicativeTaxRate; // null,
107 | private BigDecimal indicativeSettlePrice; // 323.33,
108 | private BigDecimal optionUnderlyingPrice; // null,
109 | private BigDecimal settledPrice; // 323.33,
110 | private Date timestamp; // "2014-11-21T21; //00; //02.409Z"
111 | }
112 |
--------------------------------------------------------------------------------
/baseservice/src/main/java/com/zyf/baseservice/util/okex/OkexSignUtil.java:
--------------------------------------------------------------------------------
1 | package com.zyf.baseservice.util.okex;
2 |
3 | import okhttp3.OkHttpClient;
4 | import okhttp3.Request;
5 | import okhttp3.Response;
6 |
7 | import javax.crypto.Mac;
8 | import javax.crypto.spec.SecretKeySpec;
9 | import java.io.IOException;
10 | import java.io.UnsupportedEncodingException;
11 | import java.net.URLDecoder;
12 | import java.net.URLEncoder;
13 | import java.security.InvalidKeyException;
14 | import java.security.NoSuchAlgorithmException;
15 | import java.text.SimpleDateFormat;
16 | import java.util.*;
17 |
18 | /**
19 | * okex签名加密工具类
20 | * @author yuanfeng.z
21 | * @date 2019/6/28 9:30
22 | */
23 | public class OkexSignUtil {
24 |
25 | /**
26 | * 字符编码
27 | */
28 | public final static String INPUT_CHARSET = "UTF-8";
29 | /**
30 | * 加密方法
31 | */
32 | private static final String SIGNATURE_METHOD = "HmacSHA256";
33 | /**
34 | * 超时时间
35 | */
36 | private final static int TIME_OUT = 30 * 60 * 1000;
37 |
38 |
39 | /**
40 | * url编码
41 | *
42 | * @param content
43 | * @param charset
44 | * @return
45 | */
46 | public static String urlEncoded(String content, String charset) {
47 | try {
48 | return URLEncoder.encode(content, charset);
49 | } catch (UnsupportedEncodingException e) {
50 | throw new RuntimeException("指定的编码集不对,您目前指定的编码集是:" + charset);
51 | }
52 | }
53 |
54 | public static String urlEncoded(String content) {
55 | try {
56 | return URLEncoder.encode(content, OkexSignUtil.INPUT_CHARSET);
57 | } catch (UnsupportedEncodingException e) {
58 | throw new RuntimeException("指定的编码集不对,您目前指定的编码集是:" + OkexSignUtil.INPUT_CHARSET);
59 | }
60 | }
61 |
62 | /**
63 | * url解码
64 | *
65 | * @param content
66 | * @param charset
67 | * @return
68 | */
69 | public static String urlDecoded(String content, String charset) {
70 | try {
71 | return URLDecoder.decode(content, charset);
72 | } catch (UnsupportedEncodingException e){
73 | throw new RuntimeException("指定的编码集不对,您目前指定的编码集是:" + charset);
74 | }
75 | }
76 |
77 | public static String urlDecoded(String content) {
78 | try {
79 | return URLDecoder.decode(content, OkexSignUtil.INPUT_CHARSET);
80 | } catch (UnsupportedEncodingException e){
81 | throw new RuntimeException("指定的编码集不对,您目前指定的编码集是:" + OkexSignUtil.INPUT_CHARSET);
82 | }
83 | }
84 |
85 | /**
86 | * 签名
87 | *
88 | * @param method 请求类型
89 | * @param address ip地址
90 | * @param resourcePath 资源路径
91 | * @param body 请求参数
92 | * @param apiKey 密钥
93 | * @param secretKey 私钥
94 | * @param passPhrase 密码
95 | * @return
96 | */
97 | public static LinkedHashMap sign(String method, String address, LinkedHashMap body, String resourcePath, String apiKey, String secretKey, String passPhrase) {
98 |
99 | String epoch = formatEpoch(System.currentTimeMillis());
100 |
101 | StringBuilder s = new StringBuilder();
102 | s.append(epoch).append(method).append(resourcePath).append(body != null ? OkexUtil.addParams(body) : "");
103 | String sign = hmacSHA256(s.toString(), secretKey);
104 |
105 | LinkedHashMap lh = new LinkedHashMap();
106 | lh.put("OK-ACCESS-KEY", apiKey);
107 | lh.put("OK-ACCESS-SIGN", sign);
108 | lh.put("OK-ACCESS-TIMESTAMP", epoch);
109 | lh.put("OK-ACCESS-PASSPHRASE", passPhrase);
110 | lh.put("x-simulated-trading", "1");
111 |
112 | return lh;
113 | }
114 |
115 | public static String formatEpoch(Long time) {
116 | if (null == time) {
117 | return "";
118 | }
119 | return String.format("%s.%03d", time / 1000, time % 1000);
120 | }
121 |
122 |
123 | /**
124 | * HmacSHA256 加密
125 | *
126 | * @param msg 加密内容
127 | * @param secretKey 私钥
128 | */
129 | public static String hmacSHA256(String msg, String secretKey) {
130 | try {
131 | byte [] sign = OkexSignUtil.hmac(msg.getBytes(), secretKey, SIGNATURE_METHOD);
132 | return Base64.getEncoder().encodeToString(sign);
133 | } catch (Exception e) {
134 | System.out.println("Error:"+e.getStackTrace());
135 | }
136 | return null;
137 | }
138 |
139 | public static byte[] hmac(byte[] message, String key, String algorithm)
140 | throws NoSuchAlgorithmException, InvalidKeyException {
141 | Objects.requireNonNull(message, "message");
142 | SecretKeySpec signingKey = new SecretKeySpec(key.getBytes(), algorithm);
143 | Mac mac = Mac.getInstance(algorithm);
144 | mac.init(signingKey);
145 | return mac.doFinal(message);
146 | }
147 |
148 | /**
149 | * 获取UTC时间
150 | * @param delay 延迟
151 | * @return UTC时间
152 | */
153 | private static SimpleDateFormat sdf = new SimpleDateFormat("YYYY-MM-dd'T'HH:mm:ss");
154 | private static Date getUTCTimeString() {
155 | Calendar cal = Calendar.getInstance();
156 | int zoneOffset = cal.get(Calendar.ZONE_OFFSET);
157 | int dstOffset = cal.get(Calendar.DST_OFFSET);
158 | cal.add(Calendar.MILLISECOND, -(zoneOffset + dstOffset));
159 | return new Date(cal.getTime().getTime());
160 | }
161 |
162 |
163 | public static void main(String[] args) {
164 |
165 | String appKey = "xx-xx-x-x-x";
166 | String secret = "xx";
167 | String address = "https://www.okex.com";
168 | String passPrase = "123456mzy";
169 | String body = null;
170 | String resouecePath = "/api/spot/v3/accounts/btc";
171 | String method = "GET";
172 |
173 | LinkedHashMap lh = OkexSignUtil.sign(method, address, null, resouecePath, appKey, secret, passPrase);
174 |
175 | OkHttpClient client = new OkHttpClient();
176 | Request request = new Request.Builder()
177 | .url(address + resouecePath)
178 | .get()
179 | .addHeader("OK-ACCESS-KEY", lh.get("OK-ACCESS-KEY"))
180 | .addHeader("OK-ACCESS-SIGN", lh.get("OK-ACCESS-SIGN"))
181 | .addHeader("OK-ACCESS-TIMESTAMP", lh.get("OK-ACCESS-TIMESTAMP"))
182 | .addHeader("OK-ACCESS-PASSPHRASE", lh.get("OK-ACCESS-PASSPHRASE"))
183 | .build();
184 |
185 | try (Response response = client.newCall(request).execute()) {
186 | System.out.println(response.body().string());
187 | } catch (IOException e) {
188 | e.printStackTrace();
189 | }
190 |
191 | }
192 |
193 |
194 | }
195 |
--------------------------------------------------------------------------------