需求描述:按交易员分组、按合约交易对分组组装数据
数据结构
/**
* 跟单信息
*/
public class TraceOrderInfoVo implements Serializable, IProductSort{
/**
* 交易员ID
*/
private String traderUserId;
/**
* 交易员名称
*/
private String traderName;
/**
* 交易对
*/
private String productCode;
/**
* 交易名称
*/
private String productName;
/**
* 币对
*/
private String symbolId;
/**
* 交易对信息
*/
private List<TradingDetailsVo> tradingDetailsVos;
@Override
public String getSort() {
return traderUserId;
}
}
-----------------------------------------------------------
/**
* 合约交易对信息
* @author xsh
*/
public class TradingDetailsVo implements Serializable, IProductSort {
/**
* 交易对
*/
private String productCode;
/**
* 交易名称
*/
private String productName;
/**
* 交易员ID
*/
private String traderUserId;
/**
* 币对
*/
private String symbolId;
/**
* 保证金信息
*/
private List<MarginDetailsVo> marginDetailsVos;
@Override
public String getSort() {
return productCode;
}
}
----------------------------------------------------------
/**
* 保证金信息
*/
public class MarginDetailsVo implements Serializable, IProductSort{
/**
* 资产id,保证金
*/
private String tokenId;
/**
* 币对
*/
private String symbolId;
/**
* 最大跟随持仓张数
*/
private BigDecimal maxFollowCount = BigDecimal.ZERO;
/**
* 剩余跟随额度
*/
private String sumOpenMarginCount;
/**
* 交易员ID
*/
private String traderUserId;
/**
* 交易员名称
*/
private String traderName;
/**
* 交易对
*/
private String productCode;
/**
* 交易名称
*/
private String productName;
/**
* id
*/
private String id;
@Override
public String getSort() {
return productCode;
}
}
返回json串示例
{
"code": "00000",
"data": [
{
"productCode": "BTCUSD",
"productName": null,
"sort": "3092137847",
"symbolId": null,
"traderName": "跟跟跟,梭哈!!",
"traderUserId": "3092137847",
"tradingDetailsVos": [
{
"marginDetailsVos": [
{
"id": null,
"maxFollowCount": "20000",
"productCode": "ETHUSDT",
"productName": null,
"sort": "ETHUSDT",
"sumOpenMarginCount": "20000",
"symbolId": "ETHUSDT_UMCBL",
"tokenId": "USDT",
"traderName": null,
"traderUserId": "3092137847"
}
],
"productCode": "ETHUSDT",
"productName": null,
"sort": "ETHUSDT",
"symbolId": "ETHUSDT_UMCBL",
"traderUserId": "3092137847"
},
{
"marginDetailsVos": [
{
"id": null,
"maxFollowCount": "20000",
"productCode": "BTCUSD",
"productName": null,
"sort": "BTCUSD",
"sumOpenMarginCount": "18908",
"symbolId": "BTCUSD_DMCBL",
"tokenId": "BTC",
"traderName": null,
"traderUserId": "3092137847"
}
],
"productCode": "BTCUSD",
"productName": null,
"sort": "BTCUSD",
"symbolId": "BTCUSD_DMCBL",
"traderUserId": "3092137847"
},
{
"marginDetailsVos": [
{
"id": null,
"maxFollowCount": "20000",
"productCode": "BTCUSDT",
"productName": null,
"sort": "BTCUSDT",
"sumOpenMarginCount": "20000",
"symbolId": "BTCUSDT_UMCBL",
"tokenId": "USDT",
"traderName": null,
"traderUserId": "3092137847"
}
],
"productCode": "BTCUSDT",
"productName": null,
"sort": "BTCUSDT",
"symbolId": "BTCUSDT_UMCBL",
"traderUserId": "3092137847"
}
]
},
{
"productCode": "BTCUSD",
"productName": null,
"sort": "6438781764",
"symbolId": null,
"traderName": "999888****",
"traderUserId": "6438781764",
"tradingDetailsVos": [
{
"marginDetailsVos": [
{
"id": null,
"maxFollowCount": "30000",
"productCode": "BTCUSD",
"productName": null,
"sort": "BTCUSD",
"sumOpenMarginCount": "30000",
"symbolId": "BTCUSD_DMCBL",
"tokenId": "BTC",
"traderName": null,
"traderUserId": "6438781764"
},
{
"id": null,
"maxFollowCount": "30000",
"productCode": "BTCUSD",
"productName": null,
"sort": "BTCUSD",
"sumOpenMarginCount": "30000",
"symbolId": "BTCUSD_DMCBL",
"tokenId": "ETH",
"traderName": null,
"traderUserId": "6438781764"
}
],
"productCode": "BTCUSD",
"productName": null,
"sort": "BTCUSD",
"symbolId": "BTCUSD_DMCBL",
"traderUserId": "6438781764"
},
{
"marginDetailsVos": [
{
"id": null,
"maxFollowCount": "30000",
"productCode": "BTCUSDT",
"productName": null,
"sort": "BTCUSDT",
"sumOpenMarginCount": "30000",
"symbolId": "BTCUSDT_UMCBL",
"tokenId": "USDT",
"traderName": null,
"traderUserId": "6438781764"
}
],
"productCode": "BTCUSDT",
"productName": null,
"sort": "BTCUSDT",
"symbolId": "BTCUSDT_UMCBL",
"traderUserId": "6438781764"
}
]
}
],
"msg": "success"
}
代码
public List<TraceOrderInfoVo> getInfoList(Long userId, LanguageTypeEnum languageType) {
List<TraceOrderInfoVo> traceOrderInfoVos = new ArrayList<>();
List<MarginDetailsVo> marginDetailsVos = new ArrayList<>();
List<TraceUserConfig> list = traceUserConfigRepository.getInfoList(userId);
if (CollectionUtils.isEmpty(list)) {
return traceOrderInfoVos;
}
//查询保证金
for (TraceUserConfig traceUserConfig : list) {
List<com.upex.trigger.common.domain.shard.ContractTrackingOrder> contractTrackingOrderList = getSymbolId(traceUserConfig);
if (CollectionUtils.isEmpty(contractTrackingOrderList)) {
BusinessSymbol businessSymbol = MixContractConfigUtils.getBusinessSymbol(traceUserConfig.getSymbolId());
List<String> supportMarginTokenIds = businessSymbol.getSupportMarginTokenIds();
supportMarginTokenIds.forEach(token -> {
marginDetailsVos.add(MarginDetailsVo.builder().traderUserId(traceUserConfig.getTraderUserId().toString()).symbolId(traceUserConfig.getSymbolId())
.maxFollowCount(new BigDecimal(traceUserConfig.getMaxFollowCount()))
.productCode(MixContractConfigUtils.getBusinessSymbol(traceUserConfig.getSymbolId()) == null ? null : MixContractConfigUtils.getBusinessSymbol(traceUserConfig.getSymbolId()).getSymbolDisplayName())
.tokenId(token)
.sumOpenMarginCount(traceUserConfig.getMaxFollowCount().toString())
.build());
});
continue;
}
for (com.upex.trigger.common.domain.shard.ContractTrackingOrder contractTrackingOrder : contractTrackingOrderList) {
MarginDetailsVo marginDetailsVo = new MarginDetailsVo();
marginDetailsVo.setTraderUserId(contractTrackingOrder.getTraderUserId().toString());
marginDetailsVo.setTokenId(contractTrackingOrder.getTokenId());
marginDetailsVo.setSymbolId(contractTrackingOrder.getSymbolId());
marginDetailsVo.setMaxFollowCount(new BigDecimal(traceUserConfig.getMaxFollowCount()));
marginDetailsVo.setProductCode(MixContractConfigUtils.getBusinessSymbol(contractTrackingOrder.getSymbolId()) == null ? null : MixContractConfigUtils.getBusinessSymbol(contractTrackingOrder.getSymbolId()).getSymbolDisplayName());
marginDetailsVo.setId(contractTrackingOrder.getId().toString());
marginDetailsVos.add(marginDetailsVo);
}
}
if (CollectionUtils.isEmpty(marginDetailsVos)) {
return traceOrderInfoVos;
}
List<MarginDetailsVo> marginDetailsVoList = ProductCodeSortUtils.sortSymbolIdByApollo
(marginDetailsVos.stream().map(marginDetailsVo -> MarginDetailsVo.builder()
.productCode(marginDetailsVo.getProductCode())
.productName(MixContractConfigUtils.getBusinessSymbol(marginDetailsVo.getProductCode()) == null ? null : MixContractConfigUtils.getBusinessSymbol(marginDetailsVo.getProductCode()).getSymbolDisplayName())
.maxFollowCount(marginDetailsVo.getMaxFollowCount())
.symbolId(marginDetailsVo.getSymbolId())
.traderUserId(marginDetailsVo.getTraderUserId())
.tokenId(marginDetailsVo.getTokenId())
.sumOpenMarginCount(marginDetailsVo.getSumOpenMarginCount() == null ? null : marginDetailsVo.getSumOpenMarginCount())
.build()).collect(Collectors.toList()));
List<Integer> languageTypeOrder = traderInfoService.getLanguageTypeOrder(languageType);
// 按交易员分组,补交易员姓名
Map<String, TraceOrderInfoVo> tradersMap = Maps.newHashMap();
for (MarginDetailsVo marginDetailsVo : marginDetailsVoList) {
TraceOrderInfoVo traceOrderInfoVo = new TraceOrderInfoVo();
if ((traceOrderInfoVo = tradersMap.get(marginDetailsVo.getTraderUserId())) == null) {
TraceUser traceUser = traceUserService.getTraceUserByUserId(Long.parseLong(marginDetailsVo.getTraderUserId()));
traceOrderInfoVo = TraceOrderInfoVo.builder()
.traderUserId(marginDetailsVo.getTraderUserId())
.traderName(traderInfoService.getNickNameByLanguageType(traceUser.getUserId(), traceUser.getNickName(), traceUser.getIsDefaultNickname(), languageTypeOrder))
.productName(marginDetailsVo.getProductName())
.productCode(marginDetailsVo.getProductCode())
.build();
tradersMap.put(traceOrderInfoVo.getTraderUserId(), traceOrderInfoVo);
continue;
}
}
List<TraceOrderInfoVo> tradersList = Lists.newArrayList(tradersMap.values());
// 按照交易对分组
Map<String, TraceOrderInfoVo> newTradersMap = Maps.newHashMap();
for (TraceOrderInfoVo traceOrderInfoVo : tradersList) {
Map<String, TradingDetailsVo> tradingMap = Maps.newHashMap();
for (MarginDetailsVo marginDetailsVo : marginDetailsVoList) {
if (traceOrderInfoVo.getTraderUserId().equals(marginDetailsVo.getTraderUserId())) {
TradingDetailsVo tradingDetailsVo = new TradingDetailsVo();
if ((tradingDetailsVo = tradingMap.get(marginDetailsVo.getSymbolId())) == null) {
tradingDetailsVo = TradingDetailsVo.builder()
.traderUserId(marginDetailsVo.getTraderUserId())
.symbolId(marginDetailsVo.getSymbolId())
.productName(marginDetailsVo.getProductName())
.productCode(marginDetailsVo.getProductCode())
.symbolId(marginDetailsVo.getSymbolId())
.marginDetailsVos(Lists.newArrayList())
.build();
tradingMap.put(tradingDetailsVo.getSymbolId(), tradingDetailsVo);
}
}
}
tradersMap.put(traceOrderInfoVo.getTraderUserId(), TraceOrderInfoVo.builder()
.traderUserId(traceOrderInfoVo.getTraderUserId())
.traderName(traceOrderInfoVo.getTraderName())
.productCode(traceOrderInfoVo.getProductCode())
.productName(traceOrderInfoVo.getProductName())
.symbolId(traceOrderInfoVo.getSymbolId())
.tradingDetailsVos(Lists.newArrayList(tradingMap.values()))
.build());
}
List<TraceOrderInfoVo> tradingList = Lists.newArrayList(tradersMap.values());
log.info("tradingList = {},marginDetailsVoList={}",JSON.toJSONString(tradingList),JSON.toJSONString(marginDetailsVoList));
// 按保证金分组,并计算剩余额度
Map<String, TraceOrderInfoVo> map = Maps.newHashMap();
for (TraceOrderInfoVo traceOrderInfoVo : tradingList) {
Map<String, TradingDetailsVo> tradingMap = Maps.newHashMap();
for (TradingDetailsVo tradingDetailsVo : traceOrderInfoVo.getTradingDetailsVos()) {
Map<String, MarginDetailsVo> marginMap = Maps.newHashMap();
if (traceOrderInfoVo.getTraderUserId().equals(tradingDetailsVo.getTraderUserId())) {
for (MarginDetailsVo marginDetailsVo : marginDetailsVoList) {
if (tradingDetailsVo.getSymbolId().equals(marginDetailsVo.getSymbolId()) && tradingDetailsVo.getTraderUserId().equals(marginDetailsVo.getTraderUserId())) {
MarginDetailsVo detailsVo = new MarginDetailsVo();
if ((detailsVo = marginMap.get(marginDetailsVo.getTokenId())) == null) {
BigDecimal rate = getRate(marginDetailsVo.getTokenId()).getMarkPrice();
BigDecimal sum = getSumOpenMarginCount(TraceUserConfig.builder()
.traderUserId(Long.parseLong(marginDetailsVo.getTraderUserId()))
.symbolId(marginDetailsVo.getSymbolId())
.tokenId(marginDetailsVo.getTokenId())
.userId(userId)
.build());
BigDecimal total = marginDetailsVo.getMaxFollowCount().subtract(rate.multiply(sum));
log.info("sum={},total={},sumOpenMarginCount={}",sum,total,marginDetailsVo.getSumOpenMarginCount());
detailsVo = MarginDetailsVo.builder()
.sumOpenMarginCount(marginDetailsVo.getSumOpenMarginCount() != null ? marginDetailsVo.getMaxFollowCount().setScale(0, BigDecimal.ROUND_DOWN).toPlainString() : total.setScale(0, BigDecimal.ROUND_DOWN).toPlainString())
.tokenId(marginDetailsVo.getTokenId())
.productCode(marginDetailsVo.getProductCode())
.maxFollowCount(marginDetailsVo.getMaxFollowCount())
.symbolId(marginDetailsVo.getSymbolId())
.traderUserId(marginDetailsVo.getTraderUserId())
.productName(marginDetailsVo.getProductName())
.traderName(marginDetailsVo.getTraderName())
.build();
marginMap.put(marginDetailsVo.getTokenId(), detailsVo);
}
tradingDetailsVo.getMarginDetailsVos().add(detailsVo);
}
}
tradingMap.put(tradingDetailsVo.getSymbolId(), TradingDetailsVo.builder()
.traderUserId(tradingDetailsVo.getTraderUserId())
.symbolId(tradingDetailsVo.getSymbolId())
.productName(tradingDetailsVo.getProductName())
.productCode(tradingDetailsVo.getProductCode())
.symbolId(tradingDetailsVo.getSymbolId())
.marginDetailsVos(Lists.newArrayList(marginMap.values()))
.build());
}
}
map.put(traceOrderInfoVo.getTraderUserId(), TraceOrderInfoVo.builder()
.traderUserId(traceOrderInfoVo.getTraderUserId())
.traderName(traceOrderInfoVo.getTraderName())
.productCode(traceOrderInfoVo.getProductCode())
.productName(traceOrderInfoVo.getProductName())
.symbolId(traceOrderInfoVo.getSymbolId())
.tradingDetailsVos(Lists.newArrayList(tradingMap.values()))
.build());
}
List<TraceOrderInfoVo> allList = Lists.newArrayList(map.values());
return allList;
}
代码质量不行,欢迎提出代码修改意见