Administrator
2025-12-17 fa7d25e98db0e6cb763d304b95e6a943f43ac240
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
package com.xcong.excoin.modules.okxNewPrice.jiaoyi;
 
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xcong.excoin.modules.okxNewPrice.okxpi.MallUtils;
import com.xcong.excoin.modules.okxNewPrice.okxpi.config.Dto.QuantApiMessage;
import com.xcong.excoin.modules.okxNewPrice.okxpi.config.OKXAccount;
import com.xcong.excoin.modules.okxNewPrice.okxpi.enumerates.TradeTypeEnum;
import com.xcong.excoin.modules.okxNewPrice.okxpi.trade.TradeEventEnum;
import com.xcong.excoin.modules.okxNewPrice.okxpi.trade.TradeEventRunner;
import com.xcong.excoin.modules.okxNewPrice.okxpi.trade.TradeRequestBuy;
import com.xcong.excoin.modules.okxNewPrice.okxpi.trade.TradeRequestSell;
import com.xcong.excoin.modules.okxNewPrice.okxpi.verify.VerifyAccountFactory;
import com.xcong.excoin.modules.okxNewPrice.zhanghu.IApiMessageService;
import com.xcong.excoin.modules.okxNewPrice.zhanghu.ZhangHuEnum;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
 
import java.math.BigDecimal;
import java.util.LinkedHashMap;
 
