package com.goldenchart.entity; import jakarta.persistence.*; import lombok.*; import org.hibernate.annotations.JdbcTypeCode; import org.hibernate.type.SqlTypes; import java.math.BigDecimal; import java.time.LocalDateTime; /** * 앱 전역 차트 기본 설정. * *

프론트엔드 코드에 하드코딩된 다음 값들을 DB 로 대체한다: *

*/ @Entity @Table(name = "gc_app_settings") @Getter @Setter @NoArgsConstructor @AllArgsConstructor @Builder public class GcAppSettings { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @Column(name = "device_id", length = 100, unique = true) private String deviceId; @Column(name = "user_id", unique = true) private Long userId; @Column(name = "default_symbol", length = 50, nullable = false) @Builder.Default private String defaultSymbol = "KRW-BTC"; @Column(name = "default_timeframe", length = 10, nullable = false) @Builder.Default private String defaultTimeframe = "1D"; @Column(name = "default_chart_type", length = 20, nullable = false) @Builder.Default private String defaultChartType = "candlestick"; @Column(name = "default_theme", length = 20, nullable = false) @Builder.Default private String defaultTheme = "dark"; @Column(name = "default_log_scale", nullable = false) @Builder.Default private Boolean defaultLogScale = false; @Column(name = "default_layout_id", length = 20, nullable = false) @Builder.Default private String defaultLayoutId = "1"; /** 차트·UI 시간 표시 IANA 시간대 */ @Column(name = "display_timezone", length = 64, nullable = false) @Builder.Default private String displayTimezone = "Asia/Seoul"; /** 차트 하단 시간축 표시 포맷 (예: yyyy-MM-dd HH:mm) */ @Column(name = "chart_time_format", length = 64, nullable = false) @Builder.Default private String chartTimeFormat = "MM-dd HH:mm"; /** 매매 시그널 알림 팝업 시간 표시 포맷 */ @Column(name = "trade_alert_time_format", length = 64, nullable = false) @Builder.Default private String tradeAlertTimeFormat = "MM-dd HH:mm"; /** 캔들 색상 JSON (frontend MainChartStyle 구조) */ @Column(name = "main_chart_style_json", columnDefinition = "JSON") @JdbcTypeCode(SqlTypes.JSON) private String mainChartStyleJson; /** 멀티차트 동기화 옵션 JSON (frontend SyncOptions 구조) */ @Column(name = "sync_options_json", columnDefinition = "JSON") @JdbcTypeCode(SqlTypes.JSON) private String syncOptionsJson; /** 백테스팅 완료 시 결과 팝업 자동 표시 여부 (기본 true) */ @Column(name = "bt_auto_popup", nullable = false) @Builder.Default private Boolean btAutoPopup = true; /** 백테스팅 매수/매도 마커에 금액 표시 여부 (기본 true) */ @Column(name = "bt_show_price", nullable = false) @Builder.Default private Boolean btShowPrice = true; /** 캔들 영역(오버레이) 우측 가격축 라벨·설명·금액 하이라이트 (기본 true) */ @Column(name = "chart_candle_area_price_labels", nullable = false) @Builder.Default private Boolean chartCandleAreaPriceLabels = true; /** 하단 보조지표 pane 우측 가격축 라벨·설명·금액 하이라이트 (기본 true) */ @Column(name = "chart_series_price_labels", nullable = false) @Builder.Default private Boolean chartSeriesPriceLabels = true; /** 차트 하단 거래량 바 표시 (기본 true) */ @Column(name = "chart_volume_visible", nullable = false) @Builder.Default private Boolean chartVolumeVisible = true; /** 실시간 수신 시 카드 아웃라인 형광 연두 음영 (기본 true) */ @Column(name = "chart_live_receive_highlight", nullable = false) @Builder.Default private Boolean chartLiveReceiveHighlight = true; /** 크로스헤어 이동 시 OHLC·보조지표 수치 표시 (기본 true) */ @Column(name = "chart_crosshair_info_visible", nullable = false) @Builder.Default private Boolean chartCrosshairInfoVisible = true; /** 차트 마우스오버 줌·이동 플로팅 툴바(− + ⌐↔ ‹ ›) 표시 (기본 true) */ @Column(name = "chart_hover_toolbar_visible", nullable = false) @Builder.Default private Boolean chartHoverToolbarVisible = true; /** 차트 상단 범례(tv-legend) 항목별 표시 옵션 JSON */ @Column(name = "chart_legend_options_json", columnDefinition = "JSON") @JdbcTypeCode(SqlTypes.JSON) private String chartLegendOptionsJson; /** 차트 pane 구분선 옵션 JSON (visible, color, width, lineStyle) */ @Column(name = "chart_pane_separator_json", columnDefinition = "JSON") @JdbcTypeCode(SqlTypes.JSON) private String chartPaneSeparatorJson; /** 매매 시그널 발생 시 알림 팝업 표시 여부 (기본 true) */ @Column(name = "trade_alert_popup", nullable = false) @Builder.Default private Boolean tradeAlertPopup = true; /** 매매 시그널 알림 사운드 재생 여부 */ @Column(name = "trade_alert_sound_enabled", nullable = false) @Builder.Default private Boolean tradeAlertSoundEnabled = true; /** 매매 시그널 알림음 ID (bell, chime, silent 등) */ @Column(name = "trade_alert_sound", nullable = false, length = 32) @Builder.Default private String tradeAlertSound = "bell"; /** 알림 팝업 위치: right | left | bottom */ @Column(name = "trade_alert_popup_position", nullable = false, length = 10) @Builder.Default private String tradeAlertPopupPosition = "right"; /** 알림 팝업 배치: stack | grid | strip | single */ @Column(name = "trade_alert_popup_layout", nullable = false, length = 10) @Builder.Default private String tradeAlertPopupLayout = "stack"; /** 그리드 배치 시 열 개수 (2~4) */ @Column(name = "trade_alert_popup_grid_cols", nullable = false) @Builder.Default private Integer tradeAlertPopupGridCols = 2; /** 검증 이슈 등록·단계 변경 알림 팝업 (기본 true) */ @Column(name = "verification_issue_notify", nullable = false) @Builder.Default private Boolean verificationIssueNotify = true; /** 실시간 전략 체크 마스터 ON/OFF — ON 이면 DB 관심종목 전체가 체크 대상 */ @Column(name = "live_strategy_check", nullable = false) @Builder.Default private Boolean liveStrategyCheck = false; /** 관심종목에 공통 적용할 전략 ID */ @Column(name = "live_strategy_id") private Long liveStrategyId; @Column(name = "live_execution_type", nullable = false, length = 30) @Builder.Default private String liveExecutionType = "CANDLE_CLOSE"; @Column(name = "live_position_mode", nullable = false, length = 20) @Builder.Default private String livePositionMode = "LONG_ONLY"; /** 모의투자 마스터 ON/OFF */ @Column(name = "paper_trading_enabled", nullable = false) @Builder.Default private Boolean paperTradingEnabled = true; @Column(name = "paper_initial_capital", nullable = false, precision = 20, scale = 2) @Builder.Default private BigDecimal paperInitialCapital = BigDecimal.valueOf(10_000_000); @Column(name = "paper_fee_rate_pct", nullable = false, precision = 8, scale = 4) @Builder.Default private BigDecimal paperFeeRatePct = BigDecimal.valueOf(0.05); @Column(name = "paper_slippage_pct", nullable = false, precision = 8, scale = 4) @Builder.Default private BigDecimal paperSlippagePct = BigDecimal.ZERO; @Column(name = "paper_min_order_krw", nullable = false, precision = 20, scale = 2) @Builder.Default private BigDecimal paperMinOrderKrw = BigDecimal.valueOf(5000); /** 실시간 전략 시그널 시 자동 모의매매 */ @Column(name = "paper_auto_trade_enabled", nullable = false) @Builder.Default private Boolean paperAutoTradeEnabled = false; @Column(name = "paper_auto_trade_budget_pct", nullable = false, precision = 8, scale = 4) @Builder.Default private BigDecimal paperAutoTradeBudgetPct = BigDecimal.valueOf(95); /** 가상매매 투자대상 목록 최대 종목 수 */ @Column(name = "virtual_target_max_count", nullable = false) @Builder.Default private Integer virtualTargetMaxCount = 20; /** PAPER | LIVE | BOTH — 자동매매 실행 대상 */ @Column(name = "trading_mode", nullable = false, length = 10) @Builder.Default private String tradingMode = "PAPER"; /** 실거래(Upbit API) 자동매매 ON */ @Column(name = "live_auto_trade_enabled", nullable = false) @Builder.Default private Boolean liveAutoTradeEnabled = false; @Column(name = "upbit_access_key", length = 128) private String upbitAccessKey; @Column(name = "upbit_secret_key", length = 256) private String upbitSecretKey; /** * 미체결 주문 체결 모드. * LIMIT_ONLY : 지정가 조건 충족 시에만 체결 (기본값) * NEXT_TICK : 다음 시세 틱에서 무조건 체결 * AUTO_CANCEL : 주문가 대비 paper_order_auto_cancel_pct % 초과 이탈 시 자동 취소 */ @Column(name = "paper_order_fill_mode", nullable = false, length = 20) @Builder.Default private String paperOrderFillMode = "LIMIT_ONLY"; /** AUTO_CANCEL 모드의 허용 이탈폭 (%) */ @Column(name = "paper_order_auto_cancel_pct", nullable = false, precision = 8, scale = 4) @Builder.Default private BigDecimal paperOrderAutoCancelPct = BigDecimal.valueOf(1.0); /** BACKEND_STOMP | UPBIT_DIRECT */ @Column(name = "chart_realtime_source", nullable = false, length = 20) @Builder.Default private String chartRealtimeSource = "BACKEND_STOMP"; @Column(name = "live_auto_trade_budget_pct", nullable = false, precision = 8, scale = 4) @Builder.Default private BigDecimal liveAutoTradeBudgetPct = BigDecimal.valueOf(95); @Column(name = "fcm_push_enabled", nullable = false) @Builder.Default private Boolean fcmPushEnabled = false; /** 추세검색 기본 설정 JSON */ @Column(name = "trend_search_settings_json", columnDefinition = "JSON") @JdbcTypeCode(SqlTypes.JSON) private String trendSearchSettingsJson; /** 편집기·팔레트·패널 크기·가상투자 목록 등 UI 설정 통합 JSON */ @Column(name = "ui_preferences_json", columnDefinition = "JSON") @JdbcTypeCode(SqlTypes.JSON) private String uiPreferencesJson; @Column(name = "created_at", nullable = false, updatable = false) private LocalDateTime createdAt; @Column(name = "updated_at") private LocalDateTime updatedAt; @PrePersist protected void onCreate() { createdAt = LocalDateTime.now(); updatedAt = LocalDateTime.now(); } @PreUpdate protected void onUpdate() { updatedAt = LocalDateTime.now(); } }