goldenChat base source add
This commit is contained in:
@@ -0,0 +1,227 @@
|
||||
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;
|
||||
|
||||
/**
|
||||
* 앱 전역 차트 기본 설정.
|
||||
*
|
||||
* <p>프론트엔드 코드에 하드코딩된 다음 값들을 DB 로 대체한다:
|
||||
* <ul>
|
||||
* <li>기본 심볼 (DEFAULT_STATE.symbol → 'KRW-BTC')</li>
|
||||
* <li>기본 타임프레임 (DEFAULT_STATE.timeframe → '1D')</li>
|
||||
* <li>기본 차트 타입 ('candlestick')</li>
|
||||
* <li>기본 테마 ('dark')</li>
|
||||
* <li>기본 로그 스케일 (false)</li>
|
||||
* <li>기본 레이아웃 ID ('1')</li>
|
||||
* <li>캔들 색상 (DEFAULT_MAIN_CHART_STYLE)</li>
|
||||
* <li>멀티차트 동기화 옵션 (DEFAULT_SYNC)</li>
|
||||
* </ul>
|
||||
*/
|
||||
@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";
|
||||
|
||||
/** 캔들 색상 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_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;
|
||||
|
||||
/** 차트 상단 범례(tv-legend) 항목별 표시 옵션 JSON */
|
||||
@Column(name = "chart_legend_options_json", columnDefinition = "JSON")
|
||||
@JdbcTypeCode(SqlTypes.JSON)
|
||||
private String chartLegendOptionsJson;
|
||||
|
||||
/** 매매 시그널 발생 시 알림 팝업 표시 여부 (기본 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;
|
||||
|
||||
/** 실시간 전략 체크 마스터 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);
|
||||
|
||||
/** 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;
|
||||
|
||||
/** 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;
|
||||
|
||||
@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();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
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;
|
||||
|
||||
@Entity
|
||||
@Table(name = "gc_backtest_result")
|
||||
@Getter @Setter @NoArgsConstructor @AllArgsConstructor @Builder
|
||||
public class GcBacktestResult {
|
||||
|
||||
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private Long id;
|
||||
|
||||
@Column(name = "device_id", length = 100) private String deviceId;
|
||||
@Column(name = "strategy_id") private Long strategyId;
|
||||
@Column(name = "strategy_name", length = 200) private String strategyName;
|
||||
@Column(name = "symbol", length = 50) private String symbol;
|
||||
@Column(name = "timeframe", length = 10) private String timeframe;
|
||||
@Column(name = "bar_count") private Integer barCount;
|
||||
@Column(name = "from_time") private Long fromTime;
|
||||
@Column(name = "to_time") private Long toTime;
|
||||
|
||||
@Column(name = "settings_json", columnDefinition = "JSON")
|
||||
@JdbcTypeCode(SqlTypes.JSON) private String settingsJson;
|
||||
|
||||
@Column(name = "signals_json", columnDefinition = "JSON")
|
||||
@JdbcTypeCode(SqlTypes.JSON) private String signalsJson;
|
||||
|
||||
@Column(name = "analysis_json", columnDefinition = "JSON")
|
||||
@JdbcTypeCode(SqlTypes.JSON) private String analysisJson;
|
||||
|
||||
@Column(name = "total_return", precision = 12, scale = 4) private BigDecimal totalReturn;
|
||||
@Column(name = "win_rate", precision = 6, scale = 4) private BigDecimal winRate;
|
||||
@Column(name = "total_trades") private Integer totalTrades;
|
||||
@Column(name = "max_drawdown", precision = 12, scale = 4) private BigDecimal maxDrawdown;
|
||||
@Column(name = "sharpe_ratio", precision = 10, scale = 4) private BigDecimal sharpeRatio;
|
||||
@Column(name = "final_equity", precision = 20, scale = 2) private BigDecimal finalEquity;
|
||||
|
||||
@Column(name = "created_at", nullable = false, updatable = false)
|
||||
private LocalDateTime createdAt;
|
||||
|
||||
@PrePersist protected void onCreate() { createdAt = LocalDateTime.now(); }
|
||||
}
|
||||
@@ -0,0 +1,133 @@
|
||||
package com.goldenchart.entity;
|
||||
|
||||
import jakarta.persistence.*;
|
||||
import lombok.*;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 백테스팅 설정 엔티티.
|
||||
* Ta4j 의 비용 모델·손절/익절/트레일링 스탑·진입가격·재진입 규칙 등을 저장.
|
||||
*/
|
||||
@Entity
|
||||
@Table(name = "gc_backtest_settings")
|
||||
@Getter @Setter @NoArgsConstructor @AllArgsConstructor @Builder
|
||||
public class GcBacktestSettings {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private Long id;
|
||||
|
||||
@Column(name = "device_id", length = 100)
|
||||
private String deviceId;
|
||||
|
||||
// ── 자본 설정 ──────────────────────────────────────────────────────────────
|
||||
@Column(name = "initial_capital", nullable = false, precision = 20, scale = 2)
|
||||
@Builder.Default
|
||||
private BigDecimal initialCapital = new BigDecimal("10000000.00");
|
||||
|
||||
// ── 비용 모델 ──────────────────────────────────────────────────────────────
|
||||
/** LINEAR | ZERO */
|
||||
@Column(name = "commission_type", nullable = false, length = 20)
|
||||
@Builder.Default
|
||||
private String commissionType = "LINEAR";
|
||||
|
||||
@Column(name = "commission_rate", nullable = false, precision = 8, scale = 5)
|
||||
@Builder.Default
|
||||
private BigDecimal commissionRate = new BigDecimal("0.00150");
|
||||
|
||||
@Column(name = "slippage_rate", nullable = false, precision = 8, scale = 5)
|
||||
@Builder.Default
|
||||
private BigDecimal slippageRate = new BigDecimal("0.00050");
|
||||
|
||||
// ── 진입/청산 가격 ─────────────────────────────────────────────────────────
|
||||
/** CLOSE | NEXT_OPEN */
|
||||
@Column(name = "entry_price_type", nullable = false, length = 20)
|
||||
@Builder.Default
|
||||
private String entryPriceType = "CLOSE";
|
||||
|
||||
/** CLOSE | NEXT_OPEN */
|
||||
@Column(name = "exit_price_type", nullable = false, length = 20)
|
||||
@Builder.Default
|
||||
private String exitPriceType = "CLOSE";
|
||||
|
||||
// ── 포지션 방향 ────────────────────────────────────────────────────────────
|
||||
/** LONG | SHORT | BOTH */
|
||||
@Column(name = "position_direction", nullable = false, length = 10)
|
||||
@Builder.Default
|
||||
private String positionDirection = "LONG";
|
||||
|
||||
// ── 거래 규모 ──────────────────────────────────────────────────────────────
|
||||
/** CAPITAL_PCT | FIXED_AMOUNT */
|
||||
@Column(name = "trade_size_type", nullable = false, length = 20)
|
||||
@Builder.Default
|
||||
private String tradeSizeType = "CAPITAL_PCT";
|
||||
|
||||
@Column(name = "trade_size_value", nullable = false, precision = 10, scale = 4)
|
||||
@Builder.Default
|
||||
private BigDecimal tradeSizeValue = new BigDecimal("100.0000");
|
||||
|
||||
// ── 손절 ───────────────────────────────────────────────────────────────────
|
||||
@Column(name = "stop_loss_enabled", nullable = false)
|
||||
@Builder.Default
|
||||
private Boolean stopLossEnabled = false;
|
||||
|
||||
@Column(name = "stop_loss_pct", nullable = false, precision = 6, scale = 3)
|
||||
@Builder.Default
|
||||
private BigDecimal stopLossPct = new BigDecimal("2.000");
|
||||
|
||||
// ── 익절 ───────────────────────────────────────────────────────────────────
|
||||
@Column(name = "take_profit_enabled", nullable = false)
|
||||
@Builder.Default
|
||||
private Boolean takeProfitEnabled = false;
|
||||
|
||||
@Column(name = "take_profit_pct", nullable = false, precision = 6, scale = 3)
|
||||
@Builder.Default
|
||||
private BigDecimal takeProfitPct = new BigDecimal("5.000");
|
||||
|
||||
// ── 트레일링 스탑 ──────────────────────────────────────────────────────────
|
||||
@Column(name = "trailing_stop_enabled", nullable = false)
|
||||
@Builder.Default
|
||||
private Boolean trailingStopEnabled = false;
|
||||
|
||||
@Column(name = "trailing_stop_pct", nullable = false, precision = 6, scale = 3)
|
||||
@Builder.Default
|
||||
private BigDecimal trailingStopPct = new BigDecimal("2.000");
|
||||
|
||||
// ── 재진입 제어 ────────────────────────────────────────────────────────────
|
||||
@Column(name = "reentry_wait_bars", nullable = false)
|
||||
@Builder.Default
|
||||
private Integer reentryWaitBars = 0;
|
||||
|
||||
@Column(name = "max_open_trades", nullable = false)
|
||||
@Builder.Default
|
||||
private Integer maxOpenTrades = 1;
|
||||
|
||||
// ── 포지션 종속성 모드 ─────────────────────────────────────────────────────
|
||||
/** LONG_ONLY | SIGNAL_ONLY */
|
||||
@Column(name = "position_mode", nullable = false, length = 20)
|
||||
@Builder.Default
|
||||
private String positionMode = "LONG_ONLY";
|
||||
|
||||
// ── 분할 청산 ──────────────────────────────────────────────────────────────
|
||||
@Column(name = "partial_exit_enabled", nullable = false)
|
||||
@Builder.Default
|
||||
private Boolean partialExitEnabled = false;
|
||||
|
||||
@Column(name = "partial_exit_pct", nullable = false, precision = 6, scale = 3)
|
||||
@Builder.Default
|
||||
private BigDecimal partialExitPct = new BigDecimal("50.000");
|
||||
|
||||
@Column(name = "created_at", nullable = false, updatable = false)
|
||||
private LocalDateTime createdAt;
|
||||
|
||||
@Column(name = "updated_at")
|
||||
private LocalDateTime updatedAt;
|
||||
|
||||
@PrePersist
|
||||
protected void onCreate() { createdAt = updatedAt = LocalDateTime.now(); }
|
||||
|
||||
@PreUpdate
|
||||
protected void onUpdate() { updatedAt = LocalDateTime.now(); }
|
||||
}
|
||||
@@ -0,0 +1,121 @@
|
||||
package com.goldenchart.entity;
|
||||
|
||||
import jakarta.persistence.*;
|
||||
import lombok.*;
|
||||
import org.hibernate.annotations.JdbcTypeCode;
|
||||
import org.hibernate.type.SqlTypes;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 차트 슬롯 설정.
|
||||
* 멀티차트 레이아웃 내 각 슬롯의 모든 설정값을 저장.
|
||||
*/
|
||||
@Entity
|
||||
@Table(name = "gc_chart_slot",
|
||||
uniqueConstraints = @UniqueConstraint(name = "uk_slot_workspace_index",
|
||||
columnNames = {"workspace_id", "slot_index"}))
|
||||
@Getter @Setter @NoArgsConstructor @AllArgsConstructor @Builder
|
||||
public class GcChartSlot {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private Long id;
|
||||
|
||||
@ManyToOne(fetch = FetchType.LAZY)
|
||||
@JoinColumn(name = "workspace_id", nullable = false)
|
||||
private GcChartWorkspace workspace;
|
||||
|
||||
/** 슬롯 인덱스 (0-based) */
|
||||
@Column(name = "slot_index", nullable = false)
|
||||
private Integer slotIndex;
|
||||
|
||||
/** 종목 코드 (e.g. "KRW-BTC", "AAPL") */
|
||||
@Column(name = "symbol", length = 50)
|
||||
private String symbol;
|
||||
|
||||
/** 타임프레임 (1m/5m/15m/30m/1h/4h/1D/1W/1M) */
|
||||
@Column(name = "timeframe", length = 10)
|
||||
private String timeframe;
|
||||
|
||||
/** 차트 타입 (candlestick/bar/line/area/baseline) */
|
||||
@Column(name = "chart_type", length = 20)
|
||||
@Builder.Default
|
||||
private String chartType = "candlestick";
|
||||
|
||||
/** 테마 (dark/light/blue) */
|
||||
@Column(name = "theme", length = 20)
|
||||
@Builder.Default
|
||||
private String theme = "dark";
|
||||
|
||||
/** 차트 모드 (chart/trading) */
|
||||
@Column(name = "mode", length = 20)
|
||||
@Builder.Default
|
||||
private String mode = "chart";
|
||||
|
||||
/** 로그 스케일 사용 여부 */
|
||||
@Column(name = "log_scale")
|
||||
@Builder.Default
|
||||
private Boolean logScale = false;
|
||||
|
||||
/**
|
||||
* 지표 설정 JSON 배열.
|
||||
* 형식: [{id, type, params, hidden, plotVisibility}]
|
||||
* frontend IndicatorConfig[] 구조와 1:1 대응
|
||||
*/
|
||||
@Column(name = "indicators_json", columnDefinition = "JSON")
|
||||
@JdbcTypeCode(SqlTypes.JSON)
|
||||
private String indicatorsJson;
|
||||
|
||||
/**
|
||||
* 드로잉 객체 JSON 배열.
|
||||
* 형식: [{id, type, points, color, lineWidth, style, text, visible, fibtzSettings}]
|
||||
* frontend Drawing[] 구조와 1:1 대응
|
||||
*/
|
||||
@Column(name = "drawings_json", columnDefinition = "JSON")
|
||||
@JdbcTypeCode(SqlTypes.JSON)
|
||||
private String drawingsJson;
|
||||
|
||||
/** 드로잉 잠금 여부 */
|
||||
@Column(name = "drawings_locked")
|
||||
@Builder.Default
|
||||
private Boolean drawingsLocked = false;
|
||||
|
||||
/** 드로잉 표시 여부 */
|
||||
@Column(name = "drawings_visible")
|
||||
@Builder.Default
|
||||
private Boolean drawingsVisible = true;
|
||||
|
||||
/**
|
||||
* 보조지표 창(pane) 레이아웃 JSON.
|
||||
* 형식: [{paneIndex, height}]
|
||||
*/
|
||||
@Column(name = "pane_layout_json", columnDefinition = "JSON")
|
||||
@JdbcTypeCode(SqlTypes.JSON)
|
||||
private String paneLayoutJson;
|
||||
|
||||
/**
|
||||
* 메인 차트 캔들 색상 설정 JSON.
|
||||
* frontend MainChartStyle 구조
|
||||
*/
|
||||
@Column(name = "main_chart_style_json", columnDefinition = "JSON")
|
||||
@JdbcTypeCode(SqlTypes.JSON)
|
||||
private String mainChartStyleJson;
|
||||
|
||||
@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();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
package com.goldenchart.entity;
|
||||
|
||||
import jakarta.persistence.*;
|
||||
import lombok.*;
|
||||
import org.hibernate.annotations.JdbcTypeCode;
|
||||
import org.hibernate.type.SqlTypes;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 사용자 차트 워크스페이스.
|
||||
* 멀티차트 레이아웃 및 슬롯 집합을 관리한다.
|
||||
*/
|
||||
@Entity
|
||||
@Table(name = "gc_chart_workspace")
|
||||
@Getter @Setter @NoArgsConstructor @AllArgsConstructor @Builder
|
||||
public class GcChartWorkspace {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private Long id;
|
||||
|
||||
/** 소유 사용자 ID (users.id 논리 참조) */
|
||||
@Column(name = "user_id")
|
||||
private Long userId;
|
||||
|
||||
/** 비회원 기기 식별자 */
|
||||
@Column(name = "device_id", length = 100)
|
||||
private String deviceId;
|
||||
|
||||
/** 현재 적용된 레이아웃 ID (frontend layoutTypes.ts 의 LayoutDef.id 와 일치: "1","2v","2h",...) */
|
||||
@Column(name = "layout_id", length = 20, nullable = false)
|
||||
private String layoutId;
|
||||
|
||||
/** 차트 슬롯 설정 목록 (1:N) */
|
||||
@OneToMany(mappedBy = "workspace", cascade = CascadeType.ALL, orphanRemoval = true)
|
||||
@OrderBy("slotIndex ASC")
|
||||
@Builder.Default
|
||||
private List<GcChartSlot> slots = new ArrayList<>();
|
||||
|
||||
/** 차트 간 동기화 옵션 JSON {"symbol":true,"timeframe":false,"crosshair":true} */
|
||||
@Column(name = "sync_options_json", columnDefinition = "JSON")
|
||||
@JdbcTypeCode(SqlTypes.JSON)
|
||||
private String syncOptionsJson;
|
||||
|
||||
@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();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
package com.goldenchart.entity;
|
||||
|
||||
import jakarta.persistence.*;
|
||||
import lombok.*;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Entity
|
||||
@Table(name = "gc_fcm_token")
|
||||
@Getter
|
||||
@Setter
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Builder
|
||||
public class GcFcmToken {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private Long id;
|
||||
|
||||
@Column(name = "user_id")
|
||||
private Long userId;
|
||||
|
||||
@Column(name = "device_id", nullable = false, length = 64)
|
||||
private String deviceId;
|
||||
|
||||
@Column(nullable = false, unique = true, length = 512)
|
||||
private String token;
|
||||
|
||||
@Column(nullable = false)
|
||||
@Builder.Default
|
||||
private Boolean active = true;
|
||||
|
||||
@Column(name = "last_used_at")
|
||||
private LocalDateTime lastUsedAt;
|
||||
|
||||
@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();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
package com.goldenchart.entity;
|
||||
|
||||
import jakarta.persistence.*;
|
||||
import lombok.*;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 보유종목.
|
||||
*/
|
||||
@Entity
|
||||
@Table(name = "gc_holdings",
|
||||
uniqueConstraints = @UniqueConstraint(name = "uk_holdings_user_symbol",
|
||||
columnNames = {"user_id", "device_id", "symbol"}))
|
||||
@Getter @Setter @NoArgsConstructor @AllArgsConstructor @Builder
|
||||
public class GcHoldings {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private Long id;
|
||||
|
||||
@Column(name = "user_id")
|
||||
private Long userId;
|
||||
|
||||
@Column(name = "device_id", length = 100)
|
||||
private String deviceId;
|
||||
|
||||
@Column(name = "symbol", length = 50, nullable = false)
|
||||
private String symbol;
|
||||
|
||||
@Column(name = "korean_name", length = 100)
|
||||
private String koreanName;
|
||||
|
||||
@Column(name = "english_name", length = 100)
|
||||
private String englishName;
|
||||
|
||||
/** 평균 매입가 */
|
||||
@Column(name = "avg_price", precision = 30, scale = 8)
|
||||
private BigDecimal avgPrice;
|
||||
|
||||
/** 보유 수량 */
|
||||
@Column(name = "quantity", precision = 30, scale = 8)
|
||||
private BigDecimal quantity;
|
||||
|
||||
@Column(name = "display_order")
|
||||
@Builder.Default
|
||||
private Integer displayOrder = 0;
|
||||
|
||||
@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();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
package com.goldenchart.entity;
|
||||
|
||||
import jakarta.persistence.*;
|
||||
import lombok.*;
|
||||
import org.hibernate.annotations.JdbcTypeCode;
|
||||
import org.hibernate.type.SqlTypes;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 장치/사용자별 전역 지표 파라미터 설정.
|
||||
*
|
||||
* params_json 구조 예시:
|
||||
* {
|
||||
* "RSI": {"length": 9, "src": "close"},
|
||||
* "MACD": {"fastLength": 12, "slowLength": 26, "signalLength": 9, "src": "close"},
|
||||
* "BollingerBands": {"length": 20, "mult": 2.0, "src": "close"},
|
||||
* "Stochastic": {"kLength": 14, "smooth": 3, "dSmoothing": 3},
|
||||
* "IchimokuCloud": {"conversionPeriods": 9, "basePeriods": 26,
|
||||
* "laggingSpan2Periods": 52, "displacement": 26},
|
||||
* ...
|
||||
* }
|
||||
*
|
||||
* 프론트엔드 indicatorRegistry.ts 의 defaultParams 를 완전히 대체한다.
|
||||
*/
|
||||
@Entity
|
||||
@Table(name = "gc_indicator_settings")
|
||||
@Getter @Setter @NoArgsConstructor @AllArgsConstructor @Builder
|
||||
public class GcIndicatorSettings {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private Long id;
|
||||
|
||||
/** 비회원 기기 식별자 (X-Device-Id 헤더) */
|
||||
@Column(name = "device_id", length = 100, unique = true)
|
||||
private String deviceId;
|
||||
|
||||
/** 회원 ID (향후 확장) */
|
||||
@Column(name = "user_id", unique = true)
|
||||
private Long userId;
|
||||
|
||||
/**
|
||||
* 지표 타입 → 파라미터 맵의 JSON 직렬화.
|
||||
* Map<String, Map<String, Object>> 형태로 역직렬화한다.
|
||||
*/
|
||||
@Column(name = "params_json", columnDefinition = "JSON", nullable = false)
|
||||
@JdbcTypeCode(SqlTypes.JSON)
|
||||
@Builder.Default
|
||||
private String paramsJson = "{}";
|
||||
|
||||
/**
|
||||
* 지표 타입 → 시각 설정(색상·선굵기·수평선) JSON 직렬화.
|
||||
* Map<String, IndicatorVisual> 형태로 역직렬화한다.
|
||||
* <pre>
|
||||
* {
|
||||
* "RSI": {
|
||||
* "plots": [{"id":"plot0","color":"#7E57C2","lineWidth":2,"type":"line"}],
|
||||
* "hlines": [{"price":70,"color":"#EF5350","visible":true}]
|
||||
* }
|
||||
* }
|
||||
* </pre>
|
||||
*/
|
||||
@Column(name = "visual_config_json", columnDefinition = "JSON")
|
||||
@JdbcTypeCode(SqlTypes.JSON)
|
||||
@Builder.Default
|
||||
private String visualConfigJson = "{}";
|
||||
|
||||
@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();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
package com.goldenchart.entity;
|
||||
|
||||
import jakarta.persistence.*;
|
||||
import lombok.*;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 디바이스/유저 × 마켓별 실시간 전략 체크 설정.
|
||||
*
|
||||
* <ul>
|
||||
* <li>isLiveCheck — 실시간 체크 ON/OFF</li>
|
||||
* <li>executionType — CANDLE_CLOSE | REALTIME_TICK</li>
|
||||
* <li>strategyId — 연결된 gc_strategy.id (null 이면 체크 비활성)</li>
|
||||
* </ul>
|
||||
*/
|
||||
@Entity
|
||||
@Table(name = "gc_live_strategy_settings")
|
||||
@Getter @Setter @NoArgsConstructor @AllArgsConstructor @Builder
|
||||
public class GcLiveStrategySettings {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private Long id;
|
||||
|
||||
@Column(name = "device_id", length = 100)
|
||||
private String deviceId;
|
||||
|
||||
@Column(name = "user_id")
|
||||
private Long userId;
|
||||
|
||||
@Column(name = "market", nullable = false, length = 30)
|
||||
@Builder.Default
|
||||
private String market = "KRW-BTC";
|
||||
|
||||
/** 연결된 전략 ID (null = 미연결) */
|
||||
@Column(name = "strategy_id")
|
||||
private Long strategyId;
|
||||
|
||||
@Column(name = "is_live_check", nullable = false)
|
||||
@Builder.Default
|
||||
private Boolean isLiveCheck = false;
|
||||
|
||||
/** CANDLE_CLOSE | REALTIME_TICK */
|
||||
@Column(name = "execution_type", nullable = false, length = 30)
|
||||
@Builder.Default
|
||||
private String executionType = "CANDLE_CLOSE";
|
||||
|
||||
/** 전략 평가·데이터 수집 분봉 (1m, 3m, 5m, …) */
|
||||
@Column(name = "candle_type", nullable = false, length = 10)
|
||||
@Builder.Default
|
||||
private String candleType = "1m";
|
||||
|
||||
/** 매도 시그널 포지션 종속성 모드: LONG_ONLY | SIGNAL_ONLY */
|
||||
@Column(name = "position_mode", nullable = false, length = 20)
|
||||
@Builder.Default
|
||||
private String positionMode = "LONG_ONLY";
|
||||
|
||||
@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();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
package com.goldenchart.entity;
|
||||
|
||||
import jakarta.persistence.*;
|
||||
import lombok.*;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Entity
|
||||
@Table(name = "gc_live_trade")
|
||||
@Getter @Setter @NoArgsConstructor @AllArgsConstructor @Builder
|
||||
public class GcLiveTrade {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private Long id;
|
||||
|
||||
@Column(name = "device_id", nullable = false, length = 100)
|
||||
private String deviceId;
|
||||
|
||||
@Column(name = "user_id")
|
||||
private Long userId;
|
||||
|
||||
@Column(name = "symbol", nullable = false, length = 30)
|
||||
private String symbol;
|
||||
|
||||
@Column(name = "side", nullable = false, length = 8)
|
||||
private String side;
|
||||
|
||||
@Column(name = "order_kind", nullable = false, length = 16)
|
||||
@Builder.Default
|
||||
private String orderKind = "market";
|
||||
|
||||
@Column(name = "source", nullable = false, length = 32)
|
||||
@Builder.Default
|
||||
private String source = "STRATEGY";
|
||||
|
||||
@Column(name = "strategy_id")
|
||||
private Long strategyId;
|
||||
|
||||
@Column(name = "upbit_order_uuid", length = 64)
|
||||
private String upbitOrderUuid;
|
||||
|
||||
@Column(name = "price", nullable = false, precision = 20, scale = 8)
|
||||
private BigDecimal price;
|
||||
|
||||
@Column(name = "quantity", nullable = false, precision = 24, scale = 12)
|
||||
private BigDecimal quantity;
|
||||
|
||||
@Column(name = "gross_amount", nullable = false, precision = 20, scale = 2)
|
||||
private BigDecimal grossAmount;
|
||||
|
||||
@Column(name = "fee_amount", precision = 20, scale = 2)
|
||||
private BigDecimal feeAmount;
|
||||
|
||||
@Column(name = "state", nullable = false, length = 24)
|
||||
@Builder.Default
|
||||
private String state = "done";
|
||||
|
||||
@Column(name = "created_at", nullable = false, updatable = false)
|
||||
private LocalDateTime createdAt;
|
||||
|
||||
@PrePersist
|
||||
void onCreate() {
|
||||
createdAt = LocalDateTime.now();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package com.goldenchart.entity;
|
||||
|
||||
import jakarta.persistence.*;
|
||||
import lombok.*;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Entity
|
||||
@Table(name = "gc_paper_account")
|
||||
@Getter @Setter @NoArgsConstructor @AllArgsConstructor @Builder
|
||||
public class GcPaperAccount {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private Long id;
|
||||
|
||||
@Column(name = "user_id")
|
||||
private Long userId;
|
||||
|
||||
@Column(name = "device_id", length = 100, nullable = false, unique = true)
|
||||
private String deviceId;
|
||||
|
||||
@Column(name = "cash_balance", precision = 20, scale = 2, nullable = false)
|
||||
@Builder.Default
|
||||
private BigDecimal cashBalance = BigDecimal.valueOf(10_000_000);
|
||||
|
||||
@Column(name = "realized_pnl", precision = 20, scale = 2, nullable = false)
|
||||
@Builder.Default
|
||||
private BigDecimal realizedPnl = BigDecimal.ZERO;
|
||||
|
||||
@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();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
package com.goldenchart.entity;
|
||||
|
||||
import jakarta.persistence.*;
|
||||
import lombok.*;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Entity
|
||||
@Table(name = "gc_paper_position",
|
||||
uniqueConstraints = @UniqueConstraint(name = "uk_paper_position_account_symbol",
|
||||
columnNames = {"account_id", "symbol"}))
|
||||
@Getter @Setter @NoArgsConstructor @AllArgsConstructor @Builder
|
||||
public class GcPaperPosition {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private Long id;
|
||||
|
||||
@Column(name = "account_id", nullable = false)
|
||||
private Long accountId;
|
||||
|
||||
@Column(name = "symbol", length = 50, nullable = false)
|
||||
private String symbol;
|
||||
|
||||
@Column(name = "korean_name", length = 100)
|
||||
private String koreanName;
|
||||
|
||||
@Column(name = "quantity", precision = 30, scale = 12, nullable = false)
|
||||
@Builder.Default
|
||||
private BigDecimal quantity = BigDecimal.ZERO;
|
||||
|
||||
@Column(name = "avg_price", precision = 20, scale = 2, nullable = false)
|
||||
@Builder.Default
|
||||
private BigDecimal avgPrice = BigDecimal.ZERO;
|
||||
|
||||
@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();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
package com.goldenchart.entity;
|
||||
|
||||
import jakarta.persistence.*;
|
||||
import lombok.*;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Entity
|
||||
@Table(name = "gc_paper_trade")
|
||||
@Getter @Setter @NoArgsConstructor @AllArgsConstructor @Builder
|
||||
public class GcPaperTrade {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private Long id;
|
||||
|
||||
@Column(name = "account_id", nullable = false)
|
||||
private Long accountId;
|
||||
|
||||
@Column(name = "symbol", length = 50, nullable = false)
|
||||
private String symbol;
|
||||
|
||||
@Column(name = "side", length = 10, nullable = false)
|
||||
private String side;
|
||||
|
||||
@Column(name = "order_kind", length = 20, nullable = false)
|
||||
@Builder.Default
|
||||
private String orderKind = "limit";
|
||||
|
||||
@Column(name = "source", length = 20, nullable = false)
|
||||
@Builder.Default
|
||||
private String source = "MANUAL";
|
||||
|
||||
@Column(name = "strategy_id")
|
||||
private Long strategyId;
|
||||
|
||||
@Column(name = "price", precision = 20, scale = 2, nullable = false)
|
||||
private BigDecimal price;
|
||||
|
||||
@Column(name = "quantity", precision = 30, scale = 12, nullable = false)
|
||||
private BigDecimal quantity;
|
||||
|
||||
@Column(name = "gross_amount", precision = 20, scale = 2, nullable = false)
|
||||
private BigDecimal grossAmount;
|
||||
|
||||
@Column(name = "fee_amount", precision = 20, scale = 2, nullable = false)
|
||||
@Builder.Default
|
||||
private BigDecimal feeAmount = BigDecimal.ZERO;
|
||||
|
||||
@Column(name = "net_amount", precision = 20, scale = 2, nullable = false)
|
||||
private BigDecimal netAmount;
|
||||
|
||||
@Column(name = "cash_after", precision = 20, scale = 2, nullable = false)
|
||||
private BigDecimal cashAfter;
|
||||
|
||||
@Column(name = "created_at", nullable = false, updatable = false)
|
||||
private LocalDateTime createdAt;
|
||||
|
||||
@PrePersist
|
||||
protected void onCreate() {
|
||||
createdAt = LocalDateTime.now();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.goldenchart.entity;
|
||||
|
||||
import jakarta.persistence.*;
|
||||
import lombok.*;
|
||||
|
||||
@Entity
|
||||
@Table(name = "gc_role_menu_permission",
|
||||
uniqueConstraints = @UniqueConstraint(columnNames = {"role", "menu_id"}))
|
||||
@Getter @Setter @NoArgsConstructor @AllArgsConstructor @Builder
|
||||
public class GcRoleMenuPermission {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private Long id;
|
||||
|
||||
@Column(nullable = false, length = 20)
|
||||
private String role;
|
||||
|
||||
@Column(name = "menu_id", nullable = false, length = 50)
|
||||
private String menuId;
|
||||
|
||||
@Column(nullable = false)
|
||||
private Boolean allowed = true;
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
package com.goldenchart.entity;
|
||||
|
||||
import jakarta.persistence.*;
|
||||
import lombok.*;
|
||||
import org.hibernate.annotations.JdbcTypeCode;
|
||||
import org.hibernate.type.SqlTypes;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* GoldenChart 투자전략 DSL 엔티티.
|
||||
* frontend StrategyPage 에서 작성한 LogicNode 트리를 JSON 으로 저장.
|
||||
*/
|
||||
@Entity
|
||||
@Table(name = "gc_strategy")
|
||||
@Getter @Setter @NoArgsConstructor @AllArgsConstructor @Builder
|
||||
public class GcStrategy {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private Long id;
|
||||
|
||||
/** 로그인 사용자 ID (nullable — 비회원은 device_id 사용) */
|
||||
@Column(name = "user_id")
|
||||
private Long userId;
|
||||
|
||||
/** 비회원 기기 식별자 */
|
||||
@Column(name = "device_id", length = 100)
|
||||
private String deviceId;
|
||||
|
||||
@Column(name = "name", nullable = false, length = 200)
|
||||
private String name;
|
||||
|
||||
@Column(name = "description", columnDefinition = "TEXT")
|
||||
private String description;
|
||||
|
||||
/** 매수 조건 DSL JSON — frontend LogicNode 구조 */
|
||||
@Column(name = "buy_condition_json", columnDefinition = "JSON")
|
||||
@JdbcTypeCode(SqlTypes.JSON)
|
||||
private String buyConditionJson;
|
||||
|
||||
/** 매도 조건 DSL JSON — frontend LogicNode 구조 */
|
||||
@Column(name = "sell_condition_json", columnDefinition = "JSON")
|
||||
@JdbcTypeCode(SqlTypes.JSON)
|
||||
private String sellConditionJson;
|
||||
|
||||
@Column(name = "enabled", nullable = false)
|
||||
@Builder.Default
|
||||
private Boolean enabled = true;
|
||||
|
||||
@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();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
package com.goldenchart.entity;
|
||||
|
||||
import jakarta.persistence.*;
|
||||
import lombok.*;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 실시간 전략 체크에서 발생한 매매 시그널 이력.
|
||||
*/
|
||||
@Entity
|
||||
@Table(name = "gc_trade_signal")
|
||||
@Getter @Setter @NoArgsConstructor @AllArgsConstructor @Builder
|
||||
public class GcTradeSignal {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private Long id;
|
||||
|
||||
@Column(name = "device_id", length = 100)
|
||||
private String deviceId;
|
||||
|
||||
@Column(name = "user_id")
|
||||
private Long userId;
|
||||
|
||||
@Column(name = "market", nullable = false, length = 30)
|
||||
private String market;
|
||||
|
||||
@Column(name = "strategy_id")
|
||||
private Long strategyId;
|
||||
|
||||
@Column(name = "strategy_name", length = 200)
|
||||
private String strategyName;
|
||||
|
||||
/** BUY | SELL */
|
||||
@Column(name = "signal_type", nullable = false, length = 10)
|
||||
private String signalType;
|
||||
|
||||
@Column(name = "price", nullable = false)
|
||||
private Double price;
|
||||
|
||||
/** 캔들 시작 Unix 초 */
|
||||
@Column(name = "candle_time", nullable = false)
|
||||
private Long candleTime;
|
||||
|
||||
@Column(name = "candle_type", nullable = false, length = 10)
|
||||
@Builder.Default
|
||||
private String candleType = "1m";
|
||||
|
||||
/** CANDLE_CLOSE | REALTIME_TICK */
|
||||
@Column(name = "execution_type", nullable = false, length = 30)
|
||||
private String executionType;
|
||||
|
||||
@Column(name = "created_at", nullable = false, updatable = false)
|
||||
private LocalDateTime createdAt;
|
||||
|
||||
@PrePersist
|
||||
protected void onCreate() { createdAt = LocalDateTime.now(); }
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
package com.goldenchart.entity;
|
||||
|
||||
import jakarta.persistence.*;
|
||||
import lombok.*;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Entity
|
||||
@Table(name = "gc_user")
|
||||
@Getter @Setter @NoArgsConstructor @AllArgsConstructor @Builder
|
||||
public class GcUser {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private Long id;
|
||||
|
||||
@Column(nullable = false, unique = true, length = 50)
|
||||
private String username;
|
||||
|
||||
@Column(name = "password_hash", nullable = false, length = 100)
|
||||
private String passwordHash;
|
||||
|
||||
@Column(name = "display_name", length = 100)
|
||||
private String displayName;
|
||||
|
||||
@Column(nullable = false)
|
||||
private Boolean enabled = true;
|
||||
|
||||
/** ADMIN | USER | GUEST */
|
||||
@Column(nullable = false, length = 20)
|
||||
private String role = "USER";
|
||||
|
||||
@Column(name = "created_at", updatable = false)
|
||||
private LocalDateTime createdAt;
|
||||
|
||||
@Column(name = "updated_at")
|
||||
private LocalDateTime updatedAt;
|
||||
|
||||
@PrePersist
|
||||
void prePersist() {
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
if (createdAt == null) createdAt = now;
|
||||
updatedAt = now;
|
||||
}
|
||||
|
||||
@PreUpdate
|
||||
void preUpdate() {
|
||||
updatedAt = LocalDateTime.now();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package com.goldenchart.entity;
|
||||
|
||||
import jakarta.persistence.*;
|
||||
import lombok.*;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 관심종목 (워치리스트).
|
||||
* 기존 crypto_favorites 와 별도로 GoldenChart 전용 관리.
|
||||
*/
|
||||
@Entity
|
||||
@Table(name = "gc_watchlist",
|
||||
uniqueConstraints = @UniqueConstraint(name = "uk_watchlist_user_symbol",
|
||||
columnNames = {"user_id", "device_id", "symbol"}))
|
||||
@Getter @Setter @NoArgsConstructor @AllArgsConstructor @Builder
|
||||
public class GcWatchlist {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private Long id;
|
||||
|
||||
@Column(name = "user_id")
|
||||
private Long userId;
|
||||
|
||||
@Column(name = "device_id", length = 100)
|
||||
private String deviceId;
|
||||
|
||||
@Column(name = "symbol", length = 50, nullable = false)
|
||||
private String symbol;
|
||||
|
||||
@Column(name = "korean_name", length = 100)
|
||||
private String koreanName;
|
||||
|
||||
@Column(name = "english_name", length = 100)
|
||||
private String englishName;
|
||||
|
||||
@Column(name = "display_order")
|
||||
@Builder.Default
|
||||
private Integer displayOrder = 0;
|
||||
|
||||
@Column(name = "created_at", nullable = false, updatable = false)
|
||||
private LocalDateTime createdAt;
|
||||
|
||||
@PrePersist
|
||||
protected void onCreate() {
|
||||
createdAt = LocalDateTime.now();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user