/**
 * @author Administrator
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class IMQServiceImpl implements IMQService{
 
    private final IApiMessageService apiMessageService;
 
    private final VerifyAccountFactory verifyAccountFactory;
    @Override
    public void operationBuyMsg(TradeRequestBuy returnVo) {
 
        log.info("买入入参:{}", JSON.toJSONString(returnVo));
        /**
         * 1、获取用户的策略信息
         * 2、quant_operate_recode 记录表新增一条记录,finish_status 为1.未完成
         * 3、发起OKX接口调用
         */
        QuantApiMessage quantApiMessage = apiMessageService.getApiMessage(ZhangHuEnum.JIAOYISUO.getValue());
        if(ObjectUtil.isEmpty(quantApiMessage)){
            return;
        }
 
        OKXAccount okxAccount = (OKXAccount) verifyAccountFactory.getAccountMap()
                .get(quantApiMessage.getExchange())
                .initAccount(quantApiMessage);
        if(ObjectUtil.isEmpty(okxAccount)){
            return;
        }
 
        LinkedHashMap<String, Object> requestParam = new LinkedHashMap<>();
        requestParam.put("instId", returnVo.getInstId()+"-SWAP");
        /**
         * 订单方向
         * buy:买, sell:卖
         */
        requestParam.put("side", TradeTypeEnum.BUY.getValue());
        /**
         * 订单类型
         * market:市价单
         * limit:限价单
         * post_only:只做maker单
         * fok:全部成交或立即取消
         * ioc:立即成交并取消剩余
         * optimal_limit_ioc:市价委托立即成交并取消剩余(仅适用交割、永续)
         * mmp:做市商保护(仅适用于组合保证金账户模式下的期权订单)
         * mmp_and_post_only:做市商保护且只做maker单(仅适用于组合保证金账户模式下的期权订单)
         */
        String type = (BigDecimal.ZERO.compareTo(new BigDecimal(returnVo.getLimitPrice())) == 0) ? TradeTypeEnum.MARKET.getValue() : TradeTypeEnum.LIMIT.getValue();
        requestParam.put("ordType", type);
        if (TradeTypeEnum.LIMIT.getValue().equals(type)) {
            requestParam.put("px", returnVo.getLimitPrice());
            requestParam.put("ordType", TradeTypeEnum.LIMIT.getValue());
        }
        /**
         * 持仓方向
         * 在开平仓模式下必填,且仅可选择 long 或 short。 仅适用交割、永续。
         */
        String positionSide = (TradeTypeEnum.LONG.getCode() == returnVo.getPositionSide()) ? TradeTypeEnum.LONG.getValue() : TradeTypeEnum.SHORT.getValue();
        requestParam.put("posSide", positionSide);
        /**
         * 交易模式
         * 保证金模式:isolated:逐仓 ;cross:全仓
         * 非保证金模式:cash:非保证金
         * spot_isolated:现货逐仓(仅适用于现货带单) ,现货带单时,tdMode 的值需要指定为spot_isolated
         */
        String tdMode = (TradeTypeEnum.ISOLATED.getCode() == returnVo.getTdMode()) ? TradeTypeEnum.ISOLATED.getValue() : TradeTypeEnum.CROSS.getValue();
        requestParam.put("tdMode", tdMode);
        /**
         * 委托数量
         */
        requestParam.put("sz", returnVo.getTradeCnt());
        /**
         * 客户自定义订单ID
         * 字母(区分大小写)与数字的组合,可以是纯字母、纯数字且长度要在1-32位之间。
         */
        String clOrdId = MallUtils.getOrderNum();
        requestParam.put("clOrdId", clOrdId);
 
        String placeOrderRspOkxRestResponse = TradeEventRunner.runTradeEvent(TradeEventEnum.TRADE_BUY.getEventPoint(),requestParam,okxAccount);
        log.info("下买单结果成功:{}", placeOrderRspOkxRestResponse);
        log.info("消费成功:{}", JSONUtil.parseObj(returnVo));
    }
 
    @Override
    public void operationSellMsg(TradeRequestSell returnVo) {
        /**
         * 1、获取用户的策略信息
         * 2、quant_operate_recode 记录表新增一条记录,finish_status 为1.未完成
         * 3、发起OKX接口调用
         */
        QuantApiMessage quantApiMessage = apiMessageService.getApiMessage(ZhangHuEnum.JIAOYISUO.getValue());
        if(ObjectUtil.isEmpty(quantApiMessage)){
            return;
        }
 
        OKXAccount okxAccount = (OKXAccount) verifyAccountFactory.getAccountMap()
                .get(quantApiMessage.getExchange())
                .initAccount(quantApiMessage);
        if(ObjectUtil.isEmpty(okxAccount)){
            return;
        }
        LinkedHashMap<String, Object> requestParam = new LinkedHashMap<>();
 
        requestParam.put("instId", returnVo.getInstId()+"-SWAP");
        /**
         * 订单方向
         * buy:买, sell:卖
         */
        requestParam.put("side", TradeTypeEnum.SELL.getValue());
        /**
         * 订单类型
         * market:市价单
         * limit:限价单
         * post_only:只做maker单
         * fok:全部成交或立即取消
         * ioc:立即成交并取消剩余
         * optimal_limit_ioc:市价委托立即成交并取消剩余(仅适用交割、永续)
         * mmp:做市商保护(仅适用于组合保证金账户模式下的期权订单)
         * mmp_and_post_only:做市商保护且只做maker单(仅适用于组合保证金账户模式下的期权订单)
         */
        String type = (BigDecimal.ZERO.compareTo(new BigDecimal(returnVo.getLimitPrice())) == 0) ? TradeTypeEnum.MARKET.getValue() : TradeTypeEnum.LIMIT.getValue();
        requestParam.put("ordType", type);
        if (TradeTypeEnum.LIMIT.getValue().equals(type)) {
            requestParam.put("px", returnVo.getLimitPrice());
            requestParam.put("ordType", TradeTypeEnum.LIMIT.getValue());
        }
        /**
         * 持仓方向
         * 在开平仓模式下必填,且仅可选择 long 或 short。 仅适用交割、永续。
         */
        String positionSide = (TradeTypeEnum.LONG.getCode() == returnVo.getPositionSide()) ? TradeTypeEnum.LONG.getValue() : TradeTypeEnum.SHORT.getValue();
        requestParam.put("posSide", positionSide);
        /**
         * 交易模式
         * 保证金模式:isolated:逐仓 ;cross:全仓
         * 非保证金模式:cash:非保证金
         * spot_isolated:现货逐仓(仅适用于现货带单) ,现货带单时,tdMode 的值需要指定为spot_isolated
         */
        String tdMode = (TradeTypeEnum.ISOLATED.getCode() == returnVo.getTdMode()) ? TradeTypeEnum.ISOLATED.getValue() : TradeTypeEnum.CROSS.getValue();
        requestParam.put("tdMode", tdMode);
        /**
         * 委托数量
         */
        requestParam.put("sz", returnVo.getTradeCnt());
        /**
         * 客户自定义订单ID
         * 字母(区分大小写)与数字的组合,可以是纯字母、纯数字且长度要在1-32位之间。
         */
        String clOrdId = MallUtils.getOrderNum();
        requestParam.put("clOrdId", clOrdId);
 
 
        String placeOrderRspOkxRestResponse = TradeEventRunner.runTradeEvent(TradeEventEnum.TRADE_SELL.getEventPoint(), requestParam, okxAccount);
 
        String code = JSON.parseObject(placeOrderRspOkxRestResponse).get("code").toString();
        if("1".equals(code)){
            String data = JSON.parseObject(placeOrderRspOkxRestResponse).get("data").toString();
 
            JSONArray jsonArray = JSON.parseArray(data);
            JSONObject jsonObject = jsonArray.getJSONObject(0);
 
            String sCode = jsonObject.getString("sCode");
            if("51169".equals(sCode)){
                log.warn("平仓下单返回结果-失败:{}", data);
            }
        }
        log.info("平仓下单返回结果:{}", placeOrderRspOkxRestResponse);
        log.info("消费成功:{}", JSONUtil.parseObj(returnVo));
    }
}