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:
+20
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
+183
@@ -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));
|
||||
}
|
||||
}
|
||||
+240
@@ -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);
|
||||
}
|
||||
}
|
||||
+35
@@ -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);
|
||||
|
||||
}
|
||||
+33
@@ -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);
|
||||
|
||||
}
|
||||
+68
@@ -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;
|
||||
|
||||
}
|
||||
+77
@@ -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;
|
||||
|
||||
}
|
||||
+50
@@ -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));
|
||||
}
|
||||
|
||||
}
|
||||
+77
@@ -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));
|
||||
}
|
||||
|
||||
}
|
||||
+19
@@ -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, "指标计算结果不存在");
|
||||
|
||||
}
|
||||
+37
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+96
@@ -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);
|
||||
|
||||
}
|
||||
+120
@@ -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);
|
||||
|
||||
}
|
||||
+192
@@ -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);
|
||||
}
|
||||
}
|
||||
+241
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
+18
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user