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 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 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)); } }