commit c0187f3985921cca3bbd5cf5b7820fe4b69f4894
Author: dongzp_book <90fanhua@gmail.com>
Date: Sat Jul 4 23:16:37 2026 +0800
趋势网格策略
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
+
+
+
+
+
+
+
+
+