17 KiB
17 KiB
컬럼명 매핑 가이드
개요
현재 프로젝트는 하이브리드 컬럼명 방식을 사용합니다:
- PostgreSQL 테이블: 영문 컬럼명
- DataFrame (전략 코드): 한글 컬럼명
이는 DB 표준(영문)과 make-quant-py 호환성(한글)을 동시에 만족하기 위한 설계입니다.
1. Asset (종목 정보)
PostgreSQL 테이블: assets
| DB 컬럼명 (영문) | 타입 | 설명 |
|---|---|---|
| id | UUID | 고유 ID |
| ticker | String(20) | 종목코드 |
| name | String(100) | 종목명 |
| market | String(20) | 시장 (KOSPI/KOSDAQ) |
| market_cap | BigInteger | 시가총액 |
| stock_type | String(20) | 주식 분류 |
| sector | String(100) | 섹터 |
| last_price | Numeric(15,2) | 최종 가격 |
| eps | Numeric(15,2) | 주당순이익 |
| bps | Numeric(15,2) | 주당순자산 |
| dividend_per_share | Numeric(15,2) | 주당배당금 |
| base_date | Date | 기준일 |
| is_active | Boolean | 활성 여부 |
DataFrame 컬럼 (한글)
# data_helpers.get_ticker_list() 반환
{
'종목코드': ticker,
'종목명': name,
'시장': market,
'섹터': sector
}
| DataFrame 컬럼 (한글) | DB 컬럼 (영문) |
|---|---|
| 종목코드 | ticker |
| 종목명 | name |
| 시장 | market |
| 섹터 | sector |
2. PriceData (가격 데이터)
PostgreSQL 테이블: price_data
| DB 컬럼명 (영문) | 타입 | 설명 |
|---|---|---|
| ticker | String(20) | 종목코드 |
| timestamp | DateTime | 일시 |
| open | Numeric(15,2) | 시가 |
| high | Numeric(15,2) | 고가 |
| low | Numeric(15,2) | 저가 |
| close | Numeric(15,2) | 종가 |
| volume | BigInteger | 거래량 |
DataFrame 컬럼 (한글)
# data_helpers.get_price_data() 반환
{
'종목코드': ticker,
'날짜': timestamp,
'시가': open,
'고가': high,
'저가': low,
'종가': close,
'거래량': volume
}
| DataFrame 컬럼 (한글) | DB 컬럼 (영문) |
|---|---|
| 종목코드 | ticker |
| 날짜 | timestamp |
| 시가 | open |
| 고가 | high |
| 저가 | low |
| 종가 | close |
| 거래량 | volume |
3. FinancialStatement (재무제표)
PostgreSQL 테이블: financial_statements
| DB 컬럼명 (영문) | 타입 | 설명 |
|---|---|---|
| id | UUID | 고유 ID |
| ticker | String(20) | 종목코드 |
| account | String(100) | 계정명 |
| base_date | Date | 기준일 |
| value | Numeric(20,2) | 값 |
| disclosure_type | Char(1) | 공시 유형 (Y/Q) |
DataFrame 컬럼 (한글)
# data_helpers.get_financial_statements() 반환
{
'종목코드': ticker,
'계정': account,
'기준일': base_date,
'값': value
}
| DataFrame 컬럼 (한글) | DB 컬럼 (영문) |
|---|---|
| 종목코드 | ticker |
| 계정 | account |
| 기준일 | base_date |
| 값 | value |
4. 전략에서 사용하는 파생 컬럼
전략 코드에서 계산되는 추가 컬럼들 (모두 한글):
Multi-Factor 전략
Quality 팩터:
ROE- 자기자본이익률GPA- Gross Profit / AssetsCFO- 영업활동현금흐름
Value 팩터:
PER- 주가수익비율PBR- 주가순자산비율PCR- 주가현금흐름비율PSR- 주가매출액비율DY- 배당수익률
Momentum 팩터:
12M_Return- 12개월 수익률K_Ratio- K-Ratio (모멘텀 지속성)
Magic Formula 전략
magic_ebit- EBIT (영업이익)magic_ev- Enterprise Valuemagic_ic- Invested Capitalmagic_ey- Earnings Yield (EBIT / EV)magic_roc- Return on Capital (EBIT / IC)magic_rank- 종합 순위
F-Score 전략
f_score- F-Score (0-9점)분류- 시가총액 분류 (대형주/중형주/소형주)
5. 변환 로직 위치
모든 영문 → 한글 변환은 **app/utils/data_helpers.py**에서 수행됩니다.
# app/utils/data_helpers.py
def get_ticker_list(db_session: Session) -> pd.DataFrame:
"""종목 리스트 조회 (영문 → 한글 변환)"""
assets = db_session.query(Asset).filter(Asset.is_active == True).all()
data = [{
'종목코드': asset.ticker, # ticker → 종목코드
'종목명': asset.name, # name → 종목명
'시장': asset.market, # market → 시장
'섹터': asset.sector # sector → 섹터
} for asset in assets]
return pd.DataFrame(data)
def get_price_data(...) -> pd.DataFrame:
"""가격 데이터 조회 (영문 → 한글 변환)"""
# ...
data = [{
'종목코드': p.ticker, # ticker → 종목코드
'날짜': p.timestamp, # timestamp → 날짜
'시가': float(p.open), # open → 시가
'고가': float(p.high), # high → 고가
'저가': float(p.low), # low → 저가
'종가': float(p.close), # close → 종가
'거래량': p.volume # volume → 거래량
} for p in prices]
return pd.DataFrame(data)
def get_financial_statements(...) -> pd.DataFrame:
"""재무제표 조회 (영문 → 한글 변환)"""
# ...
data = [{
'종목코드': fs.ticker, # ticker → 종목코드
'계정': fs.account, # account → 계정
'기준일': fs.base_date, # base_date → 기준일
'값': float(fs.value) # value → 값
} for fs in fs_data]
return pd.DataFrame(data)
def get_value_indicators(...) -> pd.DataFrame:
"""밸류 지표 조회"""
# ...
data = [{
'종목코드': ticker,
'지표': indicator_name, # PER, PBR, PCR, PSR, DY
'값': value
}]
return pd.DataFrame(data)
6. 새로운 컬럼 추가 시 주의사항
Step 1: DB 모델에 영문 컬럼 추가
# app/models/asset.py
class Asset(Base):
# ...
new_field = Column(String(50)) # 영문 컬럼명
Step 2: Alembic 마이그레이션
alembic revision --autogenerate -m "Add new_field to assets"
alembic upgrade head
Step 3: data_helpers.py에 매핑 추가
# app/utils/data_helpers.py
def get_ticker_list(db_session):
data = [{
'종목코드': asset.ticker,
'종목명': asset.name,
# ...
'새필드': asset.new_field # 한글 컬럼명 추가
} for asset in assets]
Step 4: 전략 코드에서 사용
# app/strategies/composite/my_strategy.py
ticker_list['새필드'].tolist() # 한글 컬럼명 사용
7. 일관성 검증
테스트 코드 예시
# tests/test_column_mapping.py
def test_ticker_list_columns():
"""종목 리스트 컬럼명 검증"""
df = get_ticker_list(db_session)
# 한글 컬럼명 확인
assert '종목코드' in df.columns
assert '종목명' in df.columns
assert '시장' in df.columns
assert '섹터' in df.columns
def test_price_data_columns():
"""가격 데이터 컬럼명 검증"""
df = get_price_data(db_session, ['005930'], start_date, end_date)
# 한글 컬럼명 확인
assert '종목코드' in df.columns
assert '날짜' in df.columns
assert '시가' in df.columns
assert '고가' in df.columns
assert '저가' in df.columns
assert '종가' in df.columns
assert '거래량' in df.columns
8. 대안적 접근 (참고)
옵션 A: 완전 영문화 (현재 미사용)
# DB와 DataFrame 모두 영문
ticker_list['ticker'].tolist()
data_bind[['ticker', 'name', 'sector']].copy()
장점: 일관성 단점: make-quant-py 코드 대대적 수정 필요
옵션 B: 완전 한글화 (현재 미사용)
# DB도 한글 컬럼명
class Asset(Base):
종목코드 = Column(String(20))
종목명 = Column(String(100))
장점: 변환 불필요 단점: DB 표준 위반, 국제화 어려움, ORM 이슈
옵션 C: 하이브리드 (현재 채택) ✅
- DB: 영문 (표준 준수)
- DataFrame: 한글 (make-quant-py 호환)
- 변환: data_helpers.py가 책임
장점: 양쪽 장점 모두 활용 단점: 변환 레이어 유지보수
9. make-quant-py MySQL vs 현재 PostgreSQL
make-quant-py (MySQL)
-- kor_ticker 테이블
CREATE TABLE kor_ticker (
종목코드 VARCHAR(20), -- 한글 컬럼명
종목명 VARCHAR(100),
시가총액 BIGINT,
분류 VARCHAR(20),
섹터 VARCHAR(100),
종가 INT,
EPS DECIMAL,
BPS DECIMAL,
주당배당금 DECIMAL,
종목구분 VARCHAR(20),
기준일 DATE
);
-- kor_price 테이블
CREATE TABLE kor_price (
날짜 DATE, -- 한글 컬럼명
시가 INT,
고가 INT,
저가 INT,
종가 INT,
거래량 BIGINT,
종목코드 VARCHAR(20)
);
-- kor_fs 테이블
CREATE TABLE kor_fs (
종목코드 VARCHAR(20),
계정 VARCHAR(100),
기준일 DATE,
값 DECIMAL,
공시구분 CHAR(1)
);
현재 프로젝트 (PostgreSQL)
-- assets 테이블
CREATE TABLE assets (
id UUID,
ticker VARCHAR(20), -- 영문 컬럼명
name VARCHAR(100),
market_cap BIGINT,
stock_type VARCHAR(20),
sector VARCHAR(100),
last_price NUMERIC(15,2),
eps NUMERIC(15,2),
bps NUMERIC(15,2),
dividend_per_share NUMERIC(15,2),
market VARCHAR(20),
base_date DATE,
is_active BOOLEAN
);
-- price_data 테이블
CREATE TABLE price_data (
timestamp TIMESTAMP, -- 영문 컬럼명
open NUMERIC(15,2),
high NUMERIC(15,2),
low NUMERIC(15,2),
close NUMERIC(15,2),
volume BIGINT,
ticker VARCHAR(20)
);
-- financial_statements 테이블
CREATE TABLE financial_statements (
id UUID,
ticker VARCHAR(20),
account VARCHAR(100),
base_date DATE,
value NUMERIC(20,2),
disclosure_type CHAR(1)
);
마이그레이션 매핑 (scripts/migrate_mysql_to_postgres.py)
kor_ticker → assets:
asset = Asset(
ticker=row['종목코드'], # 한글 → ticker
name=row['종목명'], # 한글 → name
market=row['시장구분'], # 한글 → market
last_price=row['종가'], # 한글 → last_price
market_cap=row['시가총액'], # 한글 → market_cap
eps=row['EPS'], # 영문 → eps
bps=row['BPS'], # 영문 → bps
dividend_per_share=row['주당배당금'], # 한글 → dividend_per_share
stock_type=row['종목구분'], # 한글 → stock_type
base_date=row['기준일'], # 한글 → base_date
is_active=True
)
kor_price → price_data:
price = PriceData(
ticker=row['종목코드'], # 한글 → ticker
timestamp=row['날짜'], # 한글 → timestamp
open=row['시가'], # 한글 → open
high=row['고가'], # 한글 → high
low=row['저가'], # 한글 → low
close=row['종가'], # 한글 → close
volume=row['거래량'] # 한글 → volume
)
kor_fs → financial_statements:
fs = FinancialStatement(
ticker=row['종목코드'], # 한글 → ticker
account=row['계정'], # 한글 → account
base_date=row['기준일'], # 한글 → base_date
value=row['값'], # 한글 → value
disclosure_type=row['공시구분'] # 한글 → disclosure_type
)
마이그레이션 매핑 테이블
| 테이블 | MySQL 컬럼 (한글) | PostgreSQL 컬럼 (영문) | 타입 변경 |
|---|---|---|---|
| kor_ticker → assets | |||
| 종목코드 | ticker | VARCHAR(20) | |
| 종목명 | name | VARCHAR(100) | |
| 시장구분 | market | VARCHAR(20) | |
| 시가총액 | market_cap | BIGINT | |
| 종가 | last_price | INT → NUMERIC(15,2) | |
| EPS | eps | DECIMAL → NUMERIC(15,2) | |
| BPS | bps | DECIMAL → NUMERIC(15,2) | |
| 주당배당금 | dividend_per_share | DECIMAL → NUMERIC(15,2) | |
| 종목구분 | stock_type | VARCHAR(20) | |
| 기준일 | base_date | DATE | |
| kor_price → price_data | |||
| 종목코드 | ticker | VARCHAR(20) | |
| 날짜 | timestamp | DATE → TIMESTAMP | |
| 시가 | open | INT → NUMERIC(15,2) | |
| 고가 | high | INT → NUMERIC(15,2) | |
| 저가 | low | INT → NUMERIC(15,2) | |
| 종가 | close | INT → NUMERIC(15,2) | |
| 거래량 | volume | BIGINT | |
| kor_fs → financial_statements | |||
| 종목코드 | ticker | VARCHAR(20) | |
| 계정 | account | VARCHAR(100) | |
| 기준일 | base_date | DATE | |
| 값 | value | DECIMAL → NUMERIC(20,2) | |
| 공시구분 | disclosure_type | CHAR(1) |
10. 전체 데이터 흐름
┌─────────────────────────────────────────────────────┐
│ MySQL (make-quant-py) │
│ kor_ticker: 종목코드, 종목명, 시장구분, 시가총액 │
│ kor_price: 날짜, 시가, 고가, 저가, 종가, 거래량 │
│ kor_fs: 종목코드, 계정, 기준일, 값, 공시구분 │
│ 👆 한글 컬럼명 │
└─────────────────────────────────────────────────────┘
│
│ scripts/migrate_mysql_to_postgres.py
│ (한글 → 영문 매핑)
│ row['종목코드'] → Asset.ticker
│ row['시가'] → PriceData.open
▼
┌─────────────────────────────────────────────────────┐
│ PostgreSQL (현재 프로젝트) │
│ assets: ticker, name, market, market_cap │
│ price_data: timestamp, open, high, low, close │
│ financial_statements: ticker, account, base_date │
│ 👆 영문 컬럼명 │
└─────────────────────────────────────────────────────┘
│
│ app/utils/data_helpers.py
│ (영문 → 한글 매핑)
│ asset.ticker → '종목코드'
│ price.open → '시가'
▼
┌─────────────────────────────────────────────────────┐
│ DataFrame (전략 코드) │
│ 종목코드, 종목명, 시장, 섹터 │
│ 날짜, 시가, 고가, 저가, 종가, 거래량 │
│ 종목코드, 계정, 기준일, 값 │
│ 👆 한글 컬럼명 (make-quant-py 호환) │
└─────────────────────────────────────────────────────┘
일관성 보장
모든 레이어에서 동일한 매핑 규칙 사용:
-
MySQL → PostgreSQL (마이그레이션):
row['종목코드']→Asset.tickerrow['시가']→PriceData.open
-
PostgreSQL → DataFrame (data_helpers):
asset.ticker→'종목코드'price.open→'시가'
-
결과: make-quant-py 전략 코드가 수정 없이 작동!
# 전략 코드에서 그대로 사용 가능 ticker_list['종목코드'].tolist() price_df['시가'].mean()
11. 결론
현재 프로젝트는 하이브리드 컬럼명 방식을 채택하여:
- ✅ DB 표준 준수: PostgreSQL 영문 컬럼명
- ✅ make-quant-py 호환: DataFrame 한글 컬럼명
- ✅ 마이그레이션 일관성: MySQL → PostgreSQL 자동 매핑
- ✅ 명확한 책임 분리:
scripts/migrate_mysql_to_postgres.py- 마이그레이션 변환app/utils/data_helpers.py- 쿼리 결과 변환
개발자 가이드
- DB 스키마 작업 → 영문 컬럼명 사용
- 전략 코드 작성 → 한글 컬럼명 사용
- 새 컬럼 추가 → 세 곳 모두 업데이트:
- PostgreSQL 모델 (영문)
- data_helpers.py 매핑 (영문→한글)
- 마이그레이션 스크립트 (한글→영문) - 필요 시
마이그레이션 실행
python scripts/migrate_mysql_to_postgres.py \
--mysql-host localhost \
--mysql-user root \
--mysql-password password \
--mysql-database quant_db
문서 버전: v1.1.0 최종 업데이트: 2024년 1월 (마이그레이션 매핑 추가)