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,29 @@
# Docker 컨테이너 환경 설정 (SPRING_PROFILES_ACTIVE=docker 일 때 적용)
spring:
datasource:
url: jdbc:mysql://mysql:3306/stockAnalyzer?useSSL=false&serverTimezone=Asia/Seoul&characterEncoding=UTF-8&allowPublicKeyRetrieval=true&createDatabaseIfNotExist=true
username: ${DB_USERNAME:stock}
password: ${DB_PASSWORD:analyzer}
hikari:
connection-timeout: 60000
initialization-fail-timeout: 60000
jpa:
hibernate:
ddl-auto: validate
flyway:
enabled: true
baseline-on-migrate: true
baseline-version: 0
validate-on-migrate: false
goldenchart:
cors:
allowed-origins:
- "*"
logging:
level:
com.goldenchart: INFO
org.flywaydb: INFO
+103
View File
@@ -0,0 +1,103 @@
spring:
application:
name: goldenchart-backend
profiles:
active: ${SPRING_PROFILES_ACTIVE:local}
datasource:
url: ${DB_URL:jdbc:mysql://localhost:3306/stockAnalyzer?useSSL=false&serverTimezone=Asia/Seoul&characterEncoding=UTF-8&allowPublicKeyRetrieval=true}
username: ${DB_USERNAME:stock}
password: ${DB_PASSWORD:analyzer}
driver-class-name: com.mysql.cj.jdbc.Driver
hikari:
maximum-pool-size: 20
minimum-idle: 5
connection-timeout: 30000
idle-timeout: 600000
max-lifetime: 1800000
jpa:
hibernate:
ddl-auto: validate
show-sql: false
properties:
hibernate:
dialect: org.hibernate.dialect.MySQLDialect
format_sql: true
default_batch_fetch_size: 100
open-in-view: false
flyway:
enabled: true
locations: classpath:db/migration
baseline-on-migrate: true
baseline-version: 0
jackson:
serialization:
write-dates-as-timestamps: false
deserialization:
fail-on-unknown-properties: false
default-property-inclusion: non_null
time-zone: Asia/Seoul
server:
port: 8080
servlet:
context-path: /api
compression:
enabled: true
mime-types: application/json,application/javascript,text/css
# Upbit API
upbit:
api:
base-url: https://api.upbit.com
candle-limit: 1000
request-delay-ms: 110
# EMA 수렴을 위한 warm-up 목표치 (페이지네이션으로 달성)
# EMA(200) 완전 수렴: ~1150봉 필요. 여유분 포함 1500봉으로 설정.
# 1500봉 = 200봉×8페이지 / 110ms 지연 = 구독당 약 880ms 추가 소요
warmup-count: 1500
websocket:
url: wss://api.upbit.com/websocket/v1
# Logging
logging:
level:
com.goldenchart: INFO
org.springframework.security: WARN
org.hibernate.SQL: WARN
pattern:
console: "%d{HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n"
# GoldenChart settings
goldenchart:
secrets:
# 업비트 API 키 DB 암호화 (운영: GC_SECRETS_ENCRYPTION_KEY 환경변수 필수, 32자 이상 권장)
encryption-key: ${GC_SECRETS_ENCRYPTION_KEY:}
indicator:
warmup-bars: 200 # EMA/RMA 수렴을 위한 워밍업 기간
max-bars: 2000 # 최대 로드 캔들 수
trading:
pipeline:
enabled: true
queue-capacity: 65536
worker-threads: 6
order-rate-per-second: 5.0
max-bars-per-series: 500
stale-tick-seconds: 30
gap-backfill-cron: "0 */5 * * * *"
gap-backfill-candle-count: 20
cors:
allowed-origins:
- http://localhost:5173
- http://localhost:3000
- http://localhost:80
- http://localhost
# Firebase FCM (서비스 계정 JSON: classpath:firebase-service-account.json)
firebase:
enabled: ${FIREBASE_ENABLED:false}
service-account-file: ${FIREBASE_SERVICE_ACCOUNT:firebase-service-account.json}
@@ -0,0 +1,25 @@
-- ============================================================
-- V10: 실시간 전략 체크 설정 테이블
-- 디바이스(또는 유저)별, 마켓별로 어느 전략을 어떤 방식으로
-- 실시간 체크할지 저장한다.
-- ============================================================
CREATE TABLE IF NOT EXISTS gc_live_strategy_settings (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
device_id VARCHAR(100) NULL COMMENT '비회원 기기 식별자',
user_id BIGINT NULL COMMENT '회원 ID',
market VARCHAR(30) NOT NULL DEFAULT 'KRW-BTC' COMMENT '업비트 마켓 코드 (e.g. KRW-BTC)',
strategy_id BIGINT NULL COMMENT '연결된 전략 ID (gc_strategy.id)',
is_live_check TINYINT(1) NOT NULL DEFAULT 0 COMMENT '실시간 체크 ON/OFF (1=ON)',
execution_type VARCHAR(30) NOT NULL DEFAULT 'CANDLE_CLOSE'
COMMENT '체크 방식: CANDLE_CLOSE(봉 마감) | REALTIME_TICK(3초 틱)',
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
UNIQUE KEY uk_live_device_market (device_id, market),
UNIQUE KEY uk_live_user_market (user_id, market),
INDEX idx_live_device (device_id),
INDEX idx_live_user (user_id),
INDEX idx_live_market (market)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
COMMENT='디바이스/유저별 종목 실시간 전략 체크 설정';
@@ -0,0 +1,29 @@
-- ============================================================
-- V11: 매매 시그널 이력 테이블 + 앱설정 매매알림 팝업 컬럼
-- ============================================================
-- ① 실시간 전략 체크에서 발생한 매매 시그널 이력
CREATE TABLE IF NOT EXISTS gc_trade_signal (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
device_id VARCHAR(100) NULL COMMENT '기기 식별자',
user_id BIGINT NULL COMMENT '회원 ID',
market VARCHAR(30) NOT NULL COMMENT '마켓 코드 (e.g. KRW-BTC)',
strategy_id BIGINT NULL COMMENT '전략 ID',
strategy_name VARCHAR(200) NULL COMMENT '전략명 (스냅샷)',
signal_type VARCHAR(10) NOT NULL COMMENT 'BUY | SELL',
price DOUBLE NOT NULL COMMENT '시그널 발생 시 종가',
candle_time BIGINT NOT NULL COMMENT '캔들 시작 Unix 초',
candle_type VARCHAR(10) NOT NULL DEFAULT '1m' COMMENT '캔들 타입',
execution_type VARCHAR(30) NOT NULL COMMENT 'CANDLE_CLOSE | REALTIME_TICK',
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
INDEX idx_ts_device (device_id),
INDEX idx_ts_market (market),
INDEX idx_ts_created (created_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
COMMENT='실시간 전략 체크 매매 시그널 이력';
-- ② gc_app_settings 에 매매알림 팝업 ON/OFF 컬럼 추가
ALTER TABLE gc_app_settings
ADD COLUMN trade_alert_popup TINYINT(1) NOT NULL DEFAULT 1
COMMENT '매매 시그널 발생 시 알림 팝업 표시 여부 (1=ON, 0=OFF)';
@@ -0,0 +1,13 @@
-- ============================================================
-- V12: 포지션 종속성 모드 컬럼 추가
-- gc_live_strategy_settings : position_mode (LONG_ONLY | SIGNAL_ONLY)
-- gc_backtest_settings : position_mode (LONG_ONLY | SIGNAL_ONLY)
-- ============================================================
ALTER TABLE gc_live_strategy_settings
ADD COLUMN position_mode VARCHAR(20) NOT NULL DEFAULT 'LONG_ONLY'
COMMENT '매도 시그널 포지션 종속성 모드 (LONG_ONLY | SIGNAL_ONLY)';
ALTER TABLE gc_backtest_settings
ADD COLUMN position_mode VARCHAR(20) NOT NULL DEFAULT 'LONG_ONLY'
COMMENT '백테스팅 매도 시그널 포지션 종속성 모드 (LONG_ONLY | SIGNAL_ONLY)';
@@ -0,0 +1,10 @@
-- 전역 실시간 전략 설정 (관심종목 = 전략 체크 대상)
ALTER TABLE gc_app_settings
ADD COLUMN live_strategy_check TINYINT(1) NOT NULL DEFAULT 0
COMMENT '실시간 전략 체크 마스터 ON/OFF',
ADD COLUMN live_strategy_id BIGINT NULL
COMMENT '관심종목 공통 적용 전략 ID',
ADD COLUMN live_execution_type VARCHAR(30) NOT NULL DEFAULT 'CANDLE_CLOSE'
COMMENT 'CANDLE_CLOSE | REALTIME_TICK',
ADD COLUMN live_position_mode VARCHAR(20) NOT NULL DEFAULT 'LONG_ONLY'
COMMENT 'LONG_ONLY | SIGNAL_ONLY';
@@ -0,0 +1,9 @@
-- ============================================================
-- V14: gc_app_settings 에 보조지표 가격축 라벨·설명 표시 옵션 추가
-- ON(1, 기본값): 우측 가격축 금액 하이라이트 + 선 설명(전환선 등) 표시
-- OFF(0) : 지표 선만 표시
-- ============================================================
ALTER TABLE gc_app_settings
ADD COLUMN chart_series_price_labels TINYINT(1) NOT NULL DEFAULT 1
COMMENT '보조지표 우측 가격축 라벨·설명·금액 하이라이트 (1=ON, 0=OFF)';
@@ -0,0 +1,9 @@
-- ============================================================
-- V15: gc_app_settings 에 거래량 표시 옵션 추가
-- ON(1, 기본값): 차트 하단 거래량 바 표시
-- OFF(0) : 거래량 pane 숨김
-- ============================================================
ALTER TABLE gc_app_settings
ADD COLUMN chart_volume_visible TINYINT(1) NOT NULL DEFAULT 1
COMMENT '차트 하단 거래량 바 표시 (1=ON, 0=OFF)';
@@ -0,0 +1,11 @@
-- ============================================================
-- V16: gc_app_settings 에 매매 알림 사운드 옵션 추가
-- ============================================================
ALTER TABLE gc_app_settings
ADD COLUMN trade_alert_sound_enabled TINYINT(1) NOT NULL DEFAULT 1
COMMENT '매매 시그널 알림 사운드 재생 여부 (1=ON, 0=OFF)';
ALTER TABLE gc_app_settings
ADD COLUMN trade_alert_sound VARCHAR(32) NOT NULL DEFAULT 'bell'
COMMENT '매매 시그널 알림음 ID (bell, chime 등)';
@@ -0,0 +1,7 @@
-- ============================================================
-- V17: gc_app_settings 에 차트 상단 범례 표시 옵션 JSON 추가
-- ============================================================
ALTER TABLE gc_app_settings
ADD COLUMN chart_legend_options_json JSON NULL
COMMENT '차트 상단 범례(tv-legend) 항목별 표시 옵션';
@@ -0,0 +1,73 @@
-- ============================================================
-- V18: 모의투자 (페이퍼 트레이딩)
-- ============================================================
ALTER TABLE gc_app_settings
ADD COLUMN paper_trading_enabled TINYINT(1) NOT NULL DEFAULT 1
COMMENT '모의투자 기능 사용 (1=ON)',
ADD COLUMN paper_initial_capital DECIMAL(20, 2) NOT NULL DEFAULT 10000000
COMMENT '모의투자 초기 자본 (KRW)',
ADD COLUMN paper_fee_rate_pct DECIMAL(8, 4) NOT NULL DEFAULT 0.0500
COMMENT '모의투자 수수료율 (%)',
ADD COLUMN paper_slippage_pct DECIMAL(8, 4) NOT NULL DEFAULT 0.0000
COMMENT '모의투자 슬리피지 (%)',
ADD COLUMN paper_min_order_krw DECIMAL(20, 2) NOT NULL DEFAULT 5000
COMMENT '모의투자 최소 주문 금액',
ADD COLUMN paper_auto_trade_enabled TINYINT(1) NOT NULL DEFAULT 1
COMMENT '실시간 전략 시그널 시 자동 모의매매 (1=ON)',
ADD COLUMN paper_auto_trade_budget_pct DECIMAL(8, 4) NOT NULL DEFAULT 95.0000
COMMENT '자동 매수 시 가용 현금 사용 비율 (%)';
CREATE TABLE gc_paper_account (
id BIGINT NOT NULL AUTO_INCREMENT,
user_id BIGINT NULL,
device_id VARCHAR(100) NOT NULL,
cash_balance DECIMAL(20, 2) NOT NULL DEFAULT 10000000,
realized_pnl DECIMAL(20, 2) NOT NULL DEFAULT 0,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (id),
UNIQUE KEY uk_paper_account_device (device_id),
UNIQUE KEY uk_paper_account_user (user_id),
INDEX idx_paper_account_device (device_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
COMMENT='모의투자 계좌 (현금 잔고)';
CREATE TABLE gc_paper_position (
id BIGINT NOT NULL AUTO_INCREMENT,
account_id BIGINT NOT NULL,
symbol VARCHAR(50) NOT NULL,
korean_name VARCHAR(100) NULL,
quantity DECIMAL(30, 12) NOT NULL DEFAULT 0,
avg_price DECIMAL(20, 2) NOT NULL DEFAULT 0,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (id),
UNIQUE KEY uk_paper_position_account_symbol (account_id, symbol),
CONSTRAINT fk_paper_position_account FOREIGN KEY (account_id)
REFERENCES gc_paper_account(id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
COMMENT='모의투자 보유 종목';
CREATE TABLE gc_paper_trade (
id BIGINT NOT NULL AUTO_INCREMENT,
account_id BIGINT NOT NULL,
symbol VARCHAR(50) NOT NULL,
side VARCHAR(10) NOT NULL COMMENT 'BUY | SELL',
order_kind VARCHAR(20) NOT NULL DEFAULT 'limit' COMMENT 'limit | market',
source VARCHAR(20) NOT NULL DEFAULT 'MANUAL' COMMENT 'MANUAL | STRATEGY',
strategy_id BIGINT NULL,
price DECIMAL(20, 2) NOT NULL,
quantity DECIMAL(30, 12) NOT NULL,
gross_amount DECIMAL(20, 2) NOT NULL,
fee_amount DECIMAL(20, 2) NOT NULL DEFAULT 0,
net_amount DECIMAL(20, 2) NOT NULL,
cash_after DECIMAL(20, 2) NOT NULL,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id),
INDEX idx_paper_trade_account (account_id),
INDEX idx_paper_trade_created (created_at),
CONSTRAINT fk_paper_trade_account FOREIGN KEY (account_id)
REFERENCES gc_paper_account(id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
COMMENT='모의투자 체결 이력';
@@ -0,0 +1,38 @@
-- 실거래(Upbit) + 운영 모드 + 종목별 분봉
ALTER TABLE gc_app_settings
ADD COLUMN trading_mode VARCHAR(10) NOT NULL DEFAULT 'PAPER'
COMMENT 'PAPER | LIVE | BOTH' AFTER paper_auto_trade_budget_pct,
ADD COLUMN live_auto_trade_enabled TINYINT(1) NOT NULL DEFAULT 0
COMMENT '실거래 자동매매 ON' AFTER trading_mode,
ADD COLUMN upbit_access_key VARCHAR(128) NULL
COMMENT '업비트 Open API Access Key' AFTER live_auto_trade_enabled,
ADD COLUMN upbit_secret_key VARCHAR(256) NULL
COMMENT '업비트 Open API Secret Key' AFTER upbit_access_key;
ALTER TABLE gc_live_strategy_settings
ADD COLUMN candle_type VARCHAR(10) NOT NULL DEFAULT '1m'
COMMENT '전략 평가·WS warm-up 분봉: 1m,3m,5m,15m,30m,1h,4h,1d'
AFTER execution_type;
CREATE TABLE IF NOT EXISTS gc_live_trade (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
device_id VARCHAR(100) NOT NULL,
user_id BIGINT NULL,
symbol VARCHAR(30) NOT NULL COMMENT 'KRW-BTC',
side VARCHAR(8) NOT NULL COMMENT 'BUY | SELL',
order_kind VARCHAR(16) NOT NULL DEFAULT 'market',
source VARCHAR(32) NOT NULL DEFAULT 'STRATEGY' COMMENT 'STRATEGY | MANUAL | STOP_LOSS | TAKE_PROFIT',
strategy_id BIGINT NULL,
upbit_order_uuid VARCHAR(64) NULL,
price DECIMAL(20, 8) NOT NULL,
quantity DECIMAL(24, 12) NOT NULL,
gross_amount DECIMAL(20, 2) NOT NULL,
fee_amount DECIMAL(20, 2) NULL,
state VARCHAR(24) NOT NULL DEFAULT 'done',
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
INDEX idx_live_trade_device (device_id),
INDEX idx_live_trade_symbol (symbol),
INDEX idx_live_trade_created (created_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
COMMENT='업비트 실거래 체결 이력';
@@ -0,0 +1,20 @@
-- 차트 실시간 소스, 실거래 예산, FCM 푸시 설정
ALTER TABLE gc_app_settings
ADD COLUMN chart_realtime_source VARCHAR(20) NOT NULL DEFAULT 'BACKEND_STOMP'
COMMENT 'BACKEND_STOMP | UPBIT_DIRECT',
ADD COLUMN live_auto_trade_budget_pct DECIMAL(8, 4) NOT NULL DEFAULT 95.0000,
ADD COLUMN fcm_push_enabled BOOLEAN NOT NULL DEFAULT FALSE;
CREATE TABLE IF NOT EXISTS gc_fcm_token (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
user_id BIGINT NULL,
device_id VARCHAR(64) NOT NULL,
token VARCHAR(512) NOT NULL,
active BOOLEAN NOT NULL DEFAULT TRUE,
last_used_at DATETIME NULL,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME NULL ON UPDATE CURRENT_TIMESTAMP,
UNIQUE KEY uk_gc_fcm_token (token),
KEY idx_gc_fcm_device (device_id),
KEY idx_gc_fcm_user (user_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
@@ -0,0 +1,13 @@
-- GoldenChart 로그인 사용자
CREATE TABLE IF NOT EXISTS gc_user (
id BIGINT NOT NULL AUTO_INCREMENT,
username VARCHAR(50) NOT NULL COMMENT '로그인 ID',
password_hash VARCHAR(100) NOT NULL,
display_name VARCHAR(100) NULL,
enabled TINYINT(1) NOT NULL DEFAULT 1,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (id),
UNIQUE KEY uk_gc_user_username (username)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
COMMENT='GoldenChart 로그인 사용자';
@@ -0,0 +1,3 @@
ALTER TABLE gc_app_settings
ADD COLUMN display_timezone VARCHAR(64) NOT NULL DEFAULT 'Asia/Seoul'
COMMENT '차트·UI 시간 표시 IANA 시간대 (예: Asia/Seoul, UTC)' AFTER default_layout_id;
@@ -0,0 +1,5 @@
ALTER TABLE gc_user
ADD COLUMN role VARCHAR(20) NOT NULL DEFAULT 'USER'
COMMENT 'ADMIN | USER | GUEST' AFTER enabled;
UPDATE gc_user SET role = 'ADMIN' WHERE username = 'admin';
@@ -0,0 +1,42 @@
CREATE TABLE IF NOT EXISTS gc_role_menu_permission (
id BIGINT NOT NULL AUTO_INCREMENT,
role VARCHAR(20) NOT NULL COMMENT 'ADMIN | USER | GUEST',
menu_id VARCHAR(50) NOT NULL,
allowed TINYINT(1) NOT NULL DEFAULT 1,
PRIMARY KEY (id),
UNIQUE KEY uk_role_menu (role, menu_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
COMMENT='역할별 메뉴 접근 권한';
-- ADMIN: 전체 허용
INSERT INTO gc_role_menu_permission (role, menu_id, allowed) VALUES
('ADMIN', 'dashboard', 1), ('ADMIN', 'chart', 1), ('ADMIN', 'paper', 1),
('ADMIN', 'strategy', 1), ('ADMIN', 'backtest', 1), ('ADMIN', 'notifications', 1),
('ADMIN', 'settings', 1),
('ADMIN', 'settings_general', 1), ('ADMIN', 'settings_chart', 1),
('ADMIN', 'settings_indicators', 1), ('ADMIN', 'settings_backtest', 1),
('ADMIN', 'settings_strategy', 1), ('ADMIN', 'settings_paper', 1),
('ADMIN', 'settings_alert', 1), ('ADMIN', 'settings_network', 1),
('ADMIN', 'settings_admin', 1);
-- USER: 관리자 설정 제외
INSERT INTO gc_role_menu_permission (role, menu_id, allowed) VALUES
('USER', 'dashboard', 1), ('USER', 'chart', 1), ('USER', 'paper', 1),
('USER', 'strategy', 1), ('USER', 'backtest', 1), ('USER', 'notifications', 1),
('USER', 'settings', 1),
('USER', 'settings_general', 1), ('USER', 'settings_chart', 1),
('USER', 'settings_indicators', 1), ('USER', 'settings_backtest', 1),
('USER', 'settings_strategy', 1), ('USER', 'settings_paper', 1),
('USER', 'settings_alert', 1), ('USER', 'settings_network', 1),
('USER', 'settings_admin', 0);
-- GUEST: 차트·설정(일부)만
INSERT INTO gc_role_menu_permission (role, menu_id, allowed) VALUES
('GUEST', 'dashboard', 0), ('GUEST', 'chart', 1), ('GUEST', 'paper', 0),
('GUEST', 'strategy', 0), ('GUEST', 'backtest', 0), ('GUEST', 'notifications', 0),
('GUEST', 'settings', 1),
('GUEST', 'settings_general', 1), ('GUEST', 'settings_chart', 1),
('GUEST', 'settings_indicators', 0), ('GUEST', 'settings_backtest', 0),
('GUEST', 'settings_strategy', 0), ('GUEST', 'settings_paper', 0),
('GUEST', 'settings_alert', 0), ('GUEST', 'settings_network', 1),
('GUEST', 'settings_admin', 0);
@@ -0,0 +1,6 @@
-- 업비트 API 키 AES 암호문 저장용 컬럼 확장
ALTER TABLE gc_app_settings
MODIFY COLUMN upbit_access_key VARCHAR(512) NULL
COMMENT '업비트 Access Key (AES-GCM 암호문)',
MODIFY COLUMN upbit_secret_key VARCHAR(512) NULL
COMMENT '업비트 Secret Key (AES-GCM 암호문)';
@@ -0,0 +1,11 @@
-- ============================================================
-- V26: 매매 알림 팝업 표시 위치·배치 방식
-- ============================================================
ALTER TABLE gc_app_settings
ADD COLUMN trade_alert_popup_position VARCHAR(10) NOT NULL DEFAULT 'right'
COMMENT '알림 팝업 위치: right | left | bottom',
ADD COLUMN trade_alert_popup_layout VARCHAR(10) NOT NULL DEFAULT 'stack'
COMMENT '알림 팝업 배치: stack | grid | strip | single',
ADD COLUMN trade_alert_popup_grid_cols INT NOT NULL DEFAULT 2
COMMENT '그리드 배치 시 열 개수 (2~4)';
@@ -0,0 +1,4 @@
-- V26에서 TINYINT로 생성된 컬럼을 Hibernate Integer 매핑과 맞추기 위해 INT로 변경
ALTER TABLE gc_app_settings
MODIFY COLUMN trade_alert_popup_grid_cols INT NOT NULL DEFAULT 2
COMMENT '그리드 배치 시 열 개수 (2~4)';
@@ -0,0 +1,115 @@
-- ============================================================
-- GoldenChart 전용 테이블 (V2)
-- 기존 stockAnalyzer DB 에 추가
-- ============================================================
-- ────────────────────────────────────────────────────────────
-- 1. gc_chart_workspace — 사용자 차트 워크스페이스
-- ────────────────────────────────────────────────────────────
CREATE TABLE IF NOT EXISTS gc_chart_workspace (
id BIGINT NOT NULL AUTO_INCREMENT,
user_id BIGINT NULL COMMENT 'users.id 논리 참조 (로그인 사용자)',
device_id VARCHAR(100) NULL COMMENT '비회원 기기 식별자',
layout_id VARCHAR(20) NOT NULL DEFAULT '1x1' COMMENT '레이아웃 (1x1/2x1/1x2/2x2/3x1 등)',
sync_options_json JSON NULL COMMENT '차트 간 동기화 옵션 {symbol, timeframe, crosshair}',
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (id),
INDEX idx_gc_ws_user (user_id),
INDEX idx_gc_ws_device (device_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
COMMENT='GoldenChart 멀티차트 워크스페이스 설정';
-- ────────────────────────────────────────────────────────────
-- 2. gc_chart_slot — 슬롯별 차트 설정
-- ────────────────────────────────────────────────────────────
CREATE TABLE IF NOT EXISTS gc_chart_slot (
id BIGINT NOT NULL AUTO_INCREMENT,
workspace_id BIGINT NOT NULL COMMENT 'gc_chart_workspace.id',
slot_index INT NOT NULL DEFAULT 0 COMMENT '슬롯 인덱스 (0-based)',
symbol VARCHAR(50) NULL COMMENT '종목 코드 (KRW-BTC, AAPL 등)',
timeframe VARCHAR(10) NULL COMMENT '타임프레임 (1m/5m/15m/30m/1h/4h/1D/1W/1M)',
chart_type VARCHAR(20) NOT NULL DEFAULT 'candlestick',
theme VARCHAR(20) NOT NULL DEFAULT 'dark',
mode VARCHAR(20) NOT NULL DEFAULT 'chart' COMMENT 'chart / trading',
log_scale TINYINT(1) NOT NULL DEFAULT 0,
indicators_json JSON NULL COMMENT 'IndicatorConfig[] — 보조지표 설정 배열',
drawings_json JSON NULL COMMENT 'Drawing[] — 드로잉 객체 배열',
drawings_locked TINYINT(1) NOT NULL DEFAULT 0,
drawings_visible TINYINT(1) NOT NULL DEFAULT 1,
pane_layout_json JSON NULL COMMENT '보조지표 창 높이 배열 [{paneIndex, height}]',
main_chart_style_json JSON NULL COMMENT '캔들 색상 등 메인 차트 스타일',
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (id),
UNIQUE KEY uk_slot_workspace_index (workspace_id, slot_index),
INDEX idx_gc_slot_ws (workspace_id),
CONSTRAINT fk_gc_slot_workspace FOREIGN KEY (workspace_id)
REFERENCES gc_chart_workspace(id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
COMMENT='GoldenChart 슬롯별 차트 설정 (지표·드로잉 포함)';
-- ────────────────────────────────────────────────────────────
-- 3. gc_watchlist — 관심종목
-- ────────────────────────────────────────────────────────────
CREATE TABLE IF NOT EXISTS gc_watchlist (
id BIGINT NOT NULL AUTO_INCREMENT,
user_id BIGINT NULL COMMENT 'users.id 논리 참조',
device_id VARCHAR(100) NULL COMMENT '비회원 기기 식별자',
symbol VARCHAR(50) NOT NULL COMMENT 'KRW-BTC, AAPL 등',
korean_name VARCHAR(100) NULL,
english_name VARCHAR(100) NULL,
display_order INT NOT NULL DEFAULT 0,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id),
UNIQUE KEY uk_watchlist_user_symbol (user_id, symbol),
UNIQUE KEY uk_watchlist_device_symbol (device_id, symbol),
INDEX idx_gc_wl_user (user_id),
INDEX idx_gc_wl_device (device_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
COMMENT='GoldenChart 관심종목';
-- ────────────────────────────────────────────────────────────
-- 4. gc_holdings — 보유종목
-- ────────────────────────────────────────────────────────────
CREATE TABLE IF NOT EXISTS gc_holdings (
id BIGINT NOT NULL AUTO_INCREMENT,
user_id BIGINT NULL COMMENT 'users.id 논리 참조',
device_id VARCHAR(100) NULL COMMENT '비회원 기기 식별자',
symbol VARCHAR(50) NOT NULL,
korean_name VARCHAR(100) NULL,
english_name VARCHAR(100) NULL,
avg_price DECIMAL(30, 8) NULL COMMENT '평균 매입가',
quantity DECIMAL(30, 8) NULL COMMENT '보유 수량',
display_order INT NOT NULL DEFAULT 0,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (id),
UNIQUE KEY uk_holdings_user_symbol (user_id, symbol),
UNIQUE KEY uk_holdings_device_symbol (device_id, symbol),
INDEX idx_gc_hld_user (user_id),
INDEX idx_gc_hld_device (device_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
COMMENT='GoldenChart 보유종목';
-- ────────────────────────────────────────────────────────────
-- 5. gc_indicator_cache — 지표 계산 캐시 (선택적 사용)
-- ────────────────────────────────────────────────────────────
CREATE TABLE IF NOT EXISTS gc_indicator_cache (
id BIGINT NOT NULL AUTO_INCREMENT,
cache_key VARCHAR(200) NOT NULL COMMENT 'symbol:timeframe:type:params_hash',
symbol VARCHAR(50) NOT NULL,
timeframe VARCHAR(10) NOT NULL,
indicator_type VARCHAR(50) NOT NULL,
params_json JSON NULL COMMENT '계산 파라미터',
result_json MEDIUMTEXT NULL COMMENT 'IndicatorResponse JSON',
bar_count INT NULL COMMENT '계산에 사용된 캔들 수',
last_bar_time BIGINT NULL COMMENT '마지막 캔들 Unix 타임스탬프(초)',
computed_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
expired_at DATETIME NULL COMMENT 'NULL=영구, 설정 시 만료',
PRIMARY KEY (id),
UNIQUE KEY uk_gc_ind_cache_key (cache_key),
INDEX idx_gc_cache_symbol_tf (symbol, timeframe),
INDEX idx_gc_cache_expired (expired_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
COMMENT='GoldenChart 지표 계산 결과 캐시';
@@ -0,0 +1,26 @@
-- ============================================================
-- V3: 전역 지표 파라미터 설정 테이블
-- 장치(device_id) 또는 사용자(user_id)별로 지표 계산에 사용할
-- 모든 파라미터를 JSON으로 저장한다.
-- 프론트엔드 indicatorRegistry.ts의 defaultParams를 오버라이드.
-- ============================================================
CREATE TABLE IF NOT EXISTS gc_indicator_settings (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
device_id VARCHAR(100) NULL COMMENT '비회원 기기 식별자',
user_id BIGINT NULL COMMENT '회원 ID (향후 확장용)',
-- 지표 타입별 파라미터를 최상위 키로 저장
-- 예) {"RSI":{"length":9},"MACD":{"fastLength":12,"slowLength":26,"signalLength":9},...}
-- MySQL 8.0: JSON 컬럼에 DEFAULT 값 불가 → 애플리케이션 레이어에서 '{}' 기본값 처리
params_json JSON NOT NULL,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
UNIQUE KEY uk_indi_device (device_id),
UNIQUE KEY uk_indi_user (user_id),
INDEX idx_indi_device (device_id),
INDEX idx_indi_user (user_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
COMMENT='장치/사용자별 전역 지표 계산 파라미터';
@@ -0,0 +1,38 @@
-- ============================================================
-- V4: 앱 전역 차트 기본 설정 테이블
-- 장치(device_id) 또는 사용자(user_id)별로 하드코딩을 대체하는
-- 기본 차트 설정값을 저장한다.
--
-- 이 테이블의 값이 우선 적용되며, 없으면 프론트엔드 코드의 fallback 값 사용.
-- ============================================================
CREATE TABLE IF NOT EXISTS gc_app_settings (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
device_id VARCHAR(100) NULL COMMENT '비회원 기기 식별자',
user_id BIGINT NULL COMMENT '회원 ID (향후 확장)',
-- 기본 차트 설정 (per-slot 기본값, gc_chart_slot 없을 때 사용)
default_symbol VARCHAR(50) NOT NULL DEFAULT 'KRW-BTC' COMMENT '기본 종목',
default_timeframe VARCHAR(10) NOT NULL DEFAULT '1D' COMMENT '기본 타임프레임',
default_chart_type VARCHAR(20) NOT NULL DEFAULT 'candlestick' COMMENT '기본 차트 타입',
default_theme VARCHAR(20) NOT NULL DEFAULT 'dark' COMMENT '기본 테마',
default_log_scale TINYINT(1) NOT NULL DEFAULT 0 COMMENT '기본 로그 스케일',
default_layout_id VARCHAR(20) NOT NULL DEFAULT '1' COMMENT '기본 레이아웃 ID',
-- 캔들 색상 기본값 (frontend DEFAULT_MAIN_CHART_STYLE 대체)
-- {"upColor":"#ff6b6b","downColor":"#4dabf7","borderUpColor":"#ff6b6b",...}
main_chart_style_json JSON NULL COMMENT '캔들 색상 설정',
-- 기본 차트 동기화 옵션 (frontend DEFAULT_SYNC 대체)
-- {"symbol":false,"interval":false,"crosshair":true,"time":false,"dateRange":false}
sync_options_json JSON NULL COMMENT '멀티차트 동기화 옵션',
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
UNIQUE KEY uk_app_device (device_id),
UNIQUE KEY uk_app_user (user_id),
INDEX idx_app_device (device_id),
INDEX idx_app_user (user_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
COMMENT='장치/사용자별 앱 전역 차트 기본 설정 (하드코딩 대체)';
@@ -0,0 +1,20 @@
-- V5: gc_indicator_settings 에 시각 설정(색상, 선 굵기, 수평선) 컬럼 추가
-- visual_config_json 구조 예시:
-- {
-- "RSI": {
-- "plots": [{"id":"plot0","title":"RSI","color":"#7E57C2","type":"line","lineWidth":2}],
-- "hlines": [{"price":70,"color":"#EF5350","visible":true},{"price":30,"color":"#26A69A","visible":true}]
-- },
-- "MACD": {
-- "plots": [{"id":"macd","title":"MACD","color":"#2962FF","type":"line","lineWidth":2}, ...],
-- "hlines": []
-- },
-- "IchimokuCloud": {
-- "plots": [...],
-- "hlines": [],
-- "cloudColors": {"bullishColor":"#EF535033","bearishColor":"#26A69A33"}
-- }
-- }
ALTER TABLE gc_indicator_settings
ADD COLUMN visual_config_json JSON NULL
COMMENT '지표 시각 설정 JSON (색상·선굵기·수평선): Map<indicatorType, {plots, hlines}>';
@@ -0,0 +1,21 @@
-- V6: GoldenChart 투자전략 테이블
-- frontend StrategyPage 에서 생성한 DSL 전략을 DB에 저장
-- DSL 구조: { id, name, description, buyCondition: LogicNode, sellCondition: LogicNode }
CREATE TABLE IF NOT EXISTS gc_strategy (
id BIGINT NOT NULL AUTO_INCREMENT,
user_id BIGINT NULL COMMENT 'users.id 논리 참조 (로그인 사용자)',
device_id VARCHAR(100) NULL COMMENT '비회원 기기 식별자',
name VARCHAR(200) NOT NULL COMMENT '전략 이름',
description TEXT NULL COMMENT '전략 설명',
buy_condition_json JSON NULL COMMENT '매수 조건 DSL (LogicNode 트리)',
sell_condition_json JSON NULL COMMENT '매도 조건 DSL (LogicNode 트리)',
enabled TINYINT(1) NOT NULL DEFAULT 1 COMMENT '활성 여부',
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (id),
INDEX idx_gc_strategy_user (user_id),
INDEX idx_gc_strategy_device (device_id),
INDEX idx_gc_strategy_name (name)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
COMMENT='GoldenChart 투자전략 DSL 저장';
@@ -0,0 +1,48 @@
-- 백테스팅 설정 테이블
-- Ta4j 에서 제공하는 주요 백테스팅 옵션을 저장
CREATE TABLE IF NOT EXISTS gc_backtest_settings (
id BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
device_id VARCHAR(100),
-- ── 자본 설정 ──────────────────────────────────────────────────────────
initial_capital DECIMAL(20,2) NOT NULL DEFAULT 10000000.00, -- 초기 자본 (원)
-- ── 비용 모델 ──────────────────────────────────────────────────────────
commission_type VARCHAR(20) NOT NULL DEFAULT 'LINEAR', -- LINEAR | ZERO
commission_rate DECIMAL(8,5) NOT NULL DEFAULT 0.00150, -- 수수료율 (0.15%)
slippage_rate DECIMAL(8,5) NOT NULL DEFAULT 0.00050, -- 슬리피지 (0.05%)
-- ── 진입/청산 가격 ───────────────────────────────────────────────────
entry_price_type VARCHAR(20) NOT NULL DEFAULT 'CLOSE', -- CLOSE | NEXT_OPEN
exit_price_type VARCHAR(20) NOT NULL DEFAULT 'CLOSE', -- CLOSE | NEXT_OPEN
-- ── 포지션 방향 ──────────────────────────────────────────────────────
position_direction VARCHAR(10) NOT NULL DEFAULT 'LONG', -- LONG | SHORT | BOTH
-- ── 거래 규모 ──────────────────────────────────────────────────────────
trade_size_type VARCHAR(20) NOT NULL DEFAULT 'CAPITAL_PCT',-- CAPITAL_PCT | FIXED_AMOUNT
trade_size_value DECIMAL(10,4) NOT NULL DEFAULT 100.0000, -- 비율(%) or 고정금액(원)
-- ── 손절 (StopLossRule) ───────────────────────────────────────────────
stop_loss_enabled TINYINT(1) NOT NULL DEFAULT 0,
stop_loss_pct DECIMAL(6,3) NOT NULL DEFAULT 2.000, -- 손절 비율 (%)
-- ── 익절 (StopGainRule) ───────────────────────────────────────────────
take_profit_enabled TINYINT(1) NOT NULL DEFAULT 0,
take_profit_pct DECIMAL(6,3) NOT NULL DEFAULT 5.000, -- 익절 비율 (%)
-- ── 트레일링 스탑 (TrailingStopLossRule) ─────────────────────────────
trailing_stop_enabled TINYINT(1) NOT NULL DEFAULT 0,
trailing_stop_pct DECIMAL(6,3) NOT NULL DEFAULT 2.000, -- 트레일링 스탑 비율 (%)
-- ── 재진입 제어 ───────────────────────────────────────────────────────
reentry_wait_bars INT NOT NULL DEFAULT 0, -- 매도 후 재진입 대기 봉 수
max_open_trades INT NOT NULL DEFAULT 1, -- 최대 동시 보유 포지션 수
-- ── 기타 ──────────────────────────────────────────────────────────────
partial_exit_enabled TINYINT(1) NOT NULL DEFAULT 0, -- 분할 청산 여부
partial_exit_pct DECIMAL(6,3) NOT NULL DEFAULT 50.000, -- 분할 청산 비율 (%)
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
@@ -0,0 +1,33 @@
-- 백테스팅 실행 이력 및 결과 테이블
CREATE TABLE IF NOT EXISTS gc_backtest_result (
id BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
device_id VARCHAR(100),
strategy_id BIGINT,
strategy_name VARCHAR(200),
symbol VARCHAR(50),
timeframe VARCHAR(10),
bar_count INT NOT NULL DEFAULT 0,
from_time BIGINT COMMENT '시작 봉 Unix timestamp (초)',
to_time BIGINT COMMENT '종료 봉 Unix timestamp (초)',
-- 설정 스냅샷
settings_json JSON,
-- 매수/매도 시그널 배열
signals_json JSON,
-- Ta4j AnalysisCriterion 계산 결과 전체
analysis_json JSON,
-- 빠른 목록 조회용 인덱스 컬럼
total_return DECIMAL(12,4) COMMENT '총 수익률 (소수, e.g. 0.15 = +15%)',
win_rate DECIMAL(6,4) COMMENT '승률 0~1',
total_trades INT,
max_drawdown DECIMAL(12,4) COMMENT '최대 낙폭 (음수)',
sharpe_ratio DECIMAL(10,4),
final_equity DECIMAL(20,2),
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
INDEX idx_device_created (device_id, created_at DESC)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
@@ -0,0 +1,11 @@
-- ============================================================
-- V9: gc_app_settings 에 백테스팅 결과 자동 팝업 옵션 추가
-- ON(1, 기본값): 백테스팅 완료 시 결과 팝업 자동 표시
-- OFF(0) : 팝업 자동 표시 안 함 (수동으로 결과보기 버튼 클릭 필요)
-- ============================================================
ALTER TABLE gc_app_settings
ADD COLUMN bt_auto_popup TINYINT(1) NOT NULL DEFAULT 1
COMMENT '백테스팅 완료 시 결과 팝업 자동 표시 여부 (1=ON, 0=OFF)',
ADD COLUMN bt_show_price TINYINT(1) NOT NULL DEFAULT 1
COMMENT '백테스팅 매수/매도 마커에 금액 표시 여부 (1=ON, 0=OFF)';