浏览代码

update:增加持有仓位回报率网格报警v1

tujidelv 2 年之前
父节点
当前提交
9acbc56aff

+ 1 - 2
src/main/java/top/lvzhiqiang/service/CoinService.java

@@ -13,8 +13,7 @@ public interface CoinService {
 
     String monitorJob();
 
-    void monitorAlarm(JSONObject order);
-
+    void monitorAlarm(String content, String jobAlarmMode);
 
     /**
      * 主查询

+ 101 - 34
src/main/java/top/lvzhiqiang/service/impl/CoinServiceImpl.java

@@ -20,10 +20,7 @@ import top.lvzhiqiang.config.WorkWeixinProperties;
 import top.lvzhiqiang.entity.CoinHistoryOrder;
 import top.lvzhiqiang.mapper.CoinMapper;
 import top.lvzhiqiang.service.CoinService;
-import top.lvzhiqiang.util.CheckSign4Bitget;
-import top.lvzhiqiang.util.DateUtils;
-import top.lvzhiqiang.util.JsoupUtil;
-import top.lvzhiqiang.util.SpringUtils;
+import top.lvzhiqiang.util.*;
 
 import javax.annotation.Resource;
 import java.io.UnsupportedEncodingException;
@@ -36,6 +33,9 @@ import java.time.Duration;
 import java.time.LocalDateTime;
 import java.util.*;
 import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ScheduledThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
 import java.util.stream.Collectors;
 
 /**
@@ -82,6 +82,10 @@ public class CoinServiceImpl implements CoinService {
     private WorkWeixinProperties properties;
 
     private final Map<String, String> orderMap = new ConcurrentHashMap<>();
+    private final Map<String, JSONObject> mixMap = new ConcurrentHashMap<>();
+
+
+    private final static ScheduledExecutorService scheduler = new ScheduledThreadPoolExecutor(10);
 
     Proxy proxy = null;
 
@@ -134,50 +138,114 @@ public class CoinServiceImpl implements CoinService {
 
     @Override
     public String monitorJob() {
-        Timer timer = new Timer();
-        timer.scheduleAtFixedRate(new TimerTask() {
-            @Override
-            public void run() {
-                LocalDateTime endTime = LocalDateTime.now();
-                // 全部历史委托监控
-                Map<String, String> paramMap = new LinkedHashMap<>();
-                paramMap.put("productType", "umcbl");
-                paramMap.put("startTime", String.valueOf(DateUtils.localDateTimeToMilliseconds(endTime.minusMinutes(1))));
-                paramMap.put("endTime", String.valueOf(DateUtils.localDateTimeToMilliseconds(endTime)));
-                paramMap.put("pageSize", "100");
-
-                String signQueryString = paramMap.entrySet().stream().map(e -> e.getKey() + "=" + e.getValue()).collect(Collectors.joining("&"));
-                try {
-                    JSONObject response = requestApi4Common("/api/mix/v1/order/historyProductType", signQueryString, null, JsoupUtil.HTTP_GET, paramMap);
-                    JSONArray orderList = response.getJSONObject("data").getJSONArray("orderList");
-
-                    for (int i = 0; i < orderList.size(); i++) {
-                        JSONObject order = orderList.getJSONObject(i);
-                        LocalDateTime cTime = DateUtils.longToLocalDateTime(order.getLong("cTime"));
-                        String orderId = order.getString("orderId");
-                        if (Duration.between(cTime, endTime).getSeconds() < 50 && !orderMap.containsKey(orderId)) {
-                            orderMap.put(orderId, "1");
-                            SpringUtils.getBean(CoinServiceImpl.class).monitorAlarm(order);
+        scheduler.scheduleWithFixedDelay(() -> {
+            LocalDateTime endTime = LocalDateTime.now();
+            // 全部历史委托监控
+            Map<String, String> paramMap = new LinkedHashMap<>();
+            paramMap.put("productType", "umcbl");
+            paramMap.put("startTime", String.valueOf(DateUtils.localDateTimeToMilliseconds(endTime.minusMinutes(1))));
+            paramMap.put("endTime", String.valueOf(DateUtils.localDateTimeToMilliseconds(endTime)));
+            paramMap.put("pageSize", "100");
+
+            String signQueryString = paramMap.entrySet().stream().map(e -> e.getKey() + "=" + e.getValue()).collect(Collectors.joining("&"));
+            try {
+                JSONObject response = requestApi4Common("/api/mix/v1/order/historyProductType", signQueryString, null, JsoupUtil.HTTP_GET, paramMap);
+                JSONArray orderList = response.getJSONObject("data").getJSONArray("orderList");
+
+                for (int i = 0; i < orderList.size(); i++) {
+                    JSONObject order = orderList.getJSONObject(i);
+                    LocalDateTime cTime = DateUtils.longToLocalDateTime(order.getLong("cTime"));
+                    String orderId = order.getString("orderId");
+                    if (Duration.between(cTime, endTime).getSeconds() < 50 && !orderMap.containsKey(orderId)) {
+                        orderMap.put(orderId, "1");
+                        String content = order.getString("symbol") + "委托单已经触发,成交均价为" + order.getString("priceAvg");
+                        SpringUtils.getBean(CoinServiceImpl.class).monitorAlarm(content, JOB_ALARM_MODE_APP_TEXT_CARD);
+                    }
+                }
+            } catch (Exception e) {
+            }
+        }, 0, 2, TimeUnit.SECONDS);
+
+        scheduler.scheduleAtFixedRate(() -> {
+            LocalDateTime endTime = LocalDateTime.now();
+            // 全部合约仓位信息V2
+            Map<String, String> paramMap = new HashMap<>();
+            paramMap.put("productType", "umcbl");
+
+            String signQueryString = paramMap.entrySet().stream().map(e -> e.getKey() + "=" + e.getValue()).collect(Collectors.joining("&"));
+            try {
+                JSONObject response = requestApi4Common("/api/mix/v1/position/allPosition-v2", signQueryString, null, JsoupUtil.HTTP_GET, paramMap);
+                JSONArray mixList = response.getJSONArray("data");
+                for (int i = 0; i < mixList.size(); i++) {
+                    JSONObject mixData = mixList.getJSONObject(i);
+
+                    String symbol = mixData.getString("symbol");
+                    String margin = mixData.getString("margin");
+                    String averageOpenPrice = mixData.getString("averageOpenPrice");
+                    String key = symbol + margin + averageOpenPrice;
+
+                    // 回报率=未实现盈亏/保证金
+
+                    // 持仓方向 long:多头 short:空头
+                    String holdSide = mixData.getString("holdSide");
+                    BigDecimal returnRate = new BigDecimal(mixData.getString("unrealizedPL")).divide(new BigDecimal(margin)).setScale(2, RoundingMode.HALF_UP);
+                    for (int j = 1; j <= 10; j++) {
+                        BigDecimal grid = BigDecimal.valueOf(0.5).multiply(BigDecimal.valueOf(j));
+                        if ("long".equalsIgnoreCase(holdSide)) {
+                            if (returnRate.compareTo(grid) < 0) {
+                                if (mixMap.containsKey(key)) {
+                                    mixMap.get(key).put("returnRate", returnRate);
+                                } else {
+                                    JSONObject jsonObject = new JSONObject();
+                                    jsonObject.put("returnRate", returnRate);
+                                    mixMap.put(key, jsonObject);
+                                }
+                                break;
+                            }
+
+                            if (returnRate.compareTo(grid) > 0) {
+                                if (mixMap.containsKey(key)) {
+                                    mixMap.get(key).put("returnRate", returnRate);
+                                    if (mixMap.get(key).containsKey(grid.toPlainString())) {
+                                        continue;
+                                    } else {
+                                        mixMap.get(key).put(grid.toPlainString(), true);
+                                        SpringUtils.getBean(CoinServiceImpl.class).monitorAlarm(symbol.concat("回报率超过").concat(grid.toPlainString()), JOB_ALARM_MODE_CHAT_BOT);
+                                    }
+                                } else {
+                                    JSONObject jsonObject = new JSONObject();
+                                    jsonObject.put("returnRate", returnRate);
+                                    jsonObject.put(grid.toPlainString(), true);
+                                    mixMap.put(key, jsonObject);
+
+                                    SpringUtils.getBean(CoinServiceImpl.class).monitorAlarm(symbol.concat("回报率超过").concat(grid.toPlainString()), JOB_ALARM_MODE_CHAT_BOT);
+                                    break;
+                                }
+                            }
+                        }
+                        if ("short".equalsIgnoreCase(holdSide)) {
+                            // TODO
                         }
                     }
-                } catch (Exception e) {
                 }
+            } catch (Exception e) {
             }
-        }, 0, 2000);
+        }, 0, 5, TimeUnit.SECONDS);
 
         return null;
     }
 
     @Override
     @Async("coinTaskExecutor")
-    public void monitorAlarm(JSONObject order) {
+    public void monitorAlarm(String content, String jobAlarmMode) {
         // 判断告警模式
-        String jobAlarmMode = JOB_ALARM_MODE;
+        if (StringUtils.isEmpty(JOB_ALARM_MODE)) {
+            jobAlarmMode = JOB_ALARM_MODE;
+        }
 
         // 文本卡片模式发消息
         if (JOB_ALARM_MODE_APP_TEXT_CARD.equals(jobAlarmMode)) {
             String title = "监控告警明细";
-            String content = order.getString("symbol") + "触发";
             String logUrl = "https://lvzhiqiang.top";
             String btnTxt = "日志详情";
 
@@ -200,7 +268,6 @@ public class CoinServiceImpl implements CoinService {
         if (JOB_ALARM_MODE_CHAT_BOT.equals(jobAlarmMode)) {
             WxCpGroupRobotService groupRobotService = wxCpService.getGroupRobotService();
             String webhookUrl = "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=082970da-2a33-422a-81f6-15f9bde87940";
-            String content = order.getString("symbol") + "触发";
             try {
                 log.info("企业微信推送消息,send content: {}, userIdSet: {}", content, "LvZhiQiang");
                 groupRobotService.sendText(webhookUrl, content, Collections.singletonList("LvZhiQiang"), Collections.emptyList());

+ 1 - 2
src/test/java/top/lvzhiqiang/TestCoin.java

@@ -47,7 +47,6 @@ public class TestCoin {
     @Test
     public void testMonitorAlarm() {
         JSONObject jo = new JSONObject();
-        jo.put("symbol", "aaa");
-        coinService.monitorAlarm(jo);
+        coinService.monitorAlarm("symbol", null);
     }
 }