Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
## 변경사항
- 내용을 적어주세요.

## 상세내용
- 내용을 적어주세요.
## TODO
- [ ] Todo1
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.tradin.common.exception;

import com.tradin.common.response.ApiResponse;
import com.tradin.common.response.TradinResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ExceptionHandler;
Expand All @@ -11,15 +11,17 @@
public class GlobalExceptionHandler {

@ExceptionHandler(TradinException.class)
protected ResponseEntity<ApiResponse<?>> handleTradinException(TradinException e) {
protected ResponseEntity<TradinResponse<?>> handleTradinException(TradinException e) {
log.error("TradinException: {}", e.getMessage(), e);

return new ResponseEntity<>(ApiResponse.error(e.getErrorType(), e.getData()), e.getErrorType().getHttpStatus());
return new ResponseEntity<>(
TradinResponse.error(e.getErrorType(), e.getData()), e.getErrorType().getHttpStatus());
}

@ExceptionHandler(Exception.class)
protected ResponseEntity<ApiResponse<?>> handleAllExceptions(Exception e) {
protected ResponseEntity<TradinResponse<?>> handleAllExceptions(Exception e) {
log.error("Exception: {}", e.getMessage(), e);
return new ResponseEntity<>(ApiResponse.error(ExceptionType.INTERNAL_SERVER_ERROR_EXCEPTION, e.getMessage()), ExceptionType.INTERNAL_SERVER_ERROR_EXCEPTION.getHttpStatus());
return new ResponseEntity<>(
TradinResponse.error(ExceptionType.INTERNAL_SERVER_ERROR_EXCEPTION, e.getMessage()), ExceptionType.INTERNAL_SERVER_ERROR_EXCEPTION.getHttpStatus());
}
}
38 changes: 0 additions & 38 deletions src/main/java/com/tradin/common/response/ApiResponse.java

This file was deleted.

38 changes: 38 additions & 0 deletions src/main/java/com/tradin/common/response/TradinResponse.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package com.tradin.common.response;


import com.tradin.common.exception.ExceptionMessage;
import com.tradin.common.exception.ExceptionType;
import lombok.Getter;

@Getter
public class TradinResponse<S> {

private final ResultType result;

private final S data;

private final ExceptionMessage error;

private TradinResponse(ResultType result, S data, ExceptionMessage error) {
this.result = result;
this.data = data;
this.error = error;
}

public static TradinResponse<?> success() {
return new TradinResponse<>(ResultType.SUCCESS, null, null);
}

public static <S> TradinResponse<S> success(S data) {
return new TradinResponse<>(ResultType.SUCCESS, data, null);
}

public static TradinResponse<?> error(ExceptionType error) {
return new TradinResponse<>(ResultType.ERROR, null, new ExceptionMessage(error));
}

public static TradinResponse<?> error(ExceptionType error, Object errorData) {
return new TradinResponse<>(ResultType.ERROR, null, new ExceptionMessage(error, errorData));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.tradin.module.strategy.controller;

import com.tradin.common.response.TradinResponse;
import com.tradin.module.strategy.controller.dto.response.FindStrategiesInfoResponseDto;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;


@Tag(name = "전략", description = "전략 관련 API")
public interface StrategyApi {

@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "성공")
})
@Operation(summary = "선물 전략 조회")
TradinResponse<FindStrategiesInfoResponseDto> findFutureStrategiesInfos();

@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "성공")
})
@Operation(summary = "현물 전략 조회")
FindStrategiesInfoResponseDto findSpotStrategiesInfos();

}
Original file line number Diff line number Diff line change
@@ -1,91 +1,44 @@
package com.tradin.module.strategy.controller;

import com.tradin.common.annotation.DisableAuthInSwagger;
import com.tradin.module.strategy.controller.dto.request.SubscribeStrategyRequestDto;
import com.tradin.module.strategy.controller.dto.request.UnSubscribeStrategyRequestDto;
import com.tradin.module.strategy.controller.dto.request.WebHookRequestDto;
import com.tradin.common.response.TradinResponse;
import com.tradin.module.strategy.controller.dto.response.FindStrategiesInfoResponseDto;
import com.tradin.module.strategy.controller.dto.response.FindSubscriptionStrategiesInfoResponseDto;
import com.tradin.module.strategy.service.StrategyService;
import io.swagger.v3.oas.annotations.Operation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.kafka.annotation.KafkaListener;
import org.springframework.web.bind.annotation.*;

