goldenChat base source add

This commit is contained in:
aidev
2026-05-23 15:11:48 +09:00
commit a4ea7762b5
2081 changed files with 1155760 additions and 0 deletions
@@ -0,0 +1,8 @@
package com.goldenchart.dto;
import lombok.Data;
@Data
public class AdminVerifyRequest {
private String password;
}
@@ -0,0 +1,58 @@
package com.goldenchart.dto;
import lombok.*;
/**
* Ta4j AnalysisCriterion 계산 결과 전체를 담는 DTO
*/
@Data @Builder @NoArgsConstructor @AllArgsConstructor
public class BacktestAnalysisDto {
// ── 기본 자본 ─────────────────────────────────────────────────────────────
double initialCapital;
double finalEquity;
// ── 수익성 지표 ──────────────────────────────────────────────────────────
/** 총 수익률 (소수, e.g. 0.152 = +15.2%) */
double totalReturnPct;
/** 총 손익 (금액) */
double totalProfitLoss;
/** 총 수익 (이익 거래 합산) */
double grossProfit;
/** 총 손실 (손실 거래 합산, 음수) */
double grossLoss;
/** 평균 거래 수익률 */
double avgReturnPct;
/** 손익비 (총이익 / |총손실|) */
double profitLossRatio;
// ── 거래 통계 ─────────────────────────────────────────────────────────────
int numberOfPositions;
int numberOfWinning;
int numberOfLosing;
int numberOfBreakEven;
/** 승률 0~1 */
double winRate;
// ── 리스크 지표 ───────────────────────────────────────────────────────────
/** 최대 낙폭 (음수, -0.15 = -15%) */
double maxDrawdownPct;
/** 최대 상승폭 */
double maxRunupPct;
/** 샤프 비율 */
double sharpeRatio;
/** 소르티노 비율 */
double sortinoRatio;
/** 칼마 비율 (총수익률 / |최대낙폭|) */
double calmarRatio;
/** Value at Risk (95%) */
double valueAtRisk95;
/** Expected Shortfall / CVaR */
double expectedShortfall;
// ── 벤치마크 비교 ─────────────────────────────────────────────────────────
/** 바이앤홀드 수익률 */
double buyAndHoldReturnPct;
/** 전략 대비 바이앤홀드 배수 (>1 이면 전략이 유리) */
double vsBuyAndHold;
}
@@ -0,0 +1,59 @@
package com.goldenchart.dto;
import com.fasterxml.jackson.databind.JsonNode;
import lombok.*;
import java.util.List;
import java.util.Map;
/**
* 백테스팅 요청 DTO.
*
* <pre>
* {
* "strategyId": 1, // DB 전략 ID (선택 — 없으면 dsl 직접 전송)
* "buyCondition": { ...LogicNode }, // 매수 조건 DSL
* "sellCondition": { ...LogicNode }, // 매도 조건 DSL
* "bars": [ {time, open, high, low, close, volume}, ... ],
* "timeframe": "1D",
* "indicatorParams": { "CCI": {"length":13}, ... } // 사용자 설정 파라미터 (선택)
* }
* </pre>
*/
@Data @Builder @NoArgsConstructor @AllArgsConstructor
public class BacktestRequest {
/** DB 저장 전략 ID (선택 — 설정 시 buyCondition/sellCondition 무시) */
private Long strategyId;
/** 매수 조건 DSL */
private JsonNode buyCondition;
/** 매도 조건 DSL */
private JsonNode sellCondition;
/** OHLCV 캔들 데이터 */
private List<OhlcvBar> bars;
/** 타임프레임 (1m/5m/15m/30m/1h/4h/1D/1W/1M) */
private String timeframe;
/**
* 지표 파라미터 오버라이드.
* key = indicatorType (e.g. "CCI"), value = {length:13, ...}
* 없으면 IndicatorService 기본값 사용.
*/
private Map<String, Map<String, Object>> indicatorParams;
/** 백테스팅 설정 옵션 (선택 — 없으면 기본값 사용) */
private BacktestSettingsDto settings;
/** 종목 코드 (결과 저장용, e.g. "KRW-BTC") */
private String symbol;
/** 전략 이름 (결과 저장용) */
private String strategyName;
/** 디바이스 ID (결과 저장용) */
private String deviceId;
}
@@ -0,0 +1,62 @@
package com.goldenchart.dto;
import lombok.*;
import java.util.List;
/**
* 백테스팅 결과 응답 DTO.
*
* <pre>
* {
* "signals": [
* { "time": 1700000000, "type": "BUY", "price": 42000 },
* { "time": 1700200000, "type": "SELL", "price": 45000 }
* ],
* "stats": { "totalTrades": 8, "winRate": 0.625, ... }
* }
* </pre>
*/
@Data @Builder @NoArgsConstructor @AllArgsConstructor
public class BacktestResponse {
private List<Signal> signals;
private Stats stats;
/** Ta4j AnalysisCriterion 전체 결과 */
private BacktestAnalysisDto analysis;
/** DB 저장 후 부여된 결과 ID */
private Long resultId;
@Data @Builder @NoArgsConstructor @AllArgsConstructor
public static class Signal {
/** Unix timestamp (초) */
private long time;
/** BUY | SELL */
private String type;
/** 해당 봉 종가 */
private double price;
/** 진입/청산 인덱스 (0-based) */
private int barIndex;
}
@Data @Builder @NoArgsConstructor @AllArgsConstructor
public static class Stats {
private int totalSignals;
private int buySignals;
private int sellSignals;
/** 거래 쌍(매수→매도) 수 */
private int totalTrades;
/** 수익 거래 수 */
private int winTrades;
/** 승률 0~1 */
private double winRate;
/** 총 수익률 (소수, e.g. 0.15 = +15%) */
private double totalReturn;
/** 최대 낙폭 (소수, 음수, e.g. -0.12 = -12%) */
private double maxDrawdown;
/** 평균 수익률 per trade */
private double avgReturn;
/** 최종 자산 (초기 자본 × 복리 수익) */
private double finalEquity;
}
}
@@ -0,0 +1,102 @@
package com.goldenchart.dto;
import lombok.*;
import java.math.BigDecimal;
/**
* 백테스팅 설정 DTO.
* Ta4j 의 비용 모델·손절/익절·트레일링 스탑·진입가격·재진입 등 모든 옵션을 담는다.
*/
@Data @Builder @NoArgsConstructor @AllArgsConstructor
public class BacktestSettingsDto {
private Long id;
// ── 자본 설정 ──────────────────────────────────────────────────────────────
/** 초기 자본 (원) */
@Builder.Default
private BigDecimal initialCapital = new BigDecimal("10000000.00");
// ── 비용 모델 ──────────────────────────────────────────────────────────────
/** LINEAR | ZERO */
@Builder.Default
private String commissionType = "LINEAR";
/** 수수료율 (예: 0.0015 = 0.15%) */
@Builder.Default
private BigDecimal commissionRate = new BigDecimal("0.00150");
/** 슬리피지율 (예: 0.0005 = 0.05%) */
@Builder.Default
private BigDecimal slippageRate = new BigDecimal("0.00050");
// ── 진입/청산 가격 ─────────────────────────────────────────────────────────
/** CLOSE | NEXT_OPEN */
@Builder.Default
private String entryPriceType = "CLOSE";
/** CLOSE | NEXT_OPEN */
@Builder.Default
private String exitPriceType = "CLOSE";
// ── 포지션 방향 ────────────────────────────────────────────────────────────
/** LONG | SHORT | BOTH */
@Builder.Default
private String positionDirection = "LONG";
// ── 거래 규모 ──────────────────────────────────────────────────────────────
/** CAPITAL_PCT | FIXED_AMOUNT */
@Builder.Default
private String tradeSizeType = "CAPITAL_PCT";
/** 비율(%) 또는 고정 금액(원) */
@Builder.Default
private BigDecimal tradeSizeValue = new BigDecimal("100.0000");
// ── 손절 (StopLossRule) ───────────────────────────────────────────────────
@Builder.Default
private Boolean stopLossEnabled = false;
/** 손절 비율 (%) */
@Builder.Default
private BigDecimal stopLossPct = new BigDecimal("2.000");
// ── 익절 (StopGainRule) ───────────────────────────────────────────────────
@Builder.Default
private Boolean takeProfitEnabled = false;
/** 익절 비율 (%) */
@Builder.Default
private BigDecimal takeProfitPct = new BigDecimal("5.000");
// ── 트레일링 스탑 (TrailingStopLossRule) ─────────────────────────────────
@Builder.Default
private Boolean trailingStopEnabled = false;
/** 트레일링 스탑 비율 (%) */
@Builder.Default
private BigDecimal trailingStopPct = new BigDecimal("2.000");
// ── 재진입 제어 ────────────────────────────────────────────────────────────
/** 매도 후 재진입 대기 봉 수 */
@Builder.Default
private Integer reentryWaitBars = 0;
/** 최대 동시 보유 포지션 수 */
@Builder.Default
private Integer maxOpenTrades = 1;
// ── 포지션 종속성 모드 ─────────────────────────────────────────────────────
/** "LONG_ONLY" | "SIGNAL_ONLY" — 매도 시그널 포지션 종속성 제어 */
@Builder.Default
private String positionMode = "LONG_ONLY";
// ── 분할 청산 ──────────────────────────────────────────────────────────────
@Builder.Default
private Boolean partialExitEnabled = false;
/** 분할 청산 비율 (%) */
@Builder.Default
private BigDecimal partialExitPct = new BigDecimal("50.000");
}
@@ -0,0 +1,44 @@
package com.goldenchart.dto;
import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* REST API / STOMP 용 캔들 데이터 전송 객체.
*
* REST : GET /api/candles/history 응답 배열 요소
* STOMP : /sub/charts/{market}/{type} 실시간 경량 페이로드
*
* 명세서 5.1 / 5.2 포맷 준수:
* - time : Unix 초 타임스탬프
* - o/h/l/c/v : OHLCV
* - rsi : RSI 값 (null 허용)
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@JsonInclude(JsonInclude.Include.NON_NULL)
public class CandleBarDto {
/** Unix 초 타임스탬프 (캔들 시작 시간) */
private long time;
private double open;
private double high;
private double low;
private double close;
private double volume;
/** RSI 값. 계산 불가 구간(워밍업)에서는 null */
private Double rsi;
/**
* 실시간 전략 체크 시그널.
* "BUY" | "SELL" | "NONE" (null 이면 전략 체크 미설정)
*/
private String signal;
}
@@ -0,0 +1,12 @@
package com.goldenchart.dto;
import lombok.Data;
@Data
public class CreateUserRequest {
private String username;
private String password;
private String displayName;
private String role;
private Boolean enabled;
}
@@ -0,0 +1,10 @@
package com.goldenchart.dto;
import lombok.Data;
@Data
public class FcmTokenDto {
private String token;
private Long userId;
private String deviceId;
}
@@ -0,0 +1,18 @@
package com.goldenchart.dto;
import lombok.Data;
import java.util.List;
import java.util.Map;
@Data
public class IndicatorRequest {
private String symbol;
private String timeframe;
/** 지표 타입 (RSI, MACD, BollingerBands ...) */
private String indicatorType;
/** 지표 파라미터 */
private Map<String, Object> params;
/** 직접 캔들 데이터 전달 (선택: 없으면 DB에서 조회) */
private List<OhlcvBar> bars;
}
@@ -0,0 +1,34 @@
package com.goldenchart.dto;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
import java.util.Map;
/**
* 지표 계산 결과 응답.
* frontend PlotData 구조와 1:1 매핑.
*/
@Data @Builder @NoArgsConstructor @AllArgsConstructor
public class IndicatorResponse {
private String symbol;
private String timeframe;
private String indicatorType;
/** time 배열 (Unix 초) */
private List<Long> times;
/**
* plot ID → [{time, value, color?}] 배열.
* e.g. MACD: {"histogram":[...], "macd":[...], "signal":[...]}
*/
private Map<String, List<PlotPoint>> values;
@Data @Builder @NoArgsConstructor @AllArgsConstructor
public static class PlotPoint {
private long time;
private Double value;
private String color;
}
}
@@ -0,0 +1,17 @@
package com.goldenchart.dto;
import lombok.Data;
@Data
public class LiveOrderRequest {
private String market;
/** BUY | SELL */
private String side;
/** market | limit — 현재 market 만 지원 */
private String orderKind;
/** 시장가 매수 시 KRW 금액 (미지정 시 예산 % 적용) */
private Double krwAmount;
/** 시장가 매도 시 수량 (미지정 시 전량) */
private Double quantity;
private Long strategyId;
}
@@ -0,0 +1,22 @@
package com.goldenchart.dto;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
/** 관심종목 등 여러 마켓에 동일한 실시간 전략 설정을 일괄 적용 */
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class LiveStrategyBulkRequest {
/** 적용할 마켓 코드 목록 (e.g. KRW-BTC) */
private List<String> markets;
/** 각 마켓에 복사할 설정 (market 필드는 서버에서 markets 항목으로 덮어씀) */
private LiveStrategySettingsDto template;
}
@@ -0,0 +1,39 @@
package com.goldenchart.dto;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* 실시간 전략 체크 설정 DTO.
* PUT /api/strategy/settings (요청/응답 공용)
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class LiveStrategySettingsDto {
/** 업비트 마켓 코드 (e.g. "KRW-BTC") */
private String market;
/** 연결된 전략 ID (null = 미연결) */
private Long strategyId;
/** 실시간 체크 ON/OFF (JSON 키: isLiveCheck) */
@JsonProperty("isLiveCheck")
private boolean liveCheck;
/** "CANDLE_CLOSE" | "REALTIME_TICK" */
private String executionType;
/** 전략 평가 분봉: 1m, 3m, 5m, 15m, 30m, 1h, 4h, 1d */
@Builder.Default
private String candleType = "1m";
/** 매도 시그널 포지션 종속성 모드: "LONG_ONLY" | "SIGNAL_ONLY" */
@Builder.Default
private String positionMode = "LONG_ONLY";
}
@@ -0,0 +1,30 @@
package com.goldenchart.dto;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class LiveSummaryDto {
private boolean enabled;
private boolean configured;
private String tradingMode;
private double krwBalance;
private List<Position> positions;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public static class Position {
private String symbol;
private double quantity;
private double avgPrice;
}
}
@@ -0,0 +1,22 @@
package com.goldenchart.dto;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class LiveTradeDto {
private Long id;
private String symbol;
private String side;
private String source;
private double price;
private double quantity;
private double grossAmount;
private String upbitOrderUuid;
private String createdAt;
}
@@ -0,0 +1,9 @@
package com.goldenchart.dto;
import lombok.Data;
@Data
public class LoginRequest {
private String username;
private String password;
}
@@ -0,0 +1,18 @@
package com.goldenchart.dto;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class LoginResponse {
private Long userId;
private String username;
private String displayName;
/** ADMIN | USER | GUEST */
private String role;
}
@@ -0,0 +1,17 @@
package com.goldenchart.dto;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.Map;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class MenuPermissionsResponse {
private String role;
private Map<String, Boolean> permissions;
}
@@ -0,0 +1,21 @@
package com.goldenchart.dto;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* OHLCV 캔들 데이터 DTO.
* frontend OHLCVBar 와 동일 구조.
*/
@Data @Builder @NoArgsConstructor @AllArgsConstructor
public class OhlcvBar {
/** Unix timestamp (초) */
private long time;
private double open;
private double high;
private double low;
private double close;
private double volume;
}
@@ -0,0 +1,18 @@
package com.goldenchart.dto;
import lombok.Data;
@Data
public class PaperOrderRequest {
private String market;
private String side; // BUY | SELL
private String orderKind; // limit | market
private Double price;
private Double quantity;
/** 수량 미입력 시 매수 예산 비율 (가용현금 %) — 기본값: 설정의 paperAutoTradeBudgetPct */
private Double budgetPct;
/** 수량 미입력 시 매수 고정 금액 (KRW) — budgetPct보다 우선 */
private Double krwAmount;
private String source; // MANUAL | STRATEGY (optional)
private Long strategyId;
}
@@ -0,0 +1,19 @@
package com.goldenchart.dto;
import lombok.Builder;
import lombok.Data;
@Data
@Builder
public class PaperPositionDto {
private Long id;
private String symbol;
private String koreanName;
private Double quantity;
private Double avgPrice;
/** 프론트가 현재가를 넣어 평가손익 계산 시 사용 (선택) */
private Double markPrice;
private Double evalAmount;
private Double profitLoss;
private Double profitLossPct;
}
@@ -0,0 +1,25 @@
package com.goldenchart.dto;
import lombok.Builder;
import lombok.Data;
import java.util.List;
@Data
@Builder
public class PaperSummaryDto {
private Boolean enabled;
private Double initialCapital;
private Double cashBalance;
private Double stockEvalAmount;
private Double totalAsset;
private Double unrealizedPnl;
private Double realizedPnl;
private Double totalReturnPct;
private Double feeRatePct;
private Double slippagePct;
private Double minOrderKrw;
private Boolean autoTradeEnabled;
private Double autoTradeBudgetPct;
private List<PaperPositionDto> positions;
}
@@ -0,0 +1,22 @@
package com.goldenchart.dto;
import lombok.Builder;
import lombok.Data;
@Data
@Builder
public class PaperTradeDto {
private Long id;
private String symbol;
private String side;
private String orderKind;
private String source;
private Long strategyId;
private Double price;
private Double quantity;
private Double grossAmount;
private Double feeAmount;
private Double netAmount;
private Double cashAfter;
private String createdAt;
}
@@ -0,0 +1,11 @@
package com.goldenchart.dto;
import lombok.Data;
import java.util.Map;
@Data
public class RolePermissionsUpdateRequest {
private String role;
private Map<String, Boolean> permissions;
}
@@ -0,0 +1,29 @@
package com.goldenchart.dto;
import com.fasterxml.jackson.annotation.JsonRawValue;
import com.fasterxml.jackson.databind.JsonNode;
import lombok.*;
import java.time.LocalDateTime;
/**
* 투자전략 CRUD DTO.
* frontend StrategyDto 와 1:1 대응.
*/
@Data @Builder @NoArgsConstructor @AllArgsConstructor
public class StrategyDto {
private Long id;
private String name;
private String description;
/** 매수 조건 LogicNode 트리 (JSON 그대로 직렬화) */
private JsonNode buyCondition;
/** 매도 조건 LogicNode 트리 (JSON 그대로 직렬화) */
private JsonNode sellCondition;
private Boolean enabled;
private LocalDateTime createdAt;
private LocalDateTime updatedAt;
}
@@ -0,0 +1,28 @@
package com.goldenchart.dto;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* 매매 시그널 이력 DTO.
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class TradeSignalDto {
private Long id;
private String market;
private Long strategyId;
private String strategyName;
/** BUY | SELL */
private String signalType;
private Double price;
private Long candleTime;
private String candleType;
/** CANDLE_CLOSE | REALTIME_TICK */
private String executionType;
private String createdAt;
}
@@ -0,0 +1,11 @@
package com.goldenchart.dto;
import lombok.Builder;
@Builder
public record UpbitApiCredentials(String accessKey, String secretKey) {
public boolean isComplete() {
return accessKey != null && !accessKey.isBlank()
&& secretKey != null && !secretKey.isBlank();
}
}
@@ -0,0 +1,11 @@
package com.goldenchart.dto;
import lombok.Data;
@Data
public class UpdateUserRequest {
private String password;
private String displayName;
private String role;
private Boolean enabled;
}
@@ -0,0 +1,19 @@
package com.goldenchart.dto;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class UserDto {
private Long id;
private String username;
private String displayName;
private String role;
private Boolean enabled;
private String createdAt;
}