거래량 가중 평균값, VWAP 파이썬 코딩
거래량 가중 평균값(VWAP, Volume Weighted Average Price)은 주식이나 코인 시장에서 가격과 거래량의 관계를 단순 평균보다 정교하게 반영할 수 있는 기술적 지표입니다. 이번 포스팅에서는 파이썬 코딩을 통해 VWAP을 계산하는 방법을 차근차근 살펴보겠습니다. 거래량 가중 평균값을 통해 시장의 평균 체결가가 어디쯤인지 확인해 보시기 바랍니다.
글의 순서
거래량 가중 평균값(VWAP, Volume Weighted Average Price)
거래량 가중 평균값(VWAP)을 구하는 방법
예제를 통한 VWAP 계산 방법 이해
거래량 가중 평균값, VWAP 파이썬 코딩
거래량 가중 평균값(VWAP, Volume Weighted Average Price)
거래량 가중 평균값(VWAP, Volume Weighted Average Price)은 단순 이동평균선에 거래량을 합친 기술적 지표입니다. 거래량이 많을수록 해당 구간의 가격이 더 큰 가중치를 갖게 만듭니다.
예를 들어 어느 시점에 거래량이 크게 터지면서 주가(혹은 코인 시세)가 상승했다면, VWAP 역시 일반 이동평균선보다 민감하게 반응하며 더 빠르게 위로 따라가는 모습을 보입니다. 이렇게 가격뿐 아니라 거래량을 함께 고려하기 때문에, 거래가 많이 일어난 실제 체결 지점을 좀 더 정확히 반영해준다는 장점이 있습니다.
VWAP은 주로 인트라데이 차트(당일 거래 시간 내의 가격 변동)에 적용되어, 시장 흐름이 상승 쪽으로 기울었는지, 아니면 하락 쪽으로 기울었는지를 파악하는 데 도움을 줍니다. 하루 기준으로 보통 장 시작부터 값을 쌓아가며 계산하지만, 응용에 따라 1주일이나 1개월처럼 기간을 확장해 장기 추세를 파악할 수도 있습니다. 다만, 인트라데이 특성상 ‘내가 원하는 특정 시간대부터 계산을 시작’하기는 어렵다는 점이 일반적인 이동평균선과 다릅니다.
가격이 VWAP 위에 있으면 매수세 우위, 아래에 있으면 매도세 우위로 간단히 해석할 수 있습니다. 시장의 전반적인 방향성을 가늠하고자 할 때 VWAP는 유용하다고 할 수 있습니다.
거래량 가중 평균값(VWAP)을 구하는 방법
거래량 가중 평균값(VWAP, Volume Weighted Average Price)을 계산하는 과정은 다음과 같습니다.
step1) Typical Price(TP) 계산
TP = (고가 + 저가 + 종가) / 3
step2) TP × Volume 계산
각 봉(캔들)마다 앞에서 구한 TP에 해당 봉의 거래량을 곱함
step3) TP×Volume 누적합 계산
현재 봉까지 발생한 (TP×Volume)의 합을 순차적으로 더해나감 (cumulative)
step4) Volume의 누적합 계산
각 봉별 거래량을 순차적으로 더해나감
step5) VWAP 계산
VWAP = (누적 (TP×Volume)) / (누적 Volume)
즉, (TP×Volume)의 누적합을 거래량의 누적합으로 나눈 값이 당 시점의 거래량 가중 평균 가격이 됨.
예제를 통한 VWAP 계산 방법 이해
아래 세 개의 봉(캔들)에 대해, 각 봉의 고가·저가·종가와 거래량이 다음과 같다고 가정해보겠습니다.
| 봉(캔들) | 고가(High) | 저가(Low) | 종가(Close) | 거래량(Volume) |
|---|---|---|---|---|
| 1 | 100 | 90 | 95 | 1,000 |
| 2 | 102 | 92 | 98 | 1,200 |
| 3 | 105 | 95 | 100 | 800 |
step1) TP 계산
봉1의 TP = (100 + 90 + 95) ÷ 3 = 285 ÷ 3 = 95
봉2의 TP = (102 + 92 + 98) ÷ 3 = 292 ÷ 3 = 97.33
봉3의 TP = (105 + 95 + 100) ÷ 3 = 300 ÷ 3 = 100
step2) TP × Volume
봉1: 95 × 1,000 = 95,000
봉2: 97.33 × 1,200 = 116,796
봉3: 100 × 800 = 80,000
step3) (TP×Volume) 누적합
봉1: 95,000
봉2: 95,000 + 116,796 = 211,796
봉3: 211,796 + 80,000 = 291,796
step4) Volume 누적합
봉1: 1,000
봉2: 1,000 + 1,200 = 2,200
봉3: 2,200 + 800 = 3,000
step5) VWAP 계산
봉1의 VWAP = 95,000 / 1,000 = 95
봉2의 VWAP = 211,796 / 2,200 = 96.27
봉3의 VWAP = 291,796 / 3,000 = 97.27
이렇게 해서, 각 시점별로 거래량을 반영한 평균 가격(VWAP)을 계산할 수 있습니다. 이를 차트에 표시하면, 단순 이동평균선보다 거래량이 크게 실린 구간의 가격 움직임을 더욱 민감하게 추적할 수 있게 됩니다.
거래량 가중 평균값, VWAP 파이썬 코딩
거래량 가중 평균값, VWAP를 아래의 파이썬 코드에서 구현하였습니다. 아래의 파이썬 코드는 KIS API를 활용하여 하루 동안의 1분봉 데이터를 가져오고, 이를 3분봉으로 바꾼 후, VWAP를 계산합니다. KIS API를 활용하여 데이터를 가져오고, 3분봉으로 바꾸는 과정은 지난 포스팅, 한국투자증권 API, 3분봉, 5분봉, 10분봉… 원하는 분봉 자유롭게 만드는 방법의 실습코드와 동일합니다. 이번에는 여기에 VWAP를 계산하는 루틴만 추가한 것입니다.
거래량 가중 평균값, VWAP 계산을 위한 주요 함수는 다음과 같습니다.
▶ resample_candlestick 함수는 3분봉 데이터를 생성하여 캔들스틱 차트의 기본 데이터를 제공합니다.
▶ calculate_vwap 함수는 Typical Price와 거래량을 기반으로 VWAP를 계산합니다. 이 함수는 최근 n개 봉의 데이터를 고려하여 rolling 방식으로 계산됩니다.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 |
import os import requests import json import datetime import pandas as pd import matplotlib.pyplot as plt # KIS API 설정 api_key = os.getenv('KIS_APP_KEY') api_secret = os.getenv('KIS_APP_SECRET') # KIS API 기본 설정 URL_BASE = "https://openapi.koreainvestment.com:9443" # 액세스 토큰 발급 함수 def get_access_token(): """KIS API를 위한 액세스 토큰 발급""" headers = {"content-type": "application/json"} body = { "grant_type": "client_credentials", "appkey": api_key, "appsecret": api_secret } PATH = "/oauth2/tokenP" URL = f"{URL_BASE}{PATH}" res = requests.post(URL, headers=headers, data=json.dumps(body)) if res.status_code == 200: access_token = res.json()["access_token"] return access_token else: print(f"Failed to get access token: {res.json()}") return None # time_end를 minutes만큼 줄여주는 함수 def decrease_time(time_str, minutes): """time_str을 분 단위로 감소시켜서 새로운 시간을 반환""" time_format = '%H%M%S' dt = datetime.datetime.strptime(time_str, time_format) dt -= datetime.timedelta(minutes=minutes) return dt.strftime(time_format) # 당일 분봉 OHLCV 데이터 조회 함수 def get_minute_ohlcv_data(access_token, code, time_end="153000"): """당일 분봉 OHLCV 데이터를 조회하고 DataFrame으로 반환""" PATH = "/uapi/domestic-stock/v1/quotations/inquire-time-itemchartprice" URL = f"{URL_BASE}{PATH}" all_data = [] # 반복적으로 데이터를 요청하면서 time_end 값을 줄여가며 데이터를 받아옴 while True: # 현재 날짜 설정 # today = datetime.datetime.now().strftime('%Y%m%d') headers = { "Content-Type": "application/json", "authorization": f"Bearer {access_token}", "appKey": api_key, "appSecret": api_secret, "tr_id": "FHKST03010200", # 당일 분봉 데이터 조회용 거래 ID } params = { "FID_ETC_CLS_CODE": "", # 기타 구분 코드 "FID_COND_MRKT_DIV_CODE": "J", # 시장 분류 코드 "FID_INPUT_ISCD": code, # 종목 코드 "FID_INPUT_HOUR_1": time_end, # 조회 종료 시간 (HHMMSS) "FID_PW_DATA_INCU_YN": "N" # 과거 데이터 포함 여부 (N: 당일만 조회) } res = requests.get(URL, headers=headers, params=params) if res.status_code == 200: res_data = res.json() data = res_data.get('output2', []) if data: # OHLCV 데이터를 DataFrame으로 변환 ohlcv_data = [{ "Date": item['stck_bsop_date'], # 거래일자 "Time": item['stck_cntg_hour'], # 체결 시간 "Open": item['stck_oprc'], # 시가 "High": item['stck_hgpr'], # 고가 "Low": item['stck_lwpr'], # 저가 "Close": item['stck_prpr'], # 종가 "Volume": item['cntg_vol'] # 체결 거래량 } for item in data] all_data.extend(ohlcv_data) # 30개의 데이터를 받았으면 time_end를 줄여서 다음 데이터를 요청 time_end = decrease_time(time_end, minutes=30) print(f"Next time_end: {time_end}") else: print("No more data available for the specified time.") break else: print(f"Failed to retrieve data: {res.status_code}, {res.text}") return None # DataFrame 생성 및 정렬 df = pd.DataFrame(all_data) df['DateTime'] = pd.to_datetime(df['Date'] + df['Time'], format='%Y%m%d%H%M%S') # 날짜와 시간 결합 df = df.astype({'Open': 'float', 'High': 'float', 'Low': 'float', 'Close': 'float', 'Volume': 'float'}) # 데이터 타입 변환 df = df[['DateTime', 'Open', 'High', 'Low', 'Close', 'Volume']] # 열 정렬 df = df.sort_values(by='DateTime', ascending=True) # 시간 오름차순 정렬 df = df.reset_index(drop=True) # 인덱스를 다시 설정 return df def resample_ohlcv(df, freq='3T'): """ 분 단위 OHLCV 데이터(DataFrame)를 원하는 주기로 묶어서(resample) 새 OHLCV로 반환. freq 예시 - '3T': 3분 간격 - '5T': 5분 간격 - '10T': 10분 간격 - '60T' or '1H': 60분 간격 """ # 1) DateTime을 인덱스로 설정 df = df.set_index('DateTime') # 2) resample()을 이용해 묶기 # Open: 구간의 첫 시가 # High: 구간 중 최고가 # Low: 구간 중 최저가 # Close: 구간의 마지막 종가 # Volume: 구간 거래량 합계 resampled = df.resample(freq).agg({ 'Open': 'first', 'High': 'max', 'Low': 'min', 'Close': 'last', 'Volume': 'sum' }) # 3) NaN 제거 혹은 처리 # 시작 시점에 묶는 과정에서 빈 구간이 생길 수 있으니 필요시 dropna() 처리 resampled = resampled.dropna(how='any') # 4) 인덱스를 다시 컬럼으로 resampled = resampled.reset_index() return resampled def calculate_vwap(df): """ df: 반드시 'High', 'Low', 'Close', 'Volume' 컬럼을 포함. VWAP 계산: 전체 세션의 데이터를 기반으로 누적합을 사용. """ # 원본 보호를 위해 복사 df = df.copy() # (1) Typical Price df['TP'] = (df['High'] + df['Low'] + df['Close']) / 3 # (2) TP × Volume df['TPxVol'] = df['TP'] * df['Volume'] # (3) 누적합 계산: TP×Volume의 누적합 / Volume의 누적합 df['cum_TPxVol'] = df['TPxVol'].cumsum() df['cum_Vol'] = df['Volume'].cumsum() # (4) VWAP 계산 df['VWAP'] = df['cum_TPxVol'] / df['cum_Vol'] return df # 메인 실행 부분 if __name__ == "__main__": access_token = get_access_token() if access_token: # 종목, 조회 종료 시간 지정 (예: 15:30:00까지 데이터를 받아오기 시작) code_stock_krx = '006050' # 예) 현대차 time_end = "152000" # 종료 시간 df_1min = get_minute_ohlcv_data(access_token, code=code_stock_krx, time_end=time_end) if df_1min is not None: print("===== 1분봉 데이터 =====") print(df_1min.tail()) # 3분봉으로 변환 df_3min = resample_ohlcv(df_1min, freq='3T') df_3min = calculate_vwap(df_3min) print("===== 3분봉 데이터 =====") print(df_3min.tail()) else: print("Failed to get access token.") |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
Next time_end: 145000 Next time_end: 142000 Next time_end: 135000 Next time_end: 132000 Next time_end: 125000 Next time_end: 122000 Next time_end: 115000 Next time_end: 112000 Next time_end: 105000 Next time_end: 102000 Next time_end: 095000 Next time_end: 092000 Next time_end: 085000 No more data available for the specified time. ===== 1분봉 데이터 ===== DateTime Open High Low Close Volume 376 2025-01-24 15:16:00 1884.0 1890.0 1883.0 1889.0 6532.0 377 2025-01-24 15:17:00 1886.0 1890.0 1885.0 1890.0 14176.0 378 2025-01-24 15:18:00 1890.0 1894.0 1885.0 1889.0 2175.0 379 2025-01-24 15:19:00 1889.0 1890.0 1885.0 1887.0 11580.0 380 2025-01-24 15:20:00 1887.0 1887.0 1887.0 1887.0 0.0 ===== 3분봉 데이터 ===== DateTime Open High Low Close Volume TP TPxVol cum_TPxVol cum_Vol VWAP 122 2025-01-24 15:06:00 1902.0 1912.0 1900.0 1902.0 17874.0 1904.666667 3.404401e+07 2.456321e+10 12814421.0 1916.841480 123 2025-01-24 15:09:00 1902.0 1910.0 1902.0 1910.0 23614.0 1907.333333 4.503977e+07 2.460825e+10 12838035.0 1916.823991 124 2025-01-24 15:12:00 1910.0 1912.0 1893.0 1895.0 23139.0 1900.000000 4.396410e+07 2.465222e+10 12861174.0 1916.793723 125 2025-01-24 15:15:00 1894.0 1896.0 1883.0 1890.0 42146.0 1889.666667 7.964189e+07 2.473186e+10 12903320.0 1916.705118 126 2025-01-24 15:18:00 1890.0 1894.0 1885.0 1887.0 13755.0 1888.666667 2.597861e+07 2.475784e+10 12917075.0 1916.675260 |
마치며 …
VWAP(거래량 가중 평균값)은 시장의 평균 체결가를 파악하고, 매수세와 매도세의 상대적인 강도를 간단히 해석할 수 있는 강력한 도구입니다. 이번 포스팅에서는 VWAP의 기본 개념과 계산 방법, 그리고 이를 파이썬으로 구현하여 계산하는 과정을 살펴보았습니다. VWAP는 단순 이동평균선보다 더 정교하게 시장의 흐름을 반영하며, 특히 인트라데이 트레이딩에서 의사결정할 때 유용하게 횔용될 수 있습니다.
VWAP는 다양한 지표와 함께 결합하여 더욱 강력한 분석 도구로 발전시킬 수 있습니다. 예를 들어, 피봇 포인트, RSI, 또는 볼린저 밴드와 같은 지표를 VWAP와 함께 활용한다면 매매 결정을 할 때, 좀 더 폭넓은 시각을 가질 수 있을 것입니다.
함께 참고하면 좋은 글
▶ 한국투자증권 API, 3분봉, 5분봉, 10분봉… 원하는 분봉 자유롭게 만드는 방법
▶ 한국투자증권 API로 1분봉 OHLCV 데이터 가져오기
▶ 한국투자증권 REST API로 시계열 데이터를 가져오는 파이썬 코드
▶ 한국투자증권 API로 주가를 가져오는 파이썬 프로그래밍
▶ 한국투자증권 API 신청 방법
▶ RESTful API : 웹 애플리케이션 개발자를 위한 기초부터 실전까지
▶ 파이썬 데이터 분석을 위한 API 이해, REST API, WebSocket API
참고자료
▶ 한국투자증권 파이썬 API 문서
▶ 거래량 가중 이동평균 (VWMA)