Insights·2026-08-05

KRX Open API — Measuring KOSPI Daily Swings Yourself

The KRX Open API is the Korea Exchange's public data service at openapi.krx.co.kr. Put your key in an AUTH_KEY header, pass one date as basDd, and you get that day's open, high, low and close as json. Applying takes the four steps printed on the site: sign up and request a key, browse the service list for the API you want, file a usage request, then build once approved. Almost everyone stalls here, because key approval and per-service usage approval are separate gates and a key alone returns 401 on every call. With that key, thirty lines of standard-library Python produce the mean, median and extreme-day count for any window. Run it around 27 May 2026, when single-stock leveraged ETFs listed, and the 48 trading days on either side show mean absolute daily change rising from 2.56% to 4.08% and mean intraday range from 2.99% to 5.81%. Whether the numbers grew and what made them grow remain separate questions, and this data does not settle the second.

Continues fromWhat does it take to let an AI trade stocks through the Toss Securities Open API?
코스피 일간 등락률 절대값 막대그래프와 20일 이동평균, 2026-05-27 단일종목 레버리지 ETF 상장일 표시, 상장 전후 48거래일 등락률·고저폭 비교 막대와 실측 요약표
코스피 일간 등락폭 — 단일종목 레버리지 ETF 상장 전후 (KRX Open API kospi_dd_trd, 2026-08-04 확정치 기준)

There are actually two kinds of swing

There is more than one way to measure how far a market moved in a day. The familiar one is daily change: today's close divided by yesterday's close. From 6,257 to 6,358 is 1.62%. It tells you where the day ended.

The other is intraday range: the day's high minus its low, divided by the prior close. It tells you how much the day shook. When this article says price swing, it means both together.

One real day shows why you need both. On 29 July 2026 the KOSPI closed down 5.98%, but the gap between its high and low that day was 16.03%. By the close it was a bad day; inside the day it was a different market entirely.

Measuring both requires open, high, low and close, not just the close. That is where the data source starts to matter.

Why free chart sites are not enough

Plenty of sites give quotes for free, and wrong values are rare. The failure shows up somewhere else: whole bars go missing.

Pull the 4 August 2026 KOSPI daily bar from Yahoo Finance and open, high, low and close are all 6,358.95, as if the index never moved. The exchange's own record is open 6,351.38, high 6,389.40, low 6,080.25, close 6,358.95. The range that day was 4.94%.

The dangerous part is that the error is quiet. A wrong value looks wrong; a collapsed bar enters your calculation as 0% and quietly drags the average down. One such day is enough to skew a range average, and several of them make a whole window look calmer than it was.

The failure mode of free sources is not a wrong number but a missing or collapsed one. So for Korean daily index and stock data, go to the exchange.

Applying for the KRX Open API — the four steps as labelled

The Korea Exchange runs Data Marketplace OPEN API at openapi.krx.co.kr. The landing page shows four cards, STEP 01 through STEP 04, and those four are the actual process.

Services are split into seven groups: index, stocks, securities products, bonds, derivatives, general commodities and ESG. The index service that holds daily KOSPI data offers five APIs and answers in both json and xml.

StepLabel on the siteWhat you do
STEP 01Login / key requestSign up for Data Marketplace and log in (companies register business details, individuals use identity verification or social login), then request an authentication key and wait for admin approval.
STEP 02Browse the API service listFind the API you want in the service list and its spec sheet. Daily KOSPI index data is kospi_dd_trd under the index category. A sample console lets you test calls first.
STEP 03Request API usageFile a usage request for each API you intend to call and wait for a second admin approval. This gate is separate from key approval.
STEP 04Build and go liveOnce approved, you can call that API.

The first call is one line of curl

Once approved, calling is plain. Append the service name to the base URL, put the key in a header named AUTH_KEY, and pass one date as basDd. There is no token exchange and no request signing.

The payload sits in an OutBlock_1 array. The index service returns several indices for that date at once, so filter for the row where IDX_NM is the KOSPI. Price fields arrive as strings with thousands separators, so strip the commas before converting.

terminal
curl -H "AUTH_KEY: $KRX_API_KEY" \
  "https://data-dbg.krx.co.kr/svc/apis/idx/kospi_dd_trd?basDd=20260804"
response (excerpt)
{
  "OutBlock_1": [
    {
      "BAS_DD": "20260804",
      "IDX_NM": "코스피",
      "OPNPRC_IDX": "6,351.38",
      "HGPRC_IDX": "6,389.40",
      "LWPRC_IDX": "6,080.25",
      "CLSPRC_IDX": "6,358.95"
    }
  ]
}

Be your own quant — 30 lines of Python

Quant work sounds grand, but it starts with pulling prices and computing your own statistics. Implementing a definition by hand, instead of reading someone else's indicator, is what tells you exactly what a number counts.

Below is a complete script using only the standard library. Nothing to install; put your key in the KRX_API_KEY environment variable and it runs. It walks a date range one day at a time, picks out the KOSPI row, and reports mean, median and the count of extreme days.

Two lines carry the weight: the one that never calls on weekends, and the one that skips rows with an empty price. The second line is the trading-day test. The exchange returns rows on holidays too, with prices left blank, so judging by whether rows came back gets it wrong.

Running it over 24 July to 4 August gives this.

