eda
| topics | 100-데이터분석 & AI 103 데이터 분석,처리 |
| types | 레퍼런스 학습 |
| contexts | 학교 |
| tags |
EDA - 가상화폐 시장 예측 대회
데이터 설명
캐글 가상화폐 시장 예측 대회에서 사용한 데이터다. 주문서(Order Book) 정보와 거래 데이터를 기반으로 가격 방향을 예측한다.
타겟 변수: label (가격 상승/하락 예측)
컬럼 설명
기본 컬럼
| 용어 | 의미 |
|---|---|
| bid_qty | 매수 호가 수량(매수잔량): 현재 시장에 올라와 있는 매수 주문(살 사람)이 원하는 구매 수량의 총합 |
| ask_qty | 매도 호가 수량(매도잔량): 현재 시장에 올라와 있는 매도 주문(팔 사람)이 원하는 판매 수량의 총합 |
| buy_qty | 매수 수량: 지정된 시간 또는 가격 구간에서 실제로 체결된 매수(구입) 거래의 수량 |
| sell_qty | 매도 수량: 지정된 시간 또는 가격 구간에서 실제로 체결된 매도(판매) 거래의 수량 |
| volume | 거래량: 특정 기간 동안 해당 가상화폐가 실제로 거래된 총 수량 또는 금액 (보통 24시간 기준) |
전체 컬럼 리스트
['bid_qty', 'ask_qty', 'buy_qty', 'sell_qty', 'volume',
'X1', 'X2', 'X3', ..., 'X780', 'label']
총 780개의 익명화된 특성(X1~X780)과 5개의 기본 특성, 1개의 타겟 변수로 구성된다.
주요 Feature 선택
핵심 Feature (상위권 솔루션 공통)
기본 특성
bid_qty,ask_qty,buy_qty,sell_qty,volume
중요한 X 특성
X598,X344,X363,X405,X321X175,X179,X197,X22,X181X28,X169,X198,X173,X338
왜 이 특성들이 중요할까?
주문서의 불균형, 거래 강도, 시장 유동성 같은 시장 구조적 특성을 나타내는 것으로 추정된다.
솔루션별 Feature 선택
1. johndoe2011 솔루션
features = [
'X363', 'X405', 'X321',
'X175', 'X179', 'X137', 'X197', 'X22', 'X40', 'X181',
'X28', 'X169', 'X198', 'X173',
'X338', 'X288', 'X385', 'X344', 'X427', 'X587', 'X450',
'X97', 'X52', 'X444',
'X598', 'X379', 'X696', 'X297', 'X138',
'X572', 'X343', 'X586', 'X466', 'X438', 'X452', 'X459',
'X435', 'X386', 'X55', 'X341', 'X683', 'X428', 'X605',
'X445', 'X272', 'X180', 'X593', 'X680',
'X686', 'X692', 'X695',
"X603", "X674", "X421", "X333",
"X415", "X345", "X174", "X302", "X178", "X168", "X612",
"buy_qty", "sell_qty", "volume",
"bid_qty", "ask_qty",
]
출처: https://www.kaggle.com/code/johndoe2011/anyone-can-win-on-public-lb
2. rosswade 솔루션
FEATURES = [
"X863", "X856", "X344", "X598", "X862", "X385", "X852", "X603", "X860", "X674",
"X415", "X345", "X137", "X855", "X174", "X302", "X178", "X532", "X168", "X612",
"bid_qty", "ask_qty", "buy_qty", "sell_qty", "volume",
"X888", "X421", "X333"
]
출처: https://www.kaggle.com/code/rosswade/drw-crypto-market-submission
3. taylorsamarel 솔루션
core_features = [
'X363', 'X405', 'X321', 'X175', 'X179', 'X197', 'X22', 'X181', 'X28', 'X169',
'X198', 'X173', 'X338', 'X344', 'X587', 'X450', 'X97', 'X52', 'X444', 'X598',
'X297', 'X138', 'X572', 'X343', 'X438', 'X459', 'X758', 'X25',
'buy_qty', 'sell_qty', 'volume', 'bid_qty'
]
출처: https://www.kaggle.com/code/taylorsamarel/xgb-deep-learning-ensemble
Feature Engineering
상호작용 및 기본 관계 지표
주문서 유동성과 실제 거래 간의 상호작용을 나타내는 특성들이다.
"""
거래 활성도와 실제로 내놨을 때 얼마나 팔렸나를 평가하는 척도들
"""
# <span id="매수매도-호가-수량의-곱-주문서-유동성의-쌍방향-규모-예상"></span>매수/매도 호가 수량의 곱. 주문서 유동성의 쌍방향 규모 예상
df['bid_ask_interaction'] = df['bid_qty'] * df['ask_qty']
# <span id="매수-호가수량-실제-매수-체결량-호가잔량과-실제-매수간-상호작용-지표"></span>매수 호가수량 × 실제 매수 체결량. 호가잔량과 실제 매수간 상호작용 지표
df['bid_buy_interaction'] = df['bid_qty'] * df['buy_qty']
# <span id="매수-호가수량-실제-매도-체결량-미체결-매수와-매도-거래간-연결도"></span>매수 호가수량 × 실제 매도 체결량. 미체결 매수와 매도 거래간 연결도
df['bid_sell_interaction'] = df['bid_qty'] * df['sell_qty']
# <span id="매도-호가수량-실제-매수-체결량-미체결-매도와-매수-거래간-연결도"></span>매도 호가수량 × 실제 매수 체결량. 미체결 매도와 매수 거래간 연결도
df['ask_buy_interaction'] = df['ask_qty'] * df['buy_qty']
# <span id="매도-호가수량-실제-매도-체결량-호가잔량과-실제-매도간-상호작용-지표"></span>매도 호가수량 × 실제 매도 체결량. 호가잔량과 실제 매도간 상호작용 지표
df['ask_sell_interaction'] = df['ask_qty'] * df['sell_qty']
# <span id="실제-매수매도-체결량의-곱-거래-활성도의-상대-척도"></span>실제 매수·매도 체결량의 곱. 거래 활성도의 상대 척도
df['buy_sell_interaction'] = df['buy_qty'] * df['sell_qty']
# <span id="매도호가수량-매수호가수량양-호가잔량-누적로-유동성-불균형-지표"></span>(매도호가수량-매수호가수량)/(양 호가잔량 누적)로 유동성 불균형 지표
df['spread_indicator'] = (df['ask_qty'] - df['bid_qty']) / (df['ask_qty'] + df['bid_qty'] + 1e-8)
# <span id="실시간-매수-체결량매도-체결량-비율"></span>실시간 매수 체결량/매도 체결량 비율
df['buy_sell_ratio'] = df['buy_qty'] / (df['sell_qty'] + 1e-8)
# <span id="매수호가잔량매도호가잔량-비율"></span>매수호가잔량/매도호가잔량 비율
df['bid_ask_ratio'] = df['bid_qty'] / (df['ask_qty'] + 1e-8)
유동성 지표
# <span id="유동성"></span>유동성
df['total_liquidity'] = df['bid_qty'] + df['ask_qty']
# <span id="유동성-불균형도"></span>유동성 불균형도
df['liquidity_imbalance'] = (df['bid_qty'] - df['ask_qty']) / (df['total_liquidity'] + 1e-8)
# <span id="매수-체결량매수호가-매수세가-호가잔량-대비-얼마나-큰지"></span>매수 체결량/매수호가. 매수세가 호가잔량 대비 얼마나 큰지
df['normalized_buy_volume'] = df['buy_qty'] / (df['bid_qty'] + 1e-8)
# <span id="매도-체결량매도호가-매도세가-호가잔량-대비-얼마나-큰지"></span>매도 체결량/매도호가. 매도세가 호가잔량 대비 얼마나 큰지
df['normalized_sell_volume'] = df['sell_qty'] / (df['ask_qty'] + 1e-8)
거래 강도 지표
각 매수매도의 힘과 전체 시장의 방향성과 힘이 얼마인지를 확인할 수 있다.
# <span id="매도호가수량-매수호가수량총거래량-유동성-대비-스프레드-지표"></span>매도호가수량-매수호가수량)/총거래량. 유동성 대비 스프레드 지표
df['relative_spread'] = (df['ask_qty'] - df['bid_qty']) / (df['volume'] + 1e-8)
# <span id="볼륨-가중-지표"></span>볼륨 가중 지표
df['volume_weighted_buy'] = df['buy_qty'] * df['volume']
df['volume_weighted_sell'] = df['sell_qty'] * df['volume']
df['volume_weighted_bid'] = df['bid_qty'] * df['volume']
df['volume_weighted_ask'] = df['ask_qty'] * df['volume']
# <span id="실시간-매수매도-힘-균형"></span>실시간 매수·매도 힘 균형
df['order_flow_imbalance'] = (df['buy_qty'] - df['sell_qty']) / (df['volume'] + 1e-8)
# <span id="볼륨을-반영한-유동성-불균형도"></span>볼륨을 반영한 유동성 불균형도
df['liquidity_adjusted_imbalance'] = df['order_flow_imbalance'] * df['depth_ratio']
# <span id="매수매도-압력"></span>매수/매도 압력
df['buying_pressure'] = df['buy_qty'] / (df['volume'] + 1e-8)
df['selling_pressure'] = df['sell_qty'] / (df['volume'] + 1e-8)
# <span id="전체-체결횟수총거래량-시장의-거래-활성-수준"></span>전체 체결횟수/총거래량. 시장의 거래 활성 수준
df['trade_intensity'] = (df['buy_qty'] + df['sell_qty']) / (df['volume'] + 1e-8)
# <span id="평균-체결-단위-한-번-거래당-평균-체결량"></span>평균 체결 단위. 한 번 거래당 평균 체결량
df['avg_trade_size'] = df['volume'] / (df['buy_qty'] + df['sell_qty'] + 1e-8)
# <span id="실질-순매수매도-흐름-매수-매도매수매도"></span>실질 순매수/매도 흐름. (매수-매도)/(매수+매도)
df['net_trade_flow'] = (df['buy_qty'] - df['sell_qty']) / (df['buy_qty'] + df['sell_qty'] + 1e-8)
# <span id="총유동성총거래량-시장-유동성-깊이-척도"></span>총유동성/총거래량. 시장 유동성 깊이 척도
df['depth_ratio'] = df['total_liquidity'] / (df['volume'] + 1e-8)
df['volume_participation'] = (df['buy_qty'] + df['sell_qty']) / (df['total_liquidity'] + 1e-8)
# <span id="시장-활성-지표-주문서-실제-거래의-복합-지표"></span>시장 활성 지표. 주문서-실제 거래의 복합 지표
df['market_activity'] = df['volume'] * df['total_liquidity']
# <span id="체결량-차이거래량-시장-실효적-스프레드-근사치"></span>체결량 차이/거래량. 시장 실효적 스프레드 근사치
df['effective_spread_proxy'] = np.abs(df['buy_qty'] - df['sell_qty']) / (df['volume'] + 1e-8)
df['realized_volatility_proxy'] = np.abs(df['order_flow_imbalance']) * df['volume']
# <span id="매수압력-스프레드-지표-매수세와-유동성-스프레드의-복합-움직임"></span>매수압력 × 스프레드 지표. 매수세와 유동성 스프레드의 복합 움직임
df['pressure_spread_interaction'] = df['buying_pressure'] * df['spread_indicator']
추가 유용한 특성 (rosswade 솔루션)
# <span id="로그-변환"></span>로그 변환
df['log_volume'] = np.log1p(df['volume'])
# <span id="호가-불균형"></span>호가 불균형
df['bid_ask_imbalance'] = (df['bid_qty'] - df['ask_qty']) / (df['bid_qty'] + df['ask_qty'] + 1e-8)
# <span id="주문-흐름-불균형"></span>주문 흐름 불균형
df['order_flow_imbalance'] = (df['buy_qty'] - df['sell_qty']) / (df['buy_qty'] + df['sell_qty'] + 1e-8)
# <span id="유동성-비율"></span>유동성 비율
df['liquidity_ratio'] = (df['bid_qty'] + df['ask_qty']) / (df['volume'] + 1e-8)
왜 이렇게 했냐면: 원본 특성만으로는 시장의 구조적 패턴을 충분히 표현하기 어렵다. 특성 간 상호작용을 만들어서 모델이 더 복잡한 패턴을 학습할 수 있게 한다.
참고 자료
Kaggle 솔루션
- https://www.kaggle.com/code/johndoe2011/anyone-can-win-on-public-lb
- https://www.kaggle.com/code/rosswade/drw-crypto-market-submission
- https://www.kaggle.com/code/taylorsamarel/xgb-deep-learning-ensemble
- https://www.kaggle.com/code/vishalpainjane/drw-ensemble-0-72837