From c0187f3985921cca3bbd5cf5b7820fe4b69f4894 Mon Sep 17 00:00:00 2001 From: dongzp_book <90fanhua@gmail.com> Date: Sat, 4 Jul 2026 23:16:37 +0800 Subject: [PATCH] =?UTF-8?q?=E8=B6=8B=E5=8A=BF=E7=BD=91=E6=A0=BC=E7=AD=96?= =?UTF-8?q?=E7=95=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitattributes | 2 + .gitignore | 33 ++ pom.xml | 55 +++ .../com/sample/trend/StrategyApplication.java | 23 ++ .../trend/strategy/AutoGridStrategy.java | 371 ++++++++++++++++++ src/main/resources/logback.xml | 15 + 6 files changed, 499 insertions(+) create mode 100644 .gitattributes create mode 100644 .gitignore create mode 100644 pom.xml create mode 100644 src/main/java/com/sample/trend/StrategyApplication.java create mode 100644 src/main/java/com/sample/trend/strategy/AutoGridStrategy.java create mode 100644 src/main/resources/logback.xml diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..3b41682 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +/mvnw text eol=lf +*.cmd text eol=crlf diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..667aaef --- /dev/null +++ b/.gitignore @@ -0,0 +1,33 @@ +HELP.md +target/ +.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..6be101e --- /dev/null +++ b/pom.xml @@ -0,0 +1,55 @@ + + + 4.0.0 + + com.sample + trend-grid-strategy + 1.0.0-SNAPSHOT + trend-grid-strategy + 趋势网格策略 + + + 5.0.0-SNAPSHOT + + + + vip.uuquant + uuquant-java-runner + 20260329.1811 + + + + vip.uuquant + uuquant-exchange-api + 20260327.1656 + + + + + + + org.apache.maven.plugins + maven-shade-plugin + 3.4.1 + + + package + + shade + + + false + + + com.sample.trend.StrategyApplication + + + + + + + + + + diff --git a/src/main/java/com/sample/trend/StrategyApplication.java b/src/main/java/com/sample/trend/StrategyApplication.java new file mode 100644 index 0000000..2101c0e --- /dev/null +++ b/src/main/java/com/sample/trend/StrategyApplication.java @@ -0,0 +1,23 @@ +package com.sample.trend; + + +import com.sample.trend.strategy.AutoGridStrategy; +import vip.uuquant.tradesystem.runner.core.StrategyRunner; +import vip.uuquant.tradesystem.runner.vo.DebugConfig; + +public class StrategyApplication { + + public static void main(String[] args) { + // 调试模式 + DebugConfig debugConfig = new DebugConfig(); + debugConfig.setAgentHost("192.168.0.105"); + debugConfig.setRobotId(2038210296263434242L); + debugConfig.setRobotApiKey("454d7146f092fdbbcfdef0ff554d9aa4"); + + StrategyRunner strategyRunner = StrategyRunner.getInstance(); + strategyRunner.setDebugConfig(debugConfig); + strategyRunner.init(AutoGridStrategy.class); + + } + +} diff --git a/src/main/java/com/sample/trend/strategy/AutoGridStrategy.java b/src/main/java/com/sample/trend/strategy/AutoGridStrategy.java new file mode 100644 index 0000000..c9ab60a --- /dev/null +++ b/src/main/java/com/sample/trend/strategy/AutoGridStrategy.java @@ -0,0 +1,371 @@ +package com.sample.trend.strategy; + +import com.alibaba.fastjson2.JSONArray; +import com.alibaba.fastjson2.JSONObject; +import com.hengyi.xbaseweb.common.result.ApiResult; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import vip.uuquant.exhangeapi.enums.*; +import vip.uuquant.tradesystem.runner.enums.AlarmLevel; +import vip.uuquant.tradesystem.runner.enums.MessagePushType; +import vip.uuquant.tradesystem.runner.enums.RobotChartType; +import vip.uuquant.tradesystem.runner.strategy.BaseStrategy; +import vip.uuquant.tradesystem.runner.vo.*; + +import java.math.BigDecimal; +import java.time.LocalDateTime; + +/** + * @author dongzp + * @desc 策略示例,展示所有API调用方法 + **/ +public class AutoGridStrategy extends BaseStrategy { + // 日志 + private final Logger logger = LoggerFactory.getLogger(AutoGridStrategy.class); + + // 图表对象 + private Integer textChart; + private Integer tableChart; + private Integer barChart; + + // 定时任务ID + private String taskId; + + @Override + public void init(JSONObject context) { + super.init(context); + logger.info("策略初始化开始"); + + try { + // 1. 检查运行参数 + boolean check = checkParams("a17640829211617765"); + logger.info("参数检查结果:{}", check); + + // 2. 检查运行参数,不存在则抛出异常 + tryParams("a17640829211617765"); + + // 3. 获取运行参数 + JSONObject runParams = getRunParams(); + logger.info("运行参数:{}", runParams); + + // 4. 获取交易对和币符号 + String symbol = getSymbol(); + String instrument = getInstrument(); + logger.info("交易对:{},币符号:{}", symbol, instrument); + + // 5. 获取账户信息 + AccountVO account = getAccount(); + if (account != null) { + logger.info("账户信息:{}", account.getName()); + } + + // 6. 获取策略信息 + StrategyVO strategy = getStrategy(); + if (strategy != null) { + logger.info("策略信息获取成功"); + } + + // 7. 获取托管服务器信息 + AgentVO agent = getAgent(); + if (agent != null) { + logger.info("Agent信息获取成功"); + } + + SymbolVO symbolVO = getSymbolInfo(); + if (symbolVO != null) { + logger.info("获取交易对信息成功"); + } + + // 8. 创建文字图表 + textChart = createChart(RobotChartType.TEXT, "显示时间", 1, 1, 24); + logger.info("文字图表创建成功,dataId:{}", textChart); + + // 9. 创建表格图表 + tableChart = createChart(RobotChartType.TABLE, "数据表格", 2, 2, 12); + logger.info("表格图表创建成功,dataId:{}", tableChart); + + // 10. 创建柱状图图表 + barChart = createChart(RobotChartType.CHART, "统计图表", 3, 3, 12); + logger.info("柱状图图表创建成功,dataId:{}", barChart); + + // 11. 保存共享数据 + JSONObject sharedData = new JSONObject(); + sharedData.put("key1", "value1"); + sharedData.put("key2", 123); + AgentResult result = putSharedData("testKey", sharedData); + logger.info("保存共享数据结果:code={}, msg={}", result.getCode(), result.getMsg()); + + // 12. 创建定时任务(每600秒执行一次,延迟5秒开始) + taskId = createTask(this::syncAccount, 5, 600); + logger.info("定时任务创建成功,taskId:{}", taskId); + + // 13. 提交告警信息 + AgentResult alarmResult = submitAlarm("策略初始化", "策略初始化完成", AlarmLevel.INFO); + logger.info("提交告警结果:code={}, msg={}", alarmResult.getCode(), alarmResult.getMsg()); + + // 提交订单信息 + submitOrderExample(); + + // 提交持仓信息 + submitPositionExample(); + + logger.info("策略初始化完成"); + } catch (Exception e) { + logger.error("策略初始化异常", e); + } + } + + @Override + public void run() { + try { + logger.info("策略运行中,当前时间:{}", LocalDateTime.now()); + + // 1. 更新文字图表 + JSONObject textStyle = new JSONObject(); + textStyle.put("color", "red"); + textStyle.put("fontSize", "16px"); + textStyle.put("fontWeight", "bold"); + String currentTime = LocalDateTime.now().toString(); + ApiResult result = updateText(textChart, "当前时间:" + currentTime, textStyle); + logger.info("更新文字图表结果:code={}, msg={}", result.getCode(), result.getMsg()); + + // 2. 更新表格图表 + JSONArray tableData = new JSONArray(); + for (int i = 0; i < 3; i++) { + JSONObject row = new JSONObject(); + row.put("name", "用户" + (i + 1)); + row.put("sex", i % 2 == 0 ? "男" : "女"); + row.put("datetime", LocalDateTime.now().toString()); + row.put("address", "地址" + (i + 1)); + tableData.add(row); + } + + JSONObject tableOption = new JSONObject(); + tableOption.put("height", 300); + JSONArray columns = new JSONArray(); + + JSONObject col1 = new JSONObject(); + col1.put("label", "姓名"); + col1.put("prop", "name"); + col1.put("width", 200); + col1.put("fixed", true); + columns.add(col1); + + JSONObject col2 = new JSONObject(); + col2.put("label", "性别"); + col2.put("prop", "sex"); + col2.put("width", 300); + columns.add(col2); + + JSONObject col3 = new JSONObject(); + col3.put("label", "日期"); + col3.put("prop", "datetime"); + col3.put("width", 300); + columns.add(col3); + + JSONObject col4 = new JSONObject(); + col4.put("label", "地址"); + col4.put("prop", "address"); + col4.put("width", 300); + columns.add(col4); + + tableOption.put("column", columns); + ApiResult apiResult = updateTable(tableChart, tableData, tableOption); + logger.info("更新表格图表结果:code={}, msg={}", apiResult.getCode(), apiResult.getMsg()); + + // 3. 更新柱状图图表 + JSONObject chartOptions = new JSONObject(); + JSONObject xAxis = new JSONObject(); + xAxis.put("type", "category"); + JSONArray xData = new JSONArray(); + xData.add("Mon"); + xData.add("Tue"); + xData.add("Wed"); + xData.add("Thu"); + xData.add("Fri"); + xData.add("Sat"); + xData.add("Sun"); + xAxis.put("data", xData); + chartOptions.put("xAxis", xAxis); + + JSONObject yAxis = new JSONObject(); + yAxis.put("type", "value"); + chartOptions.put("yAxis", yAxis); + + JSONArray series = new JSONArray(); + JSONObject seriesItem = new JSONObject(); + JSONArray seriesData = new JSONArray(); + seriesData.add(120); + seriesData.add(200); + seriesData.add(150); + seriesData.add(80); + seriesData.add(70); + seriesData.add(110); + seriesData.add(130); + seriesItem.put("data", seriesData); + seriesItem.put("type", "bar"); + series.add(seriesItem); + chartOptions.put("series", series); + + ApiResult apiResult1 = updateEChart(barChart, chartOptions); + logger.info("更新柱状图图表结果:code={}, msg={}", apiResult1.getCode(), apiResult1.getMsg()); + + // 4. 更新账户余额(示例) + updateAccountBalance(new BigDecimal("10000.00"), new BigDecimal("8000.00"), new BigDecimal("2000.00")); + + // 5. 发送通知到平台 + // AgentResult notifyResult = sendNotify(200, "策略运行正常", "当前时间:" + LocalDateTime.now()); + // logger.info("发送通知结果:code={}", notifyResult.getCode()); + + // 6. 获取共享数据 + JSONObject sharedData = getSharedData("testKey"); + if (sharedData != null) { + logger.info("获取共享数据:{}", sharedData); + } + + } catch (Exception e) { + logger.error("策略运行异常", e); + } + } + + @Override + public void notify(JSONObject data) { + logger.info("策略收到通知:{}", data); + + try { + // 1. 提交告警信息 + String title = "收到通知"; + String content = "通知内容:" + data.toJSONString(); + AgentResult alarmResult = submitAlarm(title, content, AlarmLevel.INFO); + logger.info("提交告警结果:code={}, msg={}", alarmResult.getCode(), alarmResult.getMsg()); + + // 2. 获取共享数据 + JSONObject sharedData = getSharedData("testKey"); + if (sharedData != null) { + logger.info("共享数据:{}", sharedData); + } + + // 3. 发送通知到平台 + AgentResult notifyResult = sendNotify(200, "已收到通知", data.toJSONString()); + logger.info("发送通知结果:code={}", notifyResult.getCode()); + + // 发送一个异常告警 + AgentResult alarmResult1 = submitAlarm("策略异常", "策略异常,请检查", AlarmLevel.ERROR); + logger.info("提交告警结果:code={}", alarmResult1.getCode()); + + } catch (Exception e) { + logger.error("处理通知异常", e); + } + } + + @Override + public void destroy() { + logger.info("策略销毁开始"); + + try { + // 1. 删除所有图表 + removeChart(null); + + // 2. 删除共享数据 + AgentResult result = removeSharedData("testKey"); + logger.info("删除共享数据结果:code={}", result.getCode()); + + // 3. 删除定时任务 + if (taskId != null) { + removeTask(taskId); + logger.info("删除定时任务:{}", taskId); + } + + // 4. 删除所有定时任务 + // removeAllTask(); + + // 5. 提交告警信息 + AgentResult alarmResult = submitAlarm("策略销毁", "策略正在销毁", AlarmLevel.WARNING); + logger.info("提交告警结果:code={}", alarmResult.getCode()); + + // 发送邮件 + pushMessageExample(); + + logger.info("策略销毁完成"); + } catch (Exception e) { + logger.error("策略销毁异常", e); + } + } + + /** + * 同步账户信息(定时任务示例) + */ + private void syncAccount() { + try { + logger.info("执行定时任务:同步账户信息"); + AccountVO account = getAccount(); + if (account != null) { + logger.info("账户名称:{}", account.getName()); + } + + // 更新账户余额示例 + updateAccountBalance(new BigDecimal("10000.00"), new BigDecimal("8000.00"), new BigDecimal("2000.00")); + } catch (Exception e) { + logger.error("同步账户信息异常", e); + } + } + + /** + * 提交订单信息示例(可根据实际情况调用) + */ + private void submitOrderExample() { + JSONObject orderInfo = new JSONObject(); + orderInfo.put("robotId", 1993936305684348930L); + orderInfo.put("clientOrderId", "CLIENT_ORDER_" + System.currentTimeMillis()); + orderInfo.put("orderId", "EXCHANGE_ORDER_123"); + orderInfo.put("avgPrice", new BigDecimal("2000.50")); + orderInfo.put("cumQty", new BigDecimal("1.0")); + orderInfo.put("origQty", new BigDecimal("1.0")); + orderInfo.put("price", new BigDecimal("2000.00")); + orderInfo.put("symbol", "BTCUSDT"); + orderInfo.put("leverage", 10); + // 注意:以下字段需要根据实际的枚举类型设置 + orderInfo.put("side", OrderSide.BUY); + orderInfo.put("positionSide", PositionSide.LONG); + orderInfo.put("orderStatus", OrderStatus.FILLED); + + AgentResult result = submitOrder(orderInfo); + logger.info("提交订单结果:code={}, msg={}", result.getCode(), result.getMsg()); + } + + /** + * 提交仓位信息示例(可根据实际情况调用) + */ + private void submitPositionExample() { + JSONObject positionInfo = new JSONObject(); + positionInfo.put("robotId", 1993936305684348930L); + positionInfo.put("clientPositionId", "POSITION_" + System.currentTimeMillis()); + positionInfo.put("profitValue", new BigDecimal("100.50")); + positionInfo.put("unrealizedProfitValue", new BigDecimal("50.25")); + positionInfo.put("symbol", "BTCUSDT"); + positionInfo.put("leverage", 10); + positionInfo.put("openAvgPrice", new BigDecimal("2000.00")); + positionInfo.put("qty", new BigDecimal("1.0")); + // 注意:以下字段需要根据实际的枚举类型设置 + positionInfo.put("positionSide", PositionSide.LONG); + positionInfo.put("marginType", MarginType.ISOLATED); + positionInfo.put("qtyUnit", QtyUnitType.COIN); + positionInfo.put("positionStatus", PositionStatus.POSITION); + + AgentResult result = submitPosition(positionInfo); + logger.info("提交仓位结果:code={}, msg={}", result.getCode(), result.getMsg()); + } + + /** + * 消息推送示例(可根据实际情况调用) + */ + private void pushMessageExample() { + JSONObject params = new JSONObject(); + params.put("email", "975303544@qq.com"); + ApiResult result = pushMessage(MessagePushType.EMAIL, "欢迎使用UU量化", + "您的订单已成交,成交均价:2000.87,请注意!", + params + ); + logger.info("消息推送结果:code={} msg={}", result.getCode(), result.getMsg()); + } +} diff --git a/src/main/resources/logback.xml b/src/main/resources/logback.xml new file mode 100644 index 0000000..2a1949c --- /dev/null +++ b/src/main/resources/logback.xml @@ -0,0 +1,15 @@ + + + + + + %d{yyyy-MM-dd HH:mm:ss} %-5level [%thread] %logger{36} - %msg%n + + + + + + + + +