볼륨 프로파일 자동매매 전략

볼륨 프로파일이란?

볼륨 프로파일(Volume Profile)은 특정 가격대에서 거래된 총 거래량을 수평 히스토그램으로 표시하는 분석 도구입니다. 일반적인 거래량 지표가 시간 축 기반인 반면, 볼륨 프로파일은 가격 축 기반으로 어떤 가격대에서 가장 많은 거래가 발생했는지를 보여줍니다.

기관 투자자와 마켓 메이커가 활발히 거래하는 가격대를 파악할 수 있어, 지지·저항 수준을 객관적으로 판단하는 데 핵심적인 역할을 합니다. 퀀트 자동매매에서 볼륨 프로파일을 활용하면 감에 의존하지 않고 데이터 기반의 매매 결정이 가능합니다.

핵심 구성 요소: POC, VAH, VAL

볼륨 프로파일에서 반드시 알아야 할 세 가지 핵심 지표가 있습니다.

  • POC (Point of Control): 가장 많은 거래량이 발생한 가격대. 시장의 “공정 가치(Fair Value)”로 해석
  • VAH (Value Area High): 전체 거래량의 상위 70%가 발생한 영역의 상단
  • VAL (Value Area Low): 전체 거래량의 상위 70%가 발생한 영역의 하단
  • Value Area: VAL~VAH 사이 구간으로, 전체 거래의 약 70%가 집중된 “가치 영역”

가격이 Value Area 밖으로 이탈하면 추세 발생 신호, Value Area 안으로 회귀하면 평균회귀 신호로 활용할 수 있습니다.

파이썬으로 볼륨 프로파일 계산

아래 코드는 OHLCV 데이터에서 볼륨 프로파일의 POC, VAH, VAL을 계산하는 클래스입니다.

import numpy as np
import pandas as pd

class VolumeProfile:
    def __init__(self, num_bins=50, value_area_pct=0.70):
        self.num_bins = num_bins
        self.value_area_pct = value_area_pct
    
    def calculate(self, df, period=20):
        """최근 N봉 기준 볼륨 프로파일 계산"""
        data = df.tail(period).copy()
        price_min = data['low'].min()
        price_max = data['high'].max()
        
        # 가격대별 빈(bin) 생성
        bins = np.linspace(price_min, price_max, self.num_bins + 1)
        bin_centers = (bins[:-1] + bins[1:]) / 2
        volume_at_price = np.zeros(self.num_bins)
        
        # 각 캔들의 거래량을 가격 범위에 분배
        for _, row in data.iterrows():
            candle_low = row['low']
            candle_high = row['high']
            candle_vol = row['volume']
            
            # 해당 캔들이 걸치는 빈에 거래량 균등 분배
            mask = (bin_centers >= candle_low) & (bin_centers <= candle_high)
            n_bins_hit = mask.sum()
            if n_bins_hit > 0:
                volume_at_price[mask] += candle_vol / n_bins_hit
        
        # POC: 최대 거래량 가격대
        poc_idx = np.argmax(volume_at_price)
        poc_price = bin_centers[poc_idx]
        
        # Value Area 계산 (POC에서 양쪽으로 확장)
        total_volume = volume_at_price.sum()
        target_volume = total_volume * self.value_area_pct
        
        va_low_idx = poc_idx
        va_high_idx = poc_idx
        accumulated = volume_at_price[poc_idx]
        
        while accumulated < target_volume:
            expand_up = (volume_at_price[va_high_idx + 1] 
                        if va_high_idx + 1 < self.num_bins else 0)
            expand_down = (volume_at_price[va_low_idx - 1] 
                          if va_low_idx - 1 >= 0 else 0)
            
            if expand_up >= expand_down and va_high_idx + 1 < self.num_bins:
                va_high_idx += 1
                accumulated += expand_up
            elif va_low_idx - 1 >= 0:
                va_low_idx -= 1
                accumulated += expand_down
            else:
                break
        
        return {
            'poc': poc_price,
            'vah': bin_centers[va_high_idx],
            'val': bin_centers[va_low_idx],
            'volume_profile': dict(zip(bin_centers, volume_at_price))
        }

볼륨 프로파일 기반 자동매매 전략

볼륨 프로파일의 핵심 지표를 활용한 자동매매 전략을 구현합니다. Value Area 이탈·회귀 패턴을 기반으로 매매 신호를 생성합니다.

