趋势网格策略

This commit is contained in:
tony 2026-07-04 23:16:37 +08:00
commit c0187f3985
6 changed files with 499 additions and 0 deletions

2
.gitattributes vendored Normal file
View File

@ -0,0 +1,2 @@
/mvnw text eol=lf
*.cmd text eol=crlf

33
.gitignore vendored Normal file
View File

@ -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/

55
pom.xml Normal file
View File

@ -0,0 +1,55 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.sample</groupId>
<artifactId>trend-grid-strategy</artifactId>
<version>1.0.0-SNAPSHOT</version>
<name>trend-grid-strategy</name>
<description>趋势网格策略</description>
<properties>
<trade.version>5.0.0-SNAPSHOT</trade.version>
</properties>
<dependencies>
<dependency>
<groupId>vip.uuquant</groupId>
<artifactId>uuquant-java-runner</artifactId>
<version>20260329.1811</version>
</dependency>
<dependency>
<groupId>vip.uuquant</groupId>
<artifactId>uuquant-exchange-api</artifactId>
<version>20260327.1656</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.4.1</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<createDependencyReducedPom>false</createDependencyReducedPom>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>com.sample.trend.StrategyApplication</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@ -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);
}
}

View File

@ -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());
}
}

View File

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} %-5level [%thread] %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<!-- 根日志级别设为 DEBUG -->
<root level="DEBUG">
<appender-ref ref="CONSOLE" />
</root>
</configuration>