Daepak

Kimchi Premium TradingView Indicator

Instead of plotting the kimchi premium as a single number, it splits it into a won leg and an asset leg. The full Pine Script code is provided below — just copy and paste, no account or payment required.

Why a single number is not enough

The kimchi premium calculated from the exchange rate mixes two components with different characteristics. They often move in opposite directions.

CompositionWhat it measuresFeature
Won legHow much more expensive or cheaper domestic USDT is compared to the market exchange rate A currency-side value that applies identically to all coins
Asset legThe value remaining in the coin itself after removing the currency effect Actual domestic demand shows up here

If the total premium is negative but the asset leg is close to zero, the coin is not being sold cheaply domestically — the value comes from the KRW conversion side. Looking only at the total number would lead you to read this situation exactly backwards. The indicator highlights in red the intervals where the two legs point in different directions, so you can spot them immediately.

Calculation

Total premium = (Domestic price ÷ USD/KRW) ÷ Overseas price − 1
Won leg       = Domestic USDT ÷ USD/KRW − 1
Asset leg     = (1 + Total) ÷ (1 + Won leg) − 1
The asset leg is derived by calculation. It is not measured directly from a coin's USDT pair. In our measurement on July 30, 2026, the exchange rate back-calculated from two Upbit order books matched BTC at 1424 (market 1423), but diverged for SOL at 1449 and DOGE at 1451. Altcoin USDT pairs are thin and quotes tend to linger, so a directly measured asset leg was noise, not measurement. The derived value always reconciles back with the observed total premium.

Installation (2 min)

  1. Open a TradingView chart and expand the Pine Editor at the bottom.
  2. Copy the entire code below and overwrite the editor contents.
  3. Click Add to chart. The default is BTC-based (Upbit · Binance · USD/KRW · Upbit USDT).
  4. To view another coin, change all four Symbols fields in the settings to the same coin.

Full Pine Script code

// Kimchi Premium — won leg vs asset leg
// by Daepak · https://daepak.com/kimchi · MIT
//
// The kimchi premium is usually published as one number: how much more expensive a coin is
// on a Korean exchange than abroad, converted at the FX rate. That single number mixes two
// different things, and they often move in opposite directions:
//
//   won leg    — how far Korean USDT trades from the market USD/KRW rate. It is a currency
//                effect and applies to every coin equally.
//   asset leg  — what is left for the coin itself once the currency effect is removed.
//
// If the total premium is negative but the asset leg is near zero, the coin is not cheap in
// Korea — the won conversion is. Reading the total alone gets that backwards.
//
// The asset leg is DERIVED as (1 + total) / (1 + won) − 1, not measured from the coin's own
// USDT pair on Upbit. We tested the direct measurement on 2026-07-30: the implied rate from
// two Upbit order books matched for BTC (1424 vs 1423 market) but drifted to 1449 for SOL
// and 1451 for DOGE, because altcoin USDT pairs are thin and go stale. The derived leg always
// adds back up to the observed total; the direct one was noise.
//
// Honest limit: in our own backtest of 646 episodes, neither leg predicted price direction
// over horizons up to 24 hours. The decomposition explains what is happening now. It does not
// forecast, and this script is not investment advice.

//@version=6
indicator("Kimchi Premium · won leg vs asset leg", "Kimchi legs", overlay = false, precision = 2)

// ───────────────── inputs ─────────────────
gS = "Symbols"
krSym   = input.symbol("UPBIT:BTCKRW",    "Korean market (KRW)",  group = gS,
     tooltip = "The coin on a Korean exchange, quoted in won. Change this to follow another coin.")
glSym   = input.symbol("BINANCE:BTCUSDT", "Global market (USD)",  group = gS,
     tooltip = "The same coin on a global exchange. Must be the same asset as the Korean symbol.")
fxSym   = input.symbol("FX_IDC:USDKRW",   "USD/KRW reference",    group = gS,
     tooltip = "The market exchange rate used to convert. This is the rate the premium is measured against.")
usdtSym = input.symbol("UPBIT:USDTKRW",   "Korean USDT (KRW)",    group = gS,
     tooltip = "USDT priced in won on a Korean exchange — the most liquid stablecoin market, used to measure the won leg.")

gV = "View"
showTotal = input.bool(true,  "Total premium (FX based)", group = gV)
showWon   = input.bool(true,  "Won leg",                  group = gV)
showAsset = input.bool(true,  "Asset leg",                group = gV)
showTable = input.bool(true,  "Value panel",              group = gV)