Widen the window by changing the dates. Note that KRX returns one day per request, so 100 trading days means 100 calls. If you will hit the same dates repeatedly, cache the responses to disk. Settled history never changes, so that cache can be permanent. The one exception is today's date: during the session it returns nothing, and freezing that empty answer would mark the day a permanent holiday.

kospi_range.py
import os, json, statistics as st, urllib.request, datetime

KEY = os.environ["KRX_API_KEY"]
BASE = "https://data-dbg.krx.co.kr/svc/apis/idx/kospi_dd_trd"

def day(basDd):
    req = urllib.request.Request(f"{BASE}?basDd={basDd}", headers={"AUTH_KEY": KEY})
    rows = json.loads(urllib.request.urlopen(req, timeout=30).read())["OutBlock_1"]
    for r in rows:
        if r["IDX_NM"].strip() == "코스피" and r["CLSPRC_IDX"].strip():
            f = lambda k: float(r[k].replace(",", ""))
            return f("HGPRC_IDX"), f("LWPRC_IDX"), f("CLSPRC_IDX")
    return None                       # 휴장일 — 행은 오되 가격 필드가 비어 있다

d, end, series = datetime.date(2026, 7, 24), datetime.date(2026, 8, 4), []
while d <= end:
    if d.weekday() < 5:               # 주말은 애초에 호출하지 않는다
        v = day(d.strftime("%Y%m%d"))
        if v:
            series.append(v)
    d += datetime.timedelta(days=1)

chg = [abs(series[i][2] / series[i-1][2] - 1) * 100 for i in range(1, len(series))]
rng = [(series[i][0] - series[i][1]) / series[i-1][2] * 100 for i in range(1, len(series))]
print(f"거래일 {len(chg)}일")
print(f"등락률 평균 {st.mean(chg):.2f}% · 중앙 {st.median(chg):.2f}%")
print(f"고저폭 평균 {st.mean(rng):.2f}% · 중앙 {st.median(rng):.2f}%")
print(f"±2% 넘은 날 {sum(1 for c in chg if c >= 2)}일")
output
거래일 7일
등락률 평균 6.24% · 중앙 5.12%
고저폭 평균 8.42% · 중앙 6.23%
±2% 넘은 날 4일

Measured — before and after the single-stock leveraged ETF listing

With the same method over a wider window, here is one real question. On 27 May 2026, leveraged and double-inverse ETFs on Samsung Electronics and SK hynix listed together. Did KOSPI daily swings change around that date?

The table compares the 48 trading days before (17 March to 26 May) with the 48 after (27 May to 4 August). Median sits next to mean deliberately, to rule out a single outlier such as the 17.91% move on 31 July carrying the average. The median rose too, so the conclusion survives deleting that day.

Metric48 days before48 days afterRatio
Mean absolute daily change2.56%4.08%1.59x
Median absolute daily change2.11%3.62%1.71x
Mean intraday range2.99%5.81%1.94x
Median intraday range2.38%5.13%2.16x
Days moving beyond 2%25 of 4832 of 481.28x

Four traps you will hit on the first day

First, approval has two gates. Call right after the key approval mail and you get a 401. The message tells you which gate failed: Unauthorized Key means the key itself is invalid, Unauthorized API Call means the key is live but you never filed a usage request for that service. Send a junk string as the key against the same URL and watch the message change; that settles it immediately.

Second, the access axis is reversed. Yahoo takes a symbol and a period and returns a series. KRX takes one date and returns every instrument for that date. A 150-day series for one symbol costs 150 calls. In exchange, each fetched date covers every instrument, so caching by date means adding symbols costs nothing.

Third, holidays still return rows. Ask for a Saturday and 1,155 rows come back with every price field blank. Counting rows to detect trading days is wrong; check whether a price is present. Turned around, that check is the most accurate definition of a trading calendar you can get.

Fourth, closes are not retroactively adjusted. KRX gives the price actually traded that day. Yahoo's close is split-adjusted backwards, the exact opposite. Mixing both sources while applying one split adjustment across the board double-adjusts and corrupts historical quantities. Split the adjustment logic by source.

Finally, know the boundary. This API serves settled T+1 data only, with no live price, order book or ticks. Request today's date and you get zero rows even while the market is open. Use a broker API for real time and a different source for US equities and FX.

How far the numbers let you speak

Measuring it yourself creates one temptation. Swings grew 1.6 to 1.9 times after the listing, so it is tempting to blame the ETFs. The same data does not support that.

Break it down by month and volatility was already climbing before the listing: 1.15% in January, 2.49% in February, 3.64% in March, 2.06% in April, 2.91% in May, 3.57% in June, 4.89% in July. The listing date is not the inflection point. The post-listing window also swallows a July in which the index fell 22%, and the most extreme days cluster two months after the listing.

The Korea Capital Market Institute did not claim causation either. Over the same period SK hynix volatility went from 90% to 101% while Micron went from 85% to 126% and the Philadelphia Semiconductor Index from 46% to 75% — larger moves abroad — and it attributes the change to several overlapping factors including rebalancing flows and macro uncertainty.

So this is where the article stops. KOSPI daily swings widened around the listing. The measured variables are daily change and intraday range, and that they grew is what the data guarantees. Why they grew is not settled by this table.

That is the value of measuring it yourself. Read someone's conclusion and you cannot see how far its evidence reaches. Measure it and you know exactly what your number counted, which is what lets you stop at the edge of it.