Administrator
2025-12-16 2ae35ac760cd96f54c62323e476776267bd09f47
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
package com.xcong.excoin.modules.okxNewPrice.okxWs.wanggeList;
 
import com.xcong.excoin.rabbit.pricequeue.AscBigDecimal;
import com.xcong.excoin.rabbit.pricequeue.DescBigDecimal;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
 
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.concurrent.PriorityBlockingQueue;
 
/**
 * 网格交易服务实现类,用于初始化价格网格、开仓和平仓操作。
 *
 * @author Administrator
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class WangGeListServiceImpl implements WangGeListService {
 
    /**
     * 初始化价格网格队列。根据配置的价格上限、下限和间隔生成一系列价格点,
     * 并将这些价格点存入升序优先阻塞队列中。
     *
     * @return 返回初始化完成的升序价格队列;若初始化失败则返回null
     */
    @Override
    public PriorityBlockingQueue<AscBigDecimal> initWangGe(String markPx) {
        log.info("网格初始化中");
        PriorityBlockingQueue<AscBigDecimal> queueAsc = WangGeListQueue.getQueueAsc();
        queueAsc.clear();
 
        //获取WangGeListEnum全部网格参数
        WangGeListEnum gridByPrice = WangGeListEnum.getGridByPrice(new BigDecimal(markPx));
        if (gridByPrice == null){
            log.error("没有获取到网格参数......");
            return null;
        }
 
        String shangxianValue = gridByPrice.getJiage_shangxian();
        String xiaxianValue = gridByPrice.getJiage_xiaxian();
        String jianjuValue = gridByPrice.getJian_ju();
        String weishuValueStr = gridByPrice.getXiaoshu_weishu();
 
        try {
            BigDecimal shangxian = new BigDecimal(shangxianValue);
            BigDecimal xiaxian = new BigDecimal(xiaxianValue);
            BigDecimal jianju = new BigDecimal(jianjuValue);
 
            if (jianju.compareTo(BigDecimal.ZERO) == 0) {
                log.error("价格间隔不能为0");
                return null;
            }
 
            int weishu = Integer.parseInt(weishuValueStr);
            BigDecimal diff = shangxian.subtract(xiaxian);
            int count = diff.divide(jianju, 0, RoundingMode.DOWN).intValue();
 
            BigDecimal currentStep = BigDecimal.ZERO;
            for (int i = 0; i <= count; i++) {
                BigDecimal stepMultiplier = currentStep.multiply(jianju);
                BigDecimal wangGeJiaGe = xiaxian.add(stepMultiplier).setScale(weishu, RoundingMode.DOWN);
                AscBigDecimal ascBigDecimal = new AscBigDecimal(wangGeJiaGe.toString());
                queueAsc.add(ascBigDecimal);
                currentStep = currentStep.add(BigDecimal.ONE);
            }
 
            if (queueAsc.isEmpty()) {
                log.info("网格初始化失败");
                return null;
            }
 
            log.info("网格初始化成功");
            return queueAsc;
        } catch (NumberFormatException e) {
            log.error("解析价格参数失败", e);
            return null;
        } catch (Exception e) {
            log.error("初始化网格发生未知异常", e);
            return null;
        }
    }
 
    /**
     * 根据当前价格初始化开仓队列。遍历已有的升序价格队列,
     * 将小于当前价格的所有价格点加入降序的开仓队列中。
     *
     * @param jiaGe   当前价格
     * @param queueAsc 已初始化的价格升序队列
     */
    @Override
    public PriorityBlockingQueue<DescBigDecimal> initKaiCang(BigDecimal jiaGe, PriorityBlockingQueue<AscBigDecimal> queueAsc) {
        PriorityBlockingQueue<DescBigDecimal> queueKaiCang = WangGeListQueue.getKaiCang();
        queueKaiCang.clear();
 
        AscBigDecimal now = new AscBigDecimal(jiaGe.toString());
 
        for (AscBigDecimal ascBigDecimal : queueAsc) {
            if (ascBigDecimal.compareTo(now) < 0) {
                DescBigDecimal kaiCangJia = new DescBigDecimal(ascBigDecimal.getValue().toString());
                queueKaiCang.add(kaiCangJia);
            }
        }
        StringBuilder kaiCangStr = new StringBuilder();
        kaiCangStr.append("队列: [");
        boolean first = true;
        for (DescBigDecimal item : queueKaiCang) {
            if (!first) {
                kaiCangStr.append(", ");
            }
            kaiCangStr.append(item.getValue());
            first = false;
        }
        kaiCangStr.append("]");
        log.info(kaiCangStr.toString());
 
        return queueKaiCang;
    }
 
    /**
     * 根据当前价格初始化平仓队列。遍历已有的升序价格队列,
     * 将大于当前价格的所有价格点加入升序的平仓队列中。
     *
     * @param jiaGe   当前价格
     * @param queueAsc 已初始化的价格升序队列
     */
    @Override
    public PriorityBlockingQueue<AscBigDecimal> initPingCang(BigDecimal jiaGe, PriorityBlockingQueue<AscBigDecimal> queueAsc) {
        PriorityBlockingQueue<AscBigDecimal> queuePingCang = WangGeListQueue.getPingCang();
        queuePingCang.clear();
 
        AscBigDecimal now = new AscBigDecimal(jiaGe.toString());
 
        for (AscBigDecimal ascBigDecimal : queueAsc) {
            if (ascBigDecimal.compareTo(now) > 0) {
                queuePingCang.add(ascBigDecimal);
            }
        }
 
        StringBuilder pingCangStr = new StringBuilder();
        pingCangStr.append("平仓队列: [");
        boolean first = true;
        for (AscBigDecimal item : queuePingCang) {
            if (!first) {
                pingCangStr.append(", ");
            }
            pingCangStr.append(item.getValue());
            first = false;
        }
        pingCangStr.append("]");
        log.info(pingCangStr.toString());
 
        return queuePingCang;
    }
 
    /**
     * 主方法,用于测试网格初始化及开仓/平仓逻辑。
     * 示例使用固定价格"0.355"进行模拟调用。
     *
     * @param args 启动参数(未使用)
     */
    public static void main(String[] args) {
        WangGeListServiceImpl wangGeService = new WangGeListServiceImpl();
        String openPx = "2875";
        String markPx = "2905";
        String orderPx = "2895";
        PriorityBlockingQueue<AscBigDecimal> queueAsc = wangGeService.initWangGe(openPx);
        if (queueAsc != null) {
            wangGeService.initKaiCang(new BigDecimal(orderPx), queueAsc);
            wangGeService.initPingCang(new BigDecimal(orderPx), queueAsc);
        }
    }
}