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, X321
  • X175, X179, X197, X22, X181
  • X28, 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 솔루션

리지 회귀 참고 자료


관련 문서