import jakarta.validation.Valid;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequiredArgsConstructor
@RequestMapping("/v1/strategies")
@Slf4j
public class StrategyController {
public class StrategyController implements StrategyApi {
private final StrategyService strategyService;

// @KafkaListener(topics = "tradin", groupId = "trading-strategy-executors")
// public void test(@RequestBody WebHookRequestDto request) {
// strategyService.handleFutureWebHook(request.toServiceDto());
// }
//
// @KafkaListener(topics = "future-short-term-v1", groupId = "trading-strategy-executors")
// public void handleFutureShortTermV1WebHook(@RequestBody WebHookRequestDto request) {
// strategyService.handleFutureWebHook(request.toServiceDto());
// }
//
// @KafkaListener(topics = "future-mid-term-v1", groupId = "trading-strategy-executors")
// public void handleFutureMidTermV1WebHook(@RequestBody WebHookRequestDto request) {
// strategyService.handleFutureWebHook(request.toServiceDto());
// }
//
// @KafkaListener(topics = "future-long-term-v1", groupId = "trading-strategy-executors")
// public void handleFutureLongTermV1WebHook(@RequestBody WebHookRequestDto request) {
// strategyService.handleFutureWebHook(request.toServiceDto());
// }
//
// @KafkaListener(topics = "spot-short-term-v1", groupId = "trading-strategy-executors")
// public void handleSpotShortTermV1WebHook(@RequestBody WebHookRequestDto request) {
// strategyService.handleSpotWebHook(request.toServiceDto());
// }
//
// @KafkaListener(topics = "spot-mid-term-v1", groupId = "trading-strategy-executors")
// public void handleSpotMidTermV1WebHook(@RequestBody WebHookRequestDto request) {
// strategyService.handleSpotWebHook(request.toServiceDto());
// }
//
// @KafkaListener(topics = "spot-long-term-v1", groupId = "trading-strategy-executors")
// public void handleSpotLongTermV1WebHook(@RequestBody WebHookRequestDto request) {
// strategyService.handleSpotWebHook(request.toServiceDto());
// }

@Operation(summary = "선물 전략 전체 조회")
@DisableAuthInSwagger
@GetMapping("/future")
public FindStrategiesInfoResponseDto findFutureStrategiesInfos() {
return strategyService.findFutureStrategiesInfo();
public TradinResponse<FindStrategiesInfoResponseDto> findFutureStrategiesInfos() {
return TradinResponse.success(strategyService.findFutureStrategiesInfo());
}

@Operation(summary = "현물 전략 전체 조회")
@DisableAuthInSwagger
@GetMapping("/spot")
public FindStrategiesInfoResponseDto findSpotStrategiesInfos() {
return strategyService.findSpotStrategiesInfo();
}

@Operation(summary = "선물 전략 구독 리스트")
@GetMapping("/subscriptions")
public FindSubscriptionStrategiesInfoResponseDto findSubscriptionStrategiesInfos() {
return strategyService.findSubscriptionStrategiesInfo();
}

@Operation(summary = "선물 전략 구독")
@PostMapping("/{id}/subscriptions")
public void subscribe(@Valid @RequestBody SubscribeStrategyRequestDto request, @PathVariable Long id) {
strategyService.subscribeStrategy(request.toServiceDto(id));
}

@Operation(summary = "선물 전략 구독 취소")
@PatchMapping("/unsubscriptions")
public void unsubscribe(@Valid @RequestBody UnSubscribeStrategyRequestDto request) {
strategyService.unsubscribeStrategy(request.toServiceDto());
}
// @Operation(summary = "선물 전략 구독 리스트")
// @GetMapping("/subscriptions")
// public FindSubscriptionStrategiesInfoResponseDto findSubscriptionStrategiesInfos() {
// return strategyService.findSubscriptionStrategiesInfo();
// }
//
// @Operation(summary = "선물 전략 구독")
// @PostMapping("/{id}/subscriptions")
// public void subscribe(@Valid @RequestBody SubscribeStrategyRequestDto request, @PathVariable Long id) {
// strategyService.subscribeStrategy(request.toServiceDto(id));
// }
//
// @Operation(summary = "선물 전략 구독 취소")
// @PatchMapping("/unsubscriptions")
// public void unsubscribe(@Valid @RequestBody UnSubscribeStrategyRequestDto request) {
// strategyService.unsubscribeStrategy(request.toServiceDto());
// }
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
package com.tradin.module.strategy.controller.dto.response;

import com.tradin.module.strategy.domain.repository.dao.StrategyInfoDao;
import lombok.AllArgsConstructor;
import lombok.Getter;

import io.swagger.v3.oas.annotations.media.Schema;
import java.util.List;

@AllArgsConstructor
@Getter
public class FindStrategiesInfoResponseDto {
private final List<StrategyInfoDao> strategiesInfo;
}

public record FindStrategiesInfoResponseDto (
@Schema(description = "전략 리스트") List<StrategyInfoDao> strategiesInfos
) {
public static FindStrategiesInfoResponseDto of(List<StrategyInfoDao> strategiesInfos) {
return new FindStrategiesInfoResponseDto(strategiesInfos);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,62 +4,34 @@
import com.tradin.module.strategy.domain.CoinType;
import com.tradin.module.strategy.domain.TradingType;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Getter;

import java.time.LocalDateTime;

@Getter
public class StrategyInfoDao {
private final Long id;
private final String name;

@Schema(description = "코인명", example = "BITCOIN")
private final CoinType coinType;

@Schema(description = "수익팩터")
private final double profitFactor;

@Schema(description = "승률")
private final double winningRate;

@Schema(description = "단리 기준 수익률")
private final double simpleProfitRate;

@Schema(description = "복리 기준 수익률 -> 누적 손익률")
private final double compoundProfitRate;

@Schema(description = "총 수익률(수익율+손실율 아님)")
private final double totalProfitRate;

@Schema(description = "총 손실률")
private final double totalLossRate;

@Schema(description = "평균 수익률")
private final double averageProfitRate;

@Schema(description = "총 거래 횟수")
private final int totalTradeCount;

@Schema(description = "승리 횟수")
private final int winCount;

@Schema(description = "패배 횟수")
private final int lossCount;

@Schema(description = "거래 타입", example = "LONG")
private final TradingType tradingType;

@Schema(description = "진입 시간")
private final LocalDateTime time;

@Schema(description = "진입 가격")
private final int price;

@Schema(description = "평균 봉 수")
private final int averageHoldingPeriod;
@Schema(description = "전략 정보")
public record StrategyInfoDao(
@Schema(description = "전략Id", example = "1") Long id,
@Schema(description = "전략명", example = "Strategy-1") String name,
@Schema(description = "코인명", example = "BITCOIN") CoinType coinType,
@Schema(description = "수익팩터") double profitFactor,
@Schema(description = "승률") double winningRate,
@Schema(description = "단리 기준 수익률") double simpleProfitRate,
@Schema(description = "복리 기준 수익률 -> 누적 손익률") double compoundProfitRate,
@Schema(description = "총 수익률(수익율+손실율 아님)") double totalProfitRate,
@Schema(description = "총 손실률") double totalLossRate,
@Schema(description = "평균 수익률") double averageProfitRate,
@Schema(description = "총 거래 횟수") int totalTradeCount,
@Schema(description = "승리 횟수") int winCount,
@Schema(description = "패배 횟수") int lossCount,
@Schema(description = "거래 타입", example = "LONG") TradingType tradingType,
@Schema(description = "진입 시간") LocalDateTime time,
@Schema(description = "진입 가격") int price,
@Schema(description = "평균 봉 수") int averageHoldingPeriod) {

@QueryProjection
public StrategyInfoDao(Long id, String name, CoinType coinType, double profitFactor, double winningRate, double simpleProfitRate, double compoundProfitRate, double totalProfitRate, double totalLossRate, double averageProfitRate, int totalTradeCount, int winCount, int lossCount, TradingType tradingType, LocalDateTime time, int price, int averageHoldingPeriod) {
public StrategyInfoDao(Long id, String name, CoinType coinType, double profitFactor,
double winningRate, double simpleProfitRate, double compoundProfitRate,
double totalProfitRate, double totalLossRate, double averageProfitRate, int totalTradeCount,
int winCount, int lossCount, TradingType tradingType, LocalDateTime time, int price,
int averageHoldingPeriod) {
this.id = id;
this.name = name;
this.coinType = coinType;
Expand Down
Loading
Loading