chore(assets): 参赛提交规范红线修复(ASCII 化 + 相对路径)

按《参赛成果物提交规范·赛道一》§6 红线:
- samples/ 目录改名 sample/(git mv,保留历史)
- 10 个中日文样本文件 + docs 参赛手册 PDF 重命名为 ASCII
  (requirements_*/template_*/rules_*/contestant-handbook.pdf)
- tests/test_zh_template.py 硬编码绝对路径 D:\00_project\Genesis 改为相对路径
- 全局更新 21 个活动文件引用;历史日志/审查文档不改(追加说明记录)
全量 pytest 431 passed / 99.15%
This commit is contained in:
lhl
2026-08-26 14:15:52 +08:00
parent 1925ef7239
commit becd3e1f57
398 changed files with 286 additions and 72 deletions
@@ -0,0 +1,20 @@
package com.stock.trade.indicator;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;
/**
* 技术指标服务启动类
*
* @author AI Assistant
*/
@SpringBootApplication(scanBasePackages = {"com.stock.trade"})
@EnableScheduling // 启用定时任务
public class IndicatorApplication {
public static void main(String[] args) {
SpringApplication.run(IndicatorApplication.class, args);
}
}
@@ -0,0 +1,183 @@
package com.stock.trade.indicator.controller;
import com.stock.trade.framework.common.pojo.CommonResult;
import com.stock.trade.framework.common.pojo.PageResult;
import com.stock.trade.indicator.controller.vo.IndicatorDefinitionCreateReqVO;
import com.stock.trade.indicator.controller.vo.IndicatorDefinitionPageReqVO;
import com.stock.trade.indicator.controller.vo.IndicatorDefinitionRespVO;
import com.stock.trade.indicator.controller.vo.IndicatorDefinitionUpdateReqVO;
import com.stock.trade.indicator.convert.IndicatorDefinitionConvert;
import com.stock.trade.indicator.dal.dataobject.IndicatorDefinitionDO;
import com.stock.trade.indicator.service.IndicatorDefinitionService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.List;
import static com.stock.trade.framework.common.pojo.CommonResult.success;
/**
* 技术指标定义 Controller
*
* @author tianxin
*/
@Tag(name = "管理后台 - 技术指标定义")
@RestController
@RequestMapping("/indicator/definition")
@Validated
public class IndicatorDefinitionController {
@Resource
private IndicatorDefinitionService indicatorDefinitionService;
/**
* 创建技术指标定义
*
* @param createReqVO 创建信息
* @return 指标定义ID
*/
@PostMapping("/create")
@Operation(summary = "创建技术指标定义")
@PreAuthorize("@ss.hasPermission('indicator:definition:create')")
public CommonResult<Long> createIndicatorDefinition(@Valid @RequestBody IndicatorDefinitionCreateReqVO createReqVO) {
return success(indicatorDefinitionService.createIndicatorDefinition(createReqVO));
}
/**
* 更新技术指标定义
*
* @param updateReqVO 更新信息
* @return 是否成功
*/
@PutMapping("/update")
@Operation(summary = "更新技术指标定义")
@PreAuthorize("@ss.hasPermission('indicator:definition:update')")
public CommonResult<Boolean> updateIndicatorDefinition(@Valid @RequestBody IndicatorDefinitionUpdateReqVO updateReqVO) {
indicatorDefinitionService.updateIndicatorDefinition(updateReqVO);
return success(true);
}
/**
* 更新技术指标定义状态
*
* @param id 指标定义ID
* @param enabled 是否启用
* @return 是否成功
*/
@PutMapping("/update-status")
@Operation(summary = "更新技术指标定义状态")
@PreAuthorize("@ss.hasPermission('indicator:definition:update')")
public CommonResult<Boolean> updateIndicatorDefinitionStatus(@RequestParam("id") Long id,
@RequestParam("enabled") Boolean enabled) {
indicatorDefinitionService.updateIndicatorDefinitionStatus(id, enabled);
return success(true);
}
/**
* 删除技术指标定义
*
* @param id 指标定义ID
* @return 是否成功
*/
@DeleteMapping("/delete")
@Operation(summary = "删除技术指标定义")
@Parameter(name = "id", description = "编号", required = true)
@PreAuthorize("@ss.hasPermission('indicator:definition:delete')")
public CommonResult<Boolean> deleteIndicatorDefinition(@RequestParam("id") Long id) {
indicatorDefinitionService.deleteIndicatorDefinition(id);
return success(true);
}
/**
* 获取技术指标定义
*
* @param id 指标定义ID
* @return 指标定义信息
*/
@GetMapping("/get")
@Operation(summary = "获得技术指标定义")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
@PreAuthorize("@ss.hasPermission('indicator:definition:query')")
public CommonResult<IndicatorDefinitionRespVO> getIndicatorDefinition(@RequestParam("id") Long id) {
IndicatorDefinitionDO definition = indicatorDefinitionService.getIndicatorDefinition(id);
return success(IndicatorDefinitionConvert.INSTANCE.convert(definition));
}
/**
* 获取技术指标定义列表
*
* @param ids 指标定义ID列表
* @return 指标定义列表
*/
@GetMapping("/list")
@Operation(summary = "获得技术指标定义列表")
@Parameter(name = "ids", description = "编号列表", required = true, example = "1024,2048")
@PreAuthorize("@ss.hasPermission('indicator:definition:query')")
public CommonResult<List<IndicatorDefinitionRespVO>> getIndicatorDefinitionList(@RequestParam("ids") List<Long> ids) {
List<IndicatorDefinitionDO> list = indicatorDefinitionService.getIndicatorDefinitionList(ids);
return success(IndicatorDefinitionConvert.INSTANCE.convertList(list));
}
/**
* 获取技术指标定义分页
*
* @param pageVO 分页查询参数
* @return 指标定义分页结果
*/
@GetMapping("/page")
@Operation(summary = "获得技术指标定义分页")
@PreAuthorize("@ss.hasPermission('indicator:definition:query')")
public CommonResult<PageResult<IndicatorDefinitionRespVO>> getIndicatorDefinitionPage(@Valid IndicatorDefinitionPageReqVO pageVO) {
PageResult<IndicatorDefinitionDO> pageResult = indicatorDefinitionService.getIndicatorDefinitionPage(pageVO);
return success(IndicatorDefinitionConvert.INSTANCE.convertPage(pageResult));
}
/**
* 根据名称获取技术指标定义
*
* @param name 指标名称
* @return 指标定义信息
*/
@GetMapping("/get-by-name")
@Operation(summary = "根据名称获得技术指标定义")
@Parameter(name = "name", description = "指标名称", required = true, example = "SMA")
@PreAuthorize("@ss.hasPermission('indicator:definition:query')")
public CommonResult<IndicatorDefinitionRespVO> getIndicatorDefinitionByName(@RequestParam("name") String name) {
IndicatorDefinitionDO definition = indicatorDefinitionService.getIndicatorDefinitionByName(name);
return success(IndicatorDefinitionConvert.INSTANCE.convert(definition));
}
/**
* 根据类型获取技术指标定义列表
*
* @param type 指标类型
* @return 指标定义列表
*/
@GetMapping("/list-by-type")
@Operation(summary = "根据类型获得技术指标定义列表")
@Parameter(name = "type", description = "指标类型", required = true, example = "TREND")
@PreAuthorize("@ss.hasPermission('indicator:definition:query')")
public CommonResult<List<IndicatorDefinitionRespVO>> getIndicatorDefinitionListByType(@RequestParam("type") String type) {
List<IndicatorDefinitionDO> list = indicatorDefinitionService.getIndicatorDefinitionListByType(type);
return success(IndicatorDefinitionConvert.INSTANCE.convertList(list));
}
/**
* 获取所有启用的技术指标定义列表
*
* @return 启用的指标定义列表
*/
@GetMapping("/list-enabled")
@Operation(summary = "获得所有启用的技术指标定义列表")
@PreAuthorize("@ss.hasPermission('indicator:definition:query')")
public CommonResult<List<IndicatorDefinitionRespVO>> getEnabledIndicatorDefinitionList() {
List<IndicatorDefinitionDO> list = indicatorDefinitionService.getEnabledIndicatorDefinitionList();
return success(IndicatorDefinitionConvert.INSTANCE.convertList(list));
}
}
@@ -0,0 +1,240 @@
package com.stock.trade.indicator.controller;
import com.stock.trade.framework.common.pojo.CommonResult;
import com.stock.trade.framework.common.pojo.PageResult;
import com.stock.trade.indicator.controller.vo.indicator.value.*;
import com.stock.trade.indicator.convert.IndicatorValueConvert;
import com.stock.trade.indicator.dal.dataobject.IndicatorValueDO;
import com.stock.trade.indicator.service.IndicatorValueService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.IOException;
import java.time.LocalDateTime;
import java.util.List;
import static com.stock.trade.framework.common.pojo.CommonResult.success;
import static com.stock.trade.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
/**
* 技术指标计算结果 Controller
*
* @author AI Assistant
*/
@Tag(name = "管理后台 - 技术指标计算结果")
@RestController
@RequestMapping("/indicator/value")
@Validated
public class IndicatorValueController {
@Resource
private IndicatorValueService indicatorValueService;
/**
* 创建指标计算结果
*
* @param createReqVO 创建信息
* @return 指标计算结果ID
*/
@PostMapping("/create")
@Operation(summary = "创建指标计算结果")
@PreAuthorize("@ss.hasPermission('indicator:value:create')")
public CommonResult<Long> createIndicatorValue(@Valid @RequestBody IndicatorValueCreateReqVO createReqVO) {
return success(indicatorValueService.createIndicatorValue(createReqVO));
}
/**
* 更新指标计算结果
*
* @param updateReqVO 更新信息
* @return 是否成功
*/
@PutMapping("/update")
@Operation(summary = "更新指标计算结果")
@PreAuthorize("@ss.hasPermission('indicator:value:update')")
public CommonResult<Boolean> updateIndicatorValue(@Valid @RequestBody IndicatorValueUpdateReqVO updateReqVO) {
indicatorValueService.updateIndicatorValue(updateReqVO);
return success(true);
}
/**
* 删除指标计算结果
*
* @param id 指标计算结果ID
* @return 是否成功
*/
@DeleteMapping("/delete")
@Operation(summary = "删除指标计算结果")
@Parameter(name = "id", description = "编号", required = true)
@PreAuthorize("@ss.hasPermission('indicator:value:delete')")
public CommonResult<Boolean> deleteIndicatorValue(@RequestParam("id") Long id) {
indicatorValueService.deleteIndicatorValue(id);
return success(true);
}
/**
* 获取指标计算结果
*
* @param id 指标计算结果ID
* @return 指标计算结果信息
*/
@GetMapping("/get")
@Operation(summary = "获得指标计算结果")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
@PreAuthorize("@ss.hasPermission('indicator:value:query')")
public CommonResult<IndicatorValueRespVO> getIndicatorValue(@RequestParam("id") Long id) {
IndicatorValueDO value = indicatorValueService.getIndicatorValue(id);
return success(IndicatorValueConvert.INSTANCE.convert(value));
}
/**
* 获取指标计算结果列表
*
* @param ids 指标计算结果ID列表
* @return 指标计算结果列表
*/
@GetMapping("/list")
@Operation(summary = "获得指标计算结果列表")
@Parameter(name = "ids", description = "编号列表", required = true, example = "1024,2048")
@PreAuthorize("@ss.hasPermission('indicator:value:query')")
public CommonResult<List<IndicatorValueRespVO>> getIndicatorValueList(@RequestParam("ids") List<Long> ids) {
List<IndicatorValueDO> list = indicatorValueService.getIndicatorValueList(ids);
return success(IndicatorValueConvert.INSTANCE.convertList(list));
}
/**
* 获取指标计算结果分页
*
* @param pageVO 分页查询参数
* @return 指标计算结果分页结果
*/
@GetMapping("/page")
@Operation(summary = "获得指标计算结果分页")
@PreAuthorize("@ss.hasPermission('indicator:value:query')")
public CommonResult<PageResult<IndicatorValueRespVO>> getIndicatorValuePage(@Valid IndicatorValuePageReqVO pageVO) {
PageResult<IndicatorValueDO> pageResult = indicatorValueService.getIndicatorValuePage(pageVO);
return success(IndicatorValueConvert.INSTANCE.convertPage(pageResult));
}
/**
* 导出指标计算结果 Excel
*
* @param response HTTP响应
* @param exportReqVO 查询条件
* @throws IOException IO异常
*/
@GetMapping("/export-excel")
@Operation(summary = "导出指标计算结果 Excel")
@PreAuthorize("@ss.hasPermission('indicator:value:export')")
// @OperateLog(type = EXPORT) // 假设有操作日志注解
public void exportIndicatorValueExcel(HttpServletResponse response, @Valid IndicatorValueExportReqVO exportReqVO) throws IOException {
List<IndicatorValueDO> list = indicatorValueService.getIndicatorValueList(exportReqVO);
List<IndicatorValueExcelVO> excelList = IndicatorValueConvert.INSTANCE.convertList02(list);
// ExcelUtils.write(response, "指标计算结果.xls", "数据", IndicatorValueExcelVO.class, excelList); // 假设有Excel导出工具类
}
/**
* 获取最新的指标计算结果
*
* @param definitionId 指标定义ID
* @param stockCode 股票代码
* @param period 时间周期
* @return 最新的指标计算结果
*/
@GetMapping("/get-latest")
@Operation(summary = "获取最新的指标计算结果")
@Parameters({
@Parameter(name = "definitionId", description = "指标定义ID", required = true, example = "1"),
@Parameter(name = "stockCode", description = "股票代码", required = true, example = "600000.SH"),
@Parameter(name = "period", description = "时间周期", required = true, example = "DAY")
})
@PreAuthorize("@ss.hasPermission('indicator:value:query')")
public CommonResult<IndicatorValueRespVO> getLatestIndicatorValue(@RequestParam("definitionId") Long definitionId,
@RequestParam("stockCode") String stockCode,
@RequestParam("period") String period) {
IndicatorValueDO value = indicatorValueService.getLatestIndicatorValue(definitionId, stockCode, period);
return success(IndicatorValueConvert.INSTANCE.convert(value));
}
/**
* 获取指定时间范围内的指标计算结果列表
*
* @param definitionId 指标定义ID
* @param stockCode 股票代码
* @param period 时间周期
* @param startTime 开始时间
* @param endTime 结束时间
* @return 指标计算结果列表
*/
@GetMapping("/list-by-time-range")
@Operation(summary = "获取指定时间范围内的指标计算结果列表")
@Parameters({
@Parameter(name = "definitionId", description = "指标定义ID", required = true, example = "1"),
@Parameter(name = "stockCode", description = "股票代码", required = true, example = "600000.SH"),
@Parameter(name = "period", description = "时间周期", required = true, example = "DAY"),
@Parameter(name = "startTime", description = "开始时间", required = true, example = "2023-01-01T00:00:00"),
@Parameter(name = "endTime", description = "结束时间", required = true, example = "2023-12-31T23:59:59")
})
@PreAuthorize("@ss.hasPermission('indicator:value:query')")
public CommonResult<List<IndicatorValueRespVO>> getIndicatorValueListByTimeRange(
@RequestParam("definitionId") Long definitionId,
@RequestParam("stockCode") String stockCode,
@RequestParam("period") String period,
@RequestParam("startTime") @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime startTime,
@RequestParam("endTime") @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime endTime) {
List<IndicatorValueDO> list = indicatorValueService.getIndicatorValueListByTimeRange(definitionId, stockCode, period, startTime, endTime);
return success(IndicatorValueConvert.INSTANCE.convertList(list));
}
/**
* 获取指定状态的指标计算结果列表
*
* @param status 计算状态
* @return 指标计算结果列表
*/
@GetMapping("/list-by-status")
@Operation(summary = "获取指定状态的指标计算结果列表")
@Parameter(name = "status", description = "计算状态", required = true, example = "SUCCESS")
@PreAuthorize("@ss.hasPermission('indicator:value:query')")
public CommonResult<List<IndicatorValueRespVO>> getIndicatorValueListByStatus(@RequestParam("status") String status) {
List<IndicatorValueDO> list = indicatorValueService.getIndicatorValueListByStatus(status);
return success(IndicatorValueConvert.INSTANCE.convertList(list));
}
/**
* 批量更新指标计算结果状态
*
* @param updateStatusReqVO 更新状态请求
* @return 是否成功
*/
@PutMapping("/update-status-batch")
@Operation(summary = "批量更新指标计算结果状态")
@PreAuthorize("@ss.hasPermission('indicator:value:update')")
public CommonResult<Boolean> updateIndicatorValueStatusBatch(@Valid @RequestBody IndicatorValueUpdateStatusBatchReqVO updateStatusReqVO) {
indicatorValueService.updateIndicatorValueStatusBatch(updateStatusReqVO.getIds(), updateStatusReqVO.getStatus(), updateStatusReqVO.getErrorMessage());
return success(true);
}
/**
* 触发指标计算
*
* @param calculateReqVO 计算请求信息
* @return 指标计算结果ID列表
*/
@PostMapping("/calculate")
@Operation(summary = "触发指标计算")
@PreAuthorize("@ss.hasPermission('indicator:value:calculate')")
public CommonResult<List<Long>> calculateIndicatorValue(@Valid @RequestBody IndicatorValueCalculateReqVO calculateReqVO) {
List<Long> resultIds = indicatorValueService.calculateIndicatorValue(calculateReqVO);
return success(resultIds);
}
}
@@ -0,0 +1,35 @@
package com.stock.trade.indicator.convert;
import com.stock.trade.framework.common.pojo.PageResult;
import com.stock.trade.indicator.controller.vo.indicator.definition.*;
import com.stock.trade.indicator.dal.dataobject.IndicatorDefinitionDO;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
import java.util.List;
/**
* 指标定义 Convert
*
* @author tianxin
*/
@Mapper
public interface IndicatorDefinitionConvert {
IndicatorDefinitionConvert INSTANCE = Mappers.getMapper(IndicatorDefinitionConvert.class);
IndicatorDefinitionDO convert(IndicatorDefinitionCreateReqVO bean);
IndicatorDefinitionDO convert(IndicatorDefinitionUpdateReqVO bean);
IndicatorDefinitionRespVO convert(IndicatorDefinitionDO bean);
List<IndicatorDefinitionRespVO> convertList(List<IndicatorDefinitionDO> list);
PageResult<IndicatorDefinitionRespVO> convertPage(PageResult<IndicatorDefinitionDO> page);
List<IndicatorDefinitionExcelVO> convertList02(List<IndicatorDefinitionDO> list);
List<IndicatorDefinitionSimpleRespVO> convertList03(List<IndicatorDefinitionDO> list);
}
@@ -0,0 +1,33 @@
package com.stock.trade.indicator.convert;
import com.stock.trade.framework.common.pojo.PageResult;
import com.stock.trade.indicator.controller.vo.indicator.value.*;
import com.stock.trade.indicator.dal.dataobject.IndicatorValueDO;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
import java.util.List;
/**
* 指标计算结果 Convert
*
* @author tianxin
*/
@Mapper
public interface IndicatorValueConvert {
IndicatorValueConvert INSTANCE = Mappers.getMapper(IndicatorValueConvert.class);
IndicatorValueDO convert(IndicatorValueCreateReqVO bean);
IndicatorValueDO convert(IndicatorValueUpdateReqVO bean);
IndicatorValueRespVO convert(IndicatorValueDO bean);
List<IndicatorValueRespVO> convertList(List<IndicatorValueDO> list);
PageResult<IndicatorValueRespVO> convertPage(PageResult<IndicatorValueDO> page);
List<IndicatorValueExcelVO> convertList02(List<IndicatorValueDO> list);
}
@@ -0,0 +1,68 @@
package com.stock.trade.indicator.dal.dataobject;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.stock.trade.framework.mybatis.core.dataobject.BaseDO;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* 技术指标定义 DO
*
* @author tianxin
*/
@TableName("indicator_definition")
@Data
@EqualsAndHashCode(callSuper = true)
public class IndicatorDefinitionDO extends BaseDO {
/**
* 指标ID,主键自增
*/
@TableId(type = IdType.AUTO)
private Long id;
/**
* 指标名称,例如:Moving Average, MACD, RSI
*/
private String name;
/**
* 指标简称,例如:MA, MACD, RSI
*/
private String shortName;
/**
* 指标描述
*/
private String description;
/**
* 指标类型,例如:趋势型、震荡型、成交量型
* 可以使用枚举定义
*/
private String type;
/**
* 计算公式描述或类引用
* 例如:"CLOSE / MA(CLOSE, N)" 或 "com.stock.trade.indicator.calculator.MACDCalculator"
*/
private String formula;
/**
* 默认参数,JSON格式,例如:{"period": 20} for MA, {"shortPeriod":12, "longPeriod":26, "signalPeriod":9} for MACD
*/
private String defaultParams;
/**
* 是否启用
*/
private Boolean enabled;
/**
* 备注
*/
private String remark;
}
@@ -0,0 +1,77 @@
package com.stock.trade.indicator.dal.dataobject;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.stock.trade.framework.mybatis.core.dataobject.BaseDO;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.time.LocalDateTime;
/**
* 技术指标计算结果 DO
*
* @author tianxin
*/
@TableName("indicator_value")
@Data
@EqualsAndHashCode(callSuper = true)
public class IndicatorValueDO extends BaseDO {
/**
* 指标值ID,主键自增
*/
@TableId(type = IdType.AUTO)
private Long id;
/**
* 关联的指标定义ID
* {@link IndicatorDefinitionDO#getId()}
*/
private Long definitionId;
/**
* 股票代码
*/
private String stockCode;
/**
* 时间周期,例如:1min, 5min, 1day, 1week
*/
private String timePeriod;
/**
* 计算时间点
*/
private LocalDateTime calculationTime;
/**
* 指标计算参数,JSON格式,覆盖或补充指标定义的默认参数
* 例如:{"period": 30}
*/
private String params;
/**
* 指标计算结果,JSON格式
* 例如:{"ma": 10.5} 或 {"macd": 0.5, "diff": 0.2, "dea": 0.3}
*/
private String results;
/**
* 计算状态,例如:PENDING, CALCULATING, SUCCESS, FAILED
* 可以使用枚举定义
*/
private String status;
/**
* 错误信息,当计算失败时记录
*/
private String errorMessage;
/**
* 备注
*/
private String remark;
}
@@ -0,0 +1,50 @@
package com.stock.trade.indicator.dal.mysql;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.stock.trade.framework.mybatis.core.mapper.BaseMapperX;
import com.stock.trade.indicator.dal.dataobject.IndicatorDefinitionDO;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
/**
* 技术指标定义 Mapper
*
* @author tianxin
*/
@Mapper
public interface IndicatorDefinitionMapper extends BaseMapperX<IndicatorDefinitionDO> {
/**
* 根据指标名称查询指标定义
*
* @param name 指标名称
* @return 指标定义
*/
default IndicatorDefinitionDO selectByName(String name) {
return selectOne(new LambdaQueryWrapper<IndicatorDefinitionDO>()
.eq(IndicatorDefinitionDO::getName, name));
}
/**
* 根据指标类型查询指标定义列表
*
* @param type 指标类型
* @return 指标定义列表
*/
default List<IndicatorDefinitionDO> selectListByType(String type) {
return selectList(new LambdaQueryWrapper<IndicatorDefinitionDO>()
.eq(IndicatorDefinitionDO::getType, type));
}
/**
* 查询所有启用的指标定义
*
* @return 启用的指标定义列表
*/
default List<IndicatorDefinitionDO> selectListByEnabled() {
return selectList(new LambdaQueryWrapper<IndicatorDefinitionDO>()
.eq(IndicatorDefinitionDO::getEnabled, true));
}
}
@@ -0,0 +1,77 @@
package com.stock.trade.indicator.dal.mysql;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.stock.trade.framework.mybatis.core.mapper.BaseMapperX;
import com.stock.trade.indicator.dal.dataobject.IndicatorValueDO;
import org.apache.ibatis.annotations.Mapper;
import java.time.LocalDateTime;
import java.util.List;
/**
* 技术指标计算结果 Mapper
*
* @author tianxin
*/
@Mapper
public interface IndicatorValueMapper extends BaseMapperX<IndicatorValueDO> {
/**
* 根据指标定义ID和股票代码查询最新的计算结果
*
* @param definitionId 指标定义ID
* @param stockCode 股票代码
* @return 最新的计算结果
*/
default IndicatorValueDO selectLatestByDefinitionIdAndStockCode(Long definitionId, String stockCode) {
return selectOne(new LambdaQueryWrapper<IndicatorValueDO>()
.eq(IndicatorValueDO::getDefinitionId, definitionId)
.eq(IndicatorValueDO::getStockCode, stockCode)
.orderByDesc(IndicatorValueDO::getCalculationTime)
.last("LIMIT 1"));
}
/**
* 查询指定时间范围内的计算结果
*
* @param definitionId 指标定义ID
* @param stockCode 股票代码
* @param startTime 开始时间
* @param endTime 结束时间
* @return 计算结果列表
*/
default List<IndicatorValueDO> selectListByTimeRange(Long definitionId, String stockCode,
LocalDateTime startTime, LocalDateTime endTime) {
return selectList(new LambdaQueryWrapper<IndicatorValueDO>()
.eq(IndicatorValueDO::getDefinitionId, definitionId)
.eq(IndicatorValueDO::getStockCode, stockCode)
.between(IndicatorValueDO::getCalculationTime, startTime, endTime)
.orderByAsc(IndicatorValueDO::getCalculationTime));
}
/**
* 查询指定状态的计算结果
*
* @param status 计算状态
* @return 计算结果列表
*/
default List<IndicatorValueDO> selectListByStatus(String status) {
return selectList(new LambdaQueryWrapper<IndicatorValueDO>()
.eq(IndicatorValueDO::getStatus, status));
}
/**
* 批量更新指标计算结果的状态
*
* @param ids 指标值ID列表
* @param status 新状态
* @return 更新的记录数
*/
default int updateStatusBatch(List<Long> ids, String status) {
return update(null, new LambdaUpdateWrapper<IndicatorValueDO>()
.in(IndicatorValueDO::getId, ids)
.set(IndicatorValueDO::getStatus, status));
}
}
@@ -0,0 +1,19 @@
package com.stock.trade.indicator.enums;
import com.stock.trade.framework.common.exception.ErrorCode;
/**
* Indicator 错误码枚举类
*
* indicator 系统,使用 1-004-000-000 段
*/
public interface ErrorCodeConstants {
// ========== 指标定义 1-004-000-000 ========== //
ErrorCode INDICATOR_DEFINITION_NOT_EXISTS = new ErrorCode(1_004_000_000, "指标定义不存在");
ErrorCode INDICATOR_DEFINITION_NAME_EXISTS = new ErrorCode(1_004_000_001, "指标定义名称已存在");
// ========== 指标计算结果 1-004-001-000 ========== //
ErrorCode INDICATOR_VALUE_NOT_EXISTS = new ErrorCode(1_004_001_000, "指标计算结果不存在");
}
@@ -0,0 +1,37 @@
package com.stock.trade.indicator.job;
import com.stock.trade.indicator.service.IndicatorValueService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
/**
* 技术指标定时计算任务
*
* @author tianxin
*/
@Component
@Slf4j
public class IndicatorJob {
@Resource
private IndicatorValueService indicatorValueService;
/**
* 定时触发所有启用的技术指标计算
* TODO 后续可以优化为分布式任务调度,例如 XXL-Job
*/
@Scheduled(cron = "0 0 1 * * ?") // 每天凌晨1点执行
public void execute() {
log.info("[execute][开始执行技术指标计算任务]");
try {
indicatorValueService.triggerAllIndicatorCalculation();
log.info("[execute][技术指标计算任务执行成功]");
} catch (Exception e) {
log.error("[execute][技术指标计算任务执行失败]", e);
}
}
}
@@ -0,0 +1,96 @@
package com.stock.trade.indicator.service;
import com.stock.trade.framework.common.pojo.PageResult;
import com.stock.trade.indicator.controller.vo.IndicatorDefinitionCreateReqVO;
import com.stock.trade.indicator.controller.vo.IndicatorDefinitionPageReqVO;
import com.stock.trade.indicator.controller.vo.IndicatorDefinitionUpdateReqVO;
import com.stock.trade.indicator.dal.dataobject.IndicatorDefinitionDO;
import javax.validation.Valid;
import java.util.List;
/**
* 技术指标定义 Service 接口
*
* @author tianxin
*/
public interface IndicatorDefinitionService {
/**
* 创建技术指标定义
*
* @param createReqVO 创建信息
* @return 指标定义ID
*/
Long createIndicatorDefinition(@Valid IndicatorDefinitionCreateReqVO createReqVO);
/**
* 更新技术指标定义
*
* @param updateReqVO 更新信息
*/
void updateIndicatorDefinition(@Valid IndicatorDefinitionUpdateReqVO updateReqVO);
/**
* 删除技术指标定义
*
* @param id 指标定义ID
*/
void deleteIndicatorDefinition(Long id);
/**
* 获取技术指标定义
*
* @param id 指标定义ID
* @return 指标定义
*/
IndicatorDefinitionDO getIndicatorDefinition(Long id);
/**
* 获取技术指标定义列表
*
* @param ids 指标定义ID列表
* @return 指标定义列表
*/
List<IndicatorDefinitionDO> getIndicatorDefinitionList(List<Long> ids);
/**
* 获取技术指标定义分页
*
* @param pageReqVO 分页查询
* @return 指标定义分页
*/
PageResult<IndicatorDefinitionDO> getIndicatorDefinitionPage(IndicatorDefinitionPageReqVO pageReqVO);
/**
* 根据指标名称获取技术指标定义
*
* @param name 指标名称
* @return 指标定义
*/
IndicatorDefinitionDO getIndicatorDefinitionByName(String name);
/**
* 根据指标类型获取技术指标定义列表
*
* @param type 指标类型
* @return 指标定义列表
*/
List<IndicatorDefinitionDO> getIndicatorDefinitionListByType(String type);
/**
* 获取所有启用的技术指标定义
*
* @return 启用的指标定义列表
*/
List<IndicatorDefinitionDO> getEnabledIndicatorDefinitionList();
/**
* 更新技术指标定义状态
*
* @param id 指标定义ID
* @param enabled 是否启用
*/
void updateIndicatorDefinitionStatus(Long id, Boolean enabled);
}
@@ -0,0 +1,120 @@
package com.stock.trade.indicator.service;
import com.stock.trade.framework.common.pojo.PageResult;
import com.stock.trade.indicator.controller.vo.indicator.value.*;
import com.stock.trade.indicator.dal.dataobject.IndicatorValueDO;
import javax.validation.Valid;
import java.time.LocalDateTime;
import java.util.List;
/**
* 技术指标计算结果 Service 接口
*
* @author AI Assistant
*/
public interface IndicatorValueService {
/**
* 创建指标计算结果
*
* @param createReqVO 创建信息
* @return 指标计算结果ID
*/
Long createIndicatorValue(@Valid IndicatorValueCreateReqVO createReqVO);
/**
* 更新指标计算结果
*
* @param updateReqVO 更新信息
*/
void updateIndicatorValue(@Valid IndicatorValueUpdateReqVO updateReqVO);
/**
* 删除指标计算结果
*
* @param id 指标计算结果ID
*/
void deleteIndicatorValue(Long id);
/**
* 获取指标计算结果
*
* @param id 指标计算结果ID
* @return 指标计算结果
*/
IndicatorValueDO getIndicatorValue(Long id);
/**
* 获取指标计算结果列表
*
* @param ids 指标计算结果ID列表
* @return 指标计算结果列表
*/
List<IndicatorValueDO> getIndicatorValueList(List<Long> ids);
/**
* 获取指标计算结果分页
*
* @param pageReqVO 分页查询
* @return 指标计算结果分页
*/
PageResult<IndicatorValueDO> getIndicatorValuePage(IndicatorValuePageReqVO pageReqVO);
/**
* 获取指标计算结果列表, 用于 Excel 导出
*
* @param exportReqVO 查询条件
* @return 指标计算结果列表
*/
List<IndicatorValueDO> getIndicatorValueList(IndicatorValueExportReqVO exportReqVO);
/**
* 获取最新的指标计算结果
*
* @param indicatorDefinitionId 指标定义ID
* @param stockCode 股票代码
* @param period 时间周期
* @return 指标计算结果
*/
IndicatorValueDO getLatestIndicatorValue(Long indicatorDefinitionId, String stockCode, String period);
/**
* 获取指定时间范围内的指标计算结果列表
*
* @param indicatorDefinitionId 指标定义ID
* @param stockCode 股票代码
* @param period 时间周期
* @param startTime 开始时间
* @param endTime 结束时间
* @return 指标计算结果列表
*/
List<IndicatorValueDO> getIndicatorValueListByTimeRange(Long indicatorDefinitionId, String stockCode,
String period, LocalDateTime startTime, LocalDateTime endTime);
/**
* 获取指定状态的指标计算结果列表
*
* @param status 计算状态
* @return 指标计算结果列表
*/
List<IndicatorValueDO> getIndicatorValueListByStatus(String status);
/**
* 批量更新指标计算结果状态
*
* @param ids 指标计算结果ID列表
* @param status 新状态
* @param errorMessage 错误信息(可选)
*/
void updateIndicatorValueStatusBatch(List<Long> ids, String status, String errorMessage);
/**
* 触发指标计算
*
* @param calculateReqVO 计算请求信息
* @return 指标计算结果ID列表
*/
List<Long> calculateIndicatorValue(@Valid IndicatorValueCalculateReqVO calculateReqVO);
}
@@ -0,0 +1,192 @@
package com.stock.trade.indicator.service.impl;
import com.stock.trade.framework.common.pojo.PageResult;
import com.stock.trade.indicator.controller.vo.IndicatorDefinitionCreateReqVO;
import com.stock.trade.indicator.controller.vo.IndicatorDefinitionPageReqVO;
import com.stock.trade.indicator.controller.vo.IndicatorDefinitionUpdateReqVO;
import com.stock.trade.indicator.convert.IndicatorDefinitionConvert;
import com.stock.trade.indicator.dal.dataobject.IndicatorDefinitionDO;
import com.stock.trade.indicator.dal.mysql.IndicatorDefinitionMapper;
import com.stock.trade.indicator.service.IndicatorDefinitionService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource;
import java.util.List;
import static com.stock.trade.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.stock.trade.indicator.enums.ErrorCodeConstants.*;
/**
* 技术指标定义 Service 实现类
*
* @author tianxin
*/
@Service
@Validated
@Slf4j
public class IndicatorDefinitionServiceImpl implements IndicatorDefinitionService {
@Resource
private IndicatorDefinitionMapper indicatorDefinitionMapper;
/**
* 创建技术指标定义
*
* @param createReqVO 创建信息
* @return 指标定义ID
*/
@Override
public Long createIndicatorDefinition(IndicatorDefinitionCreateReqVO createReqVO) {
// 校验名称唯一性
validateIndicatorDefinitionNameUnique(null, createReqVO.getName());
// 插入
IndicatorDefinitionDO indicatorDefinition = IndicatorDefinitionConvert.INSTANCE.convert(createReqVO);
indicatorDefinitionMapper.insert(indicatorDefinition);
// 返回
return indicatorDefinition.getId();
}
/**
* 更新技术指标定义
*
* @param updateReqVO 更新信息
*/
@Override
public void updateIndicatorDefinition(IndicatorDefinitionUpdateReqVO updateReqVO) {
// 校验存在
validateIndicatorDefinitionExists(updateReqVO.getId());
// 校验名称唯一性
validateIndicatorDefinitionNameUnique(updateReqVO.getId(), updateReqVO.getName());
// 更新
IndicatorDefinitionDO updateObj = IndicatorDefinitionConvert.INSTANCE.convert(updateReqVO);
indicatorDefinitionMapper.updateById(updateObj);
}
/**
* 删除技术指标定义
*
* @param id 指标定义ID
*/
@Override
public void deleteIndicatorDefinition(Long id) {
// 校验存在
validateIndicatorDefinitionExists(id);
// 删除
indicatorDefinitionMapper.deleteById(id);
}
/**
* 校验技术指标定义是否存在
*
* @param id 指标定义ID
*/
private void validateIndicatorDefinitionExists(Long id) {
if (indicatorDefinitionMapper.selectById(id) == null) {
throw exception(INDICATOR_DEFINITION_NOT_EXISTS);
}
}
/**
* 校验技术指标定义名称的唯一性
*
* @param id 指标定义ID,可为空,用于更新时排除自身
* @param name 指标名称
*/
private void validateIndicatorDefinitionNameUnique(Long id, String name) {
IndicatorDefinitionDO definition = indicatorDefinitionMapper.selectByName(name);
if (definition == null) {
return;
}
// 如果 id 为空,说明不用排除自身
if (id == null) {
throw exception(INDICATOR_DEFINITION_NAME_DUPLICATE);
}
if (!definition.getId().equals(id)) {
throw exception(INDICATOR_DEFINITION_NAME_DUPLICATE);
}
}
/**
* 获取技术指标定义
*
* @param id 指标定义ID
* @return 指标定义
*/
@Override
public IndicatorDefinitionDO getIndicatorDefinition(Long id) {
return indicatorDefinitionMapper.selectById(id);
}
/**
* 获取技术指标定义列表
*
* @param ids 指标定义ID列表
* @return 指标定义列表
*/
@Override
public List<IndicatorDefinitionDO> getIndicatorDefinitionList(List<Long> ids) {
return indicatorDefinitionMapper.selectBatchIds(ids);
}
/**
* 获取技术指标定义分页
*
* @param pageReqVO 分页查询
* @return 指标定义分页
*/
@Override
public PageResult<IndicatorDefinitionDO> getIndicatorDefinitionPage(IndicatorDefinitionPageReqVO pageReqVO) {
return indicatorDefinitionMapper.selectPage(pageReqVO, IndicatorDefinitionConvert.INSTANCE.convert(pageReqVO));
}
/**
* 根据指标名称获取技术指标定义
*
* @param name 指标名称
* @return 指标定义
*/
@Override
public IndicatorDefinitionDO getIndicatorDefinitionByName(String name) {
return indicatorDefinitionMapper.selectByName(name);
}
/**
* 根据指标类型获取技术指标定义列表
*
* @param type 指标类型
* @return 指标定义列表
*/
@Override
public List<IndicatorDefinitionDO> getIndicatorDefinitionListByType(String type) {
return indicatorDefinitionMapper.selectListByType(type);
}
/**
* 获取所有启用的技术指标定义
*
* @return 启用的指标定义列表
*/
@Override
public List<IndicatorDefinitionDO> getEnabledIndicatorDefinitionList() {
return indicatorDefinitionMapper.selectListByEnabled(true);
}
/**
* 更新技术指标定义状态
*
* @param id 指标定义ID
* @param enabled 是否启用
*/
@Override
public void updateIndicatorDefinitionStatus(Long id, Boolean enabled) {
// 校验存在
validateIndicatorDefinitionExists(id);
// 更新状态
IndicatorDefinitionDO updateObj = new IndicatorDefinitionDO();
updateObj.setId(id);
updateObj.setEnabled(enabled);
indicatorDefinitionMapper.updateById(updateObj);
}
}
@@ -0,0 +1,241 @@
package com.stock.trade.indicator.service.impl;
import com.stock.trade.framework.common.pojo.PageResult;
import com.stock.trade.indicator.controller.vo.indicator.value.*;
import com.stock.trade.indicator.convert.IndicatorValueConvert;
import com.stock.trade.indicator.dal.dataobject.IndicatorValueDO;
import com.stock.trade.indicator.dal.mysql.IndicatorValueMapper;
import com.stock.trade.indicator.service.IndicatorDefinitionService;
import com.stock.trade.indicator.service.IndicatorValueService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.Collections;
import java.util.List;
import static com.stock.trade.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.stock.trade.indicator.enums.ErrorCodeConstants.*;
/**
* 技术指标计算结果 Service 实现类
*
* @author AI Assistant
*/
@Service
@Validated
@Slf4j
public class IndicatorValueServiceImpl implements IndicatorValueService {
@Resource
private IndicatorValueMapper indicatorValueMapper;
@Resource
private IndicatorDefinitionService indicatorDefinitionService; // 用于校验指标定义是否存在等
/**
* 创建指标计算结果
*
* @param createReqVO 创建信息
* @return 指标计算结果ID
*/
@Override
public Long createIndicatorValue(IndicatorValueCreateReqVO createReqVO) {
// 校验指标定义是否存在
validateIndicatorDefinitionExists(createReqVO.getDefinitionId());
IndicatorValueDO indicatorValue = IndicatorValueConvert.INSTANCE.convert(createReqVO);
indicatorValueMapper.insert(indicatorValue);
return indicatorValue.getId();
}
/**
* 更新指标计算结果
*
* @param updateReqVO 更新信息
*/
@Override
public void updateIndicatorValue(IndicatorValueUpdateReqVO updateReqVO) {
// 校验存在
validateIndicatorValueExists(updateReqVO.getId());
// 校验指标定义是否存在
validateIndicatorDefinitionExists(updateReqVO.getDefinitionId());
IndicatorValueDO updateObj = IndicatorValueConvert.INSTANCE.convert(updateReqVO);
indicatorValueMapper.updateById(updateObj);
}
/**
* 删除指标计算结果
*
* @param id 指标计算结果ID
*/
@Override
public void deleteIndicatorValue(Long id) {
// 校验存在
validateIndicatorValueExists(id);
indicatorValueMapper.deleteById(id);
}
/**
* 获取指标计算结果
*
* @param id 指标计算结果ID
* @return 指标计算结果
*/
@Override
public IndicatorValueDO getIndicatorValue(Long id) {
return indicatorValueMapper.selectById(id);
}
/**
* 获取指标计算结果列表
*
* @param ids 指标计算结果ID列表
* @return 指标计算结果列表
*/
@Override
public List<IndicatorValueDO> getIndicatorValueList(List<Long> ids) {
if (ids == null || ids.isEmpty()) {
return Collections.emptyList();
}
return indicatorValueMapper.selectBatchIds(ids);
}
/**
* 获取指标计算结果分页
*
* @param pageReqVO 分页查询
* @return 指标计算结果分页
*/
@Override
public PageResult<IndicatorValueDO> getIndicatorValuePage(IndicatorValuePageReqVO pageReqVO) {
return indicatorValueMapper.selectPage(pageReqVO, IndicatorValueConvert.INSTANCE.convert(pageReqVO));
}
/**
* 获取指标计算结果列表, 用于 Excel 导出
*
* @param exportReqVO 查询条件
* @return 指标计算结果列表
*/
@Override
public List<IndicatorValueDO> getIndicatorValueList(IndicatorValueExportReqVO exportReqVO) {
return indicatorValueMapper.selectList(IndicatorValueConvert.INSTANCE.convert(exportReqVO));
}
/**
* 获取最新的指标计算结果
*
* @param indicatorDefinitionId 指标定义ID
* @param stockCode 股票代码
* @param period 时间周期
* @return 指标计算结果
*/
@Override
public IndicatorValueDO getLatestIndicatorValue(Long indicatorDefinitionId, String stockCode, String period) {
// 校验指标定义是否存在
validateIndicatorDefinitionExists(indicatorDefinitionId);
return indicatorValueMapper.selectLatest(indicatorDefinitionId, stockCode, period);
}
/**
* 获取指定时间范围内的指标计算结果列表
*
* @param indicatorDefinitionId 指标定义ID
* @param stockCode 股票代码
* @param period 时间周期
* @param startTime 开始时间
* @param endTime 结束时间
* @return 指标计算结果列表
*/
@Override
public List<IndicatorValueDO> getIndicatorValueListByTimeRange(Long indicatorDefinitionId, String stockCode, String period, LocalDateTime startTime, LocalDateTime endTime) {
// 校验指标定义是否存在
validateIndicatorDefinitionExists(indicatorDefinitionId);
return indicatorValueMapper.selectListByTimeRange(indicatorDefinitionId, stockCode, period, startTime, endTime);
}
/**
* 获取指定状态的指标计算结果列表
*
* @param status 计算状态
* @return 指标计算结果列表
*/
@Override
public List<IndicatorValueDO> getIndicatorValueListByStatus(String status) {
return indicatorValueMapper.selectListByStatus(status);
}
/**
* 批量更新指标计算结果状态
*
* @param ids 指标计算结果ID列表
* @param status 新状态
* @param errorMessage 错误信息(可选)
*/
@Override
@Transactional
public void updateIndicatorValueStatusBatch(List<Long> ids, String status, String errorMessage) {
if (ids == null || ids.isEmpty()) {
return;
}
indicatorValueMapper.updateStatusBatch(ids, status, errorMessage);
}
/**
* 触发指标计算
*
* @param calculateReqVO 计算请求信息
* @return 指标计算结果ID列表 (这里仅为示例,实际计算逻辑可能更复杂,并可能异步执行)
*/
@Override
public List<Long> calculateIndicatorValue(IndicatorValueCalculateReqVO calculateReqVO) {
// 校验指标定义是否存在
validateIndicatorDefinitionExists(calculateReqVO.getDefinitionId());
// 实际的指标计算逻辑会在这里实现,可能涉及调用行情数据、计算引擎等
// 此处仅为示例,创建一个虚拟的计算结果并返回ID
log.info("触发指标计算: {}, 股票: {}, 周期: {}, 参数: {}",
calculateReqVO.getDefinitionId(), calculateReqVO.getStockCode(),
calculateReqVO.getPeriod(), calculateReqVO.getParams());
// 模拟创建计算结果
IndicatorValueCreateReqVO createReq = new IndicatorValueCreateReqVO();
createReq.setDefinitionId(calculateReqVO.getDefinitionId());
createReq.setStockCode(calculateReqVO.getStockCode());
createReq.setTimePeriod(calculateReqVO.getPeriod());
createReq.setCalculationTime(LocalDateTime.now());
createReq.setParams("{ \"info\": \"triggered by calculateIndicatorValue\" }"); // 示例参数
createReq.setValues("{ \"MA5\": 10.5, \"MA10\": 10.2 }"); // 示例结果
createReq.setStatus("PENDING"); // 初始状态为待计算或计算中
Long valueId = createIndicatorValue(createReq);
return Collections.singletonList(valueId);
}
/**
* 校验指标计算结果是否存在
*
* @param id 指标计算结果ID
*/
private void validateIndicatorValueExists(Long id) {
if (indicatorValueMapper.selectById(id) == null) {
throw exception(INDICATOR_VALUE_NOT_EXISTS);
}
}
/**
* 校验关联的技术指标定义是否存在
*
* @param definitionId 指标定义ID
*/
private void validateIndicatorDefinitionExists(Long definitionId) {
if (indicatorDefinitionService.getIndicatorDefinition(definitionId) == null) {
throw exception(INDICATOR_DEFINITION_NOT_EXISTS);
}
}
}
@@ -0,0 +1,18 @@
package com.trade.indicator;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
/**
* 交易指标服务启动类
*/
@EnableDiscoveryClient
@SpringBootApplication
public class TradeIndicatorApplication {
public static void main(String[] args) {
SpringApplication.run(TradeIndicatorApplication.class, args);
}
}