gA = "Alerts"
hiLevel = input.float(5.0,  "Alert above (asset leg, %)", group = gA, step = 0.5)
loLevel = input.float(-3.0, "Alert below (asset leg, %)", group = gA, step = 0.5)

// ───────────────── data ─────────────────
kr   = request.security(krSym,   timeframe.period, close)
gl   = request.security(glSym,   timeframe.period, close)
fx   = request.security(fxSym,   timeframe.period, close)
usdt = request.security(usdtSym, timeframe.period, close)

ok    = not na(kr) and not na(gl) and not na(fx) and gl > 0 and fx > 0
total = ok ? (kr / fx) / gl - 1.0 : na
won   = not na(usdt) and not na(fx) and fx > 0 ? usdt / fx - 1.0 : na
// derived, never taken from the coin's own USDT pair — see the header note
asset = not na(total) and not na(won) ? (1.0 + total) / (1.0 + won) - 1.0 : na

totalP = total * 100
wonP   = won   * 100
assetP = asset * 100

// ───────────────── plots ─────────────────
pT = plot(showTotal ? totalP : na, "Total premium", color = color.new(#7A5CFF, 0),  linewidth = 2)
pW = plot(showWon   ? wonP   : na, "Won leg",       color = color.new(#F79009, 0),  linewidth = 1)
pA = plot(showAsset ? assetP : na, "Asset leg",     color = color.new(#12B76A, 0),  linewidth = 2)
hline(0, "Parity", color = color.new(color.gray, 40), linestyle = hline.style_dashed)

// where the two legs disagree — the case the single number hides
fillCol = not na(wonP) and not na(assetP) and wonP * assetP < 0 ? color.new(#F04438, 88) : color.new(color.gray, 94)
fill(pW, pA, color = fillCol, title = "Gap between legs")

// ───────────────── panel ─────────────────
f_pct(float v) => na(v) ? "—" : (v > 0 ? "+" : "") + str.tostring(v, "#.##") + "%"

if showTable and barstate.islast
    var table t = table.new(position.top_right, 2, 5, border_width = 1)
    table.cell(t, 0, 0, "Kimchi premium",  text_color = color.white, bgcolor = #5B3DF5, text_size = size.small)
    table.cell(t, 1, 0, "now",             text_color = color.white, bgcolor = #5B3DF5, text_size = size.small)
    table.cell(t, 0, 1, "Total (FX based)", text_size = size.small)
    table.cell(t, 1, 1, f_pct(totalP), text_size = size.small,
     text_color = na(totalP) ? color.gray : totalP >= 0 ? #12B76A : #F04438)
    table.cell(t, 0, 2, "Won leg",     text_size = size.small)
    table.cell(t, 1, 2, f_pct(wonP),   text_size = size.small,
     text_color = na(wonP) ? color.gray : wonP >= 0 ? #12B76A : #F04438)
    table.cell(t, 0, 3, "Asset leg",   text_size = size.small)
    table.cell(t, 1, 3, f_pct(assetP), text_size = size.small,
     text_color = na(assetP) ? color.gray : assetP >= 0 ? #12B76A : #F04438)
    table.cell(t, 0, 4, na(assetP) ? "waiting for data" :
     math.abs(assetP) < 0.3 ? "currency effect, not the coin" :
     assetP > 0 ? "Korean demand for the coin" : "coin discounted in Korea",
     text_size = size.tiny, text_color = color.gray)
    table.cell(t, 1, 4, "daepak.com", text_size = size.tiny, text_color = color.gray)

// ───────────────── alerts ─────────────────
alertcondition(ta.crossover(assetP,  hiLevel), "Asset leg above level",
     "Kimchi asset leg crossed above the upper level")
alertcondition(ta.crossunder(assetP, loLevel), "Asset leg below level",
     "Kimchi asset leg crossed below the lower level")
alertcondition(ta.cross(wonP * assetP, 0),     "Legs diverged",
     "Kimchi legs now point in opposite directions — the single premium number is misleading here")

Honest limitations

In our validation across 646 segments, neither leg predicted price direction within 24 hours. Decomposition is a tool that explains what is happening now, not a tool that predicts what comes next. This script is not investment advice; judgment and responsibility rest with the user.

Live values and deeper analysis

The full market kimchi premium ranking, live values for the won leg and asset leg, and records from the first candle of new Upbit listings are available directly on the kimchi premium page. It opens without login. To call the same data via API and MCP, see the developer docs — you can also ask directly in ChatGPT or Claude (how to connect).