class VolumeProfileStrategy:
    def __init__(self, lookback=20, num_bins=50):
        self.vp = VolumeProfile(num_bins=num_bins)
        self.lookback = lookback
        self.position = 0  # 1: 롱, -1: 숏, 0: 없음
    
    def generate_signal(self, df, current_idx):
        """현재 시점에서 매매 신호 생성"""
        if current_idx < self.lookback:
            return 0
        
        window = df.iloc[current_idx - self.lookback:current_idx]
        profile = self.vp.calculate(window, period=self.lookback)
        
        current_price = df.iloc[current_idx]['close']
        prev_price = df.iloc[current_idx - 1]['close']
        poc = profile['poc']
        vah = profile['vah']
        val = profile['val']
        
        signal = 0
        
        # 전략 1: VAL 하향 이탈 후 복귀 → 롱
        if prev_price < val and current_price > val:
            signal = 1  # 롱 진입
        
        # 전략 2: VAH 상향 이탈 후 복귀 → 숏
        elif prev_price > vah and current_price < vah:
            signal = -1  # 숏 진입
        
        # 전략 3: POC 도달 → 포지션 청산
        elif self.position != 0:
            if abs(current_price - poc) / poc < 0.002:
                signal = 0  # 청산
        
        return signal
    
    def backtest(self, df):
        """백테스트 실행"""
        results = []
        
        for i in range(self.lookback, len(df)):
            signal = self.generate_signal(df, i)
            
            if signal != self.position:
                self.position = signal
            
            daily_return = df.iloc[i]['close'] / df.iloc[i-1]['close'] - 1
            strategy_return = self.position * daily_return
            
            results.append({
                'date': df.index[i],
                'price': df.iloc[i]['close'],
                'signal': signal,
                'strategy_return': strategy_return
            })
        
        return pd.DataFrame(results)

고급 활용: 복합 볼륨 프로파일

단일 기간이 아닌 다중 타임프레임 볼륨 프로파일을 결합하면 더 정확한 지지·저항 수준을 파악할 수 있습니다.

def multi_timeframe_profile(df, periods=[5, 20, 60]):
    """다중 기간 볼륨 프로파일에서 겹치는 POC 영역 탐지"""
    vp = VolumeProfile(num_bins=100)
    profiles = {}
    
    for period in periods:
        if len(df) >= period:
            profiles[period] = vp.calculate(df, period=period)
    
    # POC 수렴 영역 탐색
    poc_prices = [p['poc'] for p in profiles.values()]
    poc_mean = np.mean(poc_prices)
    poc_std = np.std(poc_prices)
    
    # POC가 수렴할수록 강한 지지/저항
    confluence_score = 1.0 / (1.0 + poc_std / poc_mean * 100)
    
    return {
        'profiles': profiles,
        'poc_confluence': poc_mean,
        'confluence_strength': round(confluence_score, 3),
        'is_strong_level': confluence_score > 0.8
    }

다중 기간의 POC가 비슷한 가격대에 수렴하면 해당 가격은 매우 강력한 지지/저항선으로 작용합니다. 이를 통해 진입·청산 정확도를 높일 수 있습니다.

실전 적용 체크리스트

  • 데이터 품질: 틱 데이터 또는 1분봉 이상의 고해상도 데이터 사용 권장
  • 빈(bin) 개수 설정: 너무 적으면 해상도 부족, 너무 많으면 노이즈 — 자산 변동성에 따라 30~100개 조절
  • 리스크 관리: Value Area 이탈 시 추세 추종과 평균회귀 중 시장 상황에 맞는 전략 선택
  • 거래량 필터: 거래량이 극단적으로 낮은 시간대(새벽 등)는 프로파일 신뢰도 하락
  • 갱신 주기: 실시간 자동매매에서는 매 봉마다 프로파일을 재계산하여 최신 상태 유지

볼륨 프로파일 전략은 오더플로우 자동매매 분석과 결합하면 더욱 강력해집니다. 또한 자동매매 슬리피지 최소화 전략을 함께 적용하여 실전 수익률을 개선할 수 있습니다.

결론

볼륨 프로파일은 가격대별 거래량 분포를 통해 시장 참여자들의 실제 관심 가격을 파악하는 핵심 도구입니다. POC, VAH, VAL을 활용한 자동매매 전략은 기술적 지표만으로는 알 수 없는 수급 기반의 매매 근거를 제공합니다. 파이썬으로 직접 구현하여 자신만의 퀀트 전략에 통합해 보세요.

위로 스크롤
WordPress Appliance - Powered by TurnKey Linux