Workspace IndexMath › Day 43

Correlation and Cointegration (A Light Treatment) TODO

Math · Day 43 / 52 · November — Probability, Statistics & Financial Math (Day 35-43)

Concept

The correlation coefficient standardizes the degree of linear co-movement between two variables to a value between -1 and 1; it does not imply causation and fails to capture nonlinear relationships properly. In time series, when two series each have their own trend, correlation and regression coefficients can come out large even with no real relationship — the spurious regression problem — so correlation between levels shouldn't be trusted at face value. Cointegration describes a relationship where each series is individually non-stationary (has a unit root), but some linear combination of the two is stationary and mean-reverting — a statement that a long-run equilibrium exists between the two series. The standard procedure is to test each series for a unit root, estimate the cointegrating relationship, then test whether its residuals are stationary; if cointegration holds, an error-correction model can describe how fast short-term deviations revert to equilibrium. In short: correlation is a statement about simultaneous movement, and cointegration is a statement about a long-run relationship.

Pairs trading, hedge-ratio sizing, and analyzing peg deviations for stablecoins or LSTs are all really asking whether the levels of two series stay tied together over the long run — which is cointegration's territory, not correlation's.

Code & Formula

# 상관관계와 공적분(가볍게) — 수준(level) 상관의 함정 vs 스프레드의 평균회귀
# 두 계열이 각자 추세를 가지면 아무 관계가 없어도 수준끼리는 강하게 "상관"돼 보인다(허위회귀).

import random
import statistics

random.seed(3)
N = 500

def corr(xs, ys):
    mx, my = statistics.mean(xs), statistics.mean(ys)
    cov = sum((x - mx) * (y - my) for x, y in zip(xs, ys))
    sx = (sum((x - mx) ** 2 for x in xs)) ** 0.5
    sy = (sum((y - my) ** 2 for y in ys)) ** 0.5
    return cov / (sx * sy)

# 1) 서로 무관한 두 랜덤워크(각자 추세만 가짐) — 진짜 관계는 없다
a_level = [100.0]
b_level = [50.0]
for _ in range(N):
    a_level.append(a_level[-1] + random.gauss(0.15, 1.0))  # 독립적인 상승 추세(추세가 노이즈를 압도)
    b_level.append(b_level[-1] + random.gauss(0.10, 1.0))
a_ret = [a_level[i] - a_level[i - 1] for i in range(1, len(a_level))]
b_ret = [b_level[i] - b_level[i - 1] for i in range(1, len(b_level))]

print(f"[무관한 두 랜덤워크] 수준(level) 상관 = {corr(a_level, b_level):.3f}  (허위로 높게 나옴)")
print(f"[무관한 두 랜덤워크] 수익률(return) 상관 = {corr(a_ret, b_ret):.3f}  (실제로는 0에 가까움)")

# 2) 공적분 관계: 두 계열은 각자 비정상(추세)이지만 스프레드는 평균회귀하도록 구성
x_level = [100.0]
for _ in range(N):
    x_level.append(x_level[-1] + random.gauss(0.0, 1.0))

spread = [0.0]
for _ in range(N):
    # 스프레드가 커질수록 되돌아오는 힘(AR(1), 계수<1 => 평균회귀) + 노이즈
    spread.append(spread[-1] * 0.8 + random.gauss(0.0, 0.5))

y_level = [x_level[i] - spread[i] for i in range(N + 1)]

print(f"\n[공적분 쌍] 수준 상관 = {corr(x_level, y_level):.3f}")
print(f"[공적분 쌍] 스프레드 평균/표준편차 = {statistics.mean(spread):.3f} / {statistics.stdev(spread):.3f}")
print(f"[공적분 쌍] 스프레드가 [-3, 3] 범위 안에 머문 비율 = {sum(-3 <= s <= 3 for s in spread) / len(spread):.2%}")
print("-> 스프레드가 특정 범위를 벗어나지 않고 되돌아온다면 두 계열이 장기적으로 묶여있다는 신호(공적분).")

Exercise

Take price time series for two assets, compute the correlation of log-price levels and the correlation of log returns separately, compare how different the values are, and plot whether the spread between the two series mean-reverts.

Practical Connection

Prices of different markets covering the same event, or of complementary outcome tokens, should stay tied together in the long run — so if the spread does not mean-revert, that's grounds to suspect a liquidity shortfall or a difference in settlement terms.

Where it lands in Jayverse

Key expressions

Words and phrases from this page worth keeping, with the Korean meaning and the sentence they come from.

Expression뜻 · 쓰이는 자리
co-movement동반 움직임·같이 변동함 · 두 변수가 같은 방향으로 함께 움직이는 정도. "the degree of linear co-movement between two variables"
spurious regression가짜 회귀·허위 회귀 관계 · 실제 관련 없는 두 추세가 통계상 관계 있어 보이는 함정. "the spurious regression problem"
mean-reverting평균으로 회귀하는 · 값이 벌어져도 결국 평균 수준으로 돌아오는 성질. "stationary and mean-reverting"
tied together서로 묶여 있다·연동되어 있다 · 두 시계열이 장기적으로 같이 움직인다고 말할 때. "stay tied together over the long run"
at face value액면 그대로·곧이곧대로 · 겉으로 드러난 숫자를 검증 없이 믿지 말라고 할 때. "correlation between levels shouldn't be trusted at face value"
long-run equilibrium장기 균형 · 단기적으로 벗어나도 결국 되돌아오는 안정 상태를 가리킬 때. "a long-run equilibrium exists between the two series"
grounds to suspect~을 의심할 근거 · 어떤 이상 신호가 특정 문제를 의심하게 만들 때. "that's grounds to suspect a liquidity shortfall"
LSTs유동성 스테이킹 토큰(Liquid Staking Tokens) · 스테이블코인처럼 페그 유지 여부를 확인해야 하는 자산의 예시. "peg deviations for stablecoins or LSTs"
unit root단위근 · 시계열이 평균으로 돌아오지 않고 추세를 따라 계속 벗어나는(비정상) 상태를 판정하는 통계 개념. "each series is individually non-stationary (has a unit root)"

If you study this on a given day, add a note link and a ✅ to this line in the source curriculum (docs/knowledge/math-50-curriculum.md) and this spot will lead straight to the note body. You can also write directly on this page — but regenerating overwrites it, so it's safer to keep anything you want to save as markdown under docs/algorithms/.


한국어

상관관계와 공적분(가볍게) TODO

Math · Day 43 / 52 · 11월 — 확률·통계·금융수학 (Day 35–43)

개념

상관계수는 두 변수의 선형 동조 정도를 -1과 1 사이로 표준화한 값이며, 인과를 뜻하지 않고 비선형 관계도 제대로 잡지 못한다. 시계열에서는 두 계열이 각각 추세를 가질 경우 실제 관계가 없어도 상관과 회귀 계수가 크게 나오는 허위 회귀 문제가 생기므로, 수준(level)끼리의 상관은 그대로 믿기 어렵다. 공적분은 각 계열은 비정상(단위근을 가짐)이지만 둘의 어떤 선형결합은 정상이 되어 평균으로 회귀하는 관계를 말하며, 이는 두 계열 사이에 장기 균형이 존재한다는 진술이다. 실무 절차는 각 계열의 단위근을 검정하고, 공적분 관계를 추정한 뒤 그 잔차가 정상인지 검정하는 순서이며, 공적분이 성립하면 오차수정모형으로 단기 이탈이 균형으로 되돌아가는 속도를 모델링한다. 요약하면 상관은 동시적 움직임에 대한 진술이고 공적분은 장기 관계에 대한 진술이다.

페어 트레이딩, 헤지 비율 산정, 스테이블코인이나 LST의 페그 이탈 분석은 모두 두 계열의 수준이 장기적으로 붙어 있는지를 묻는 질문이라 상관이 아니라 공적분의 영역이다.

코드 · 수식

# 상관관계와 공적분(가볍게) — 수준(level) 상관의 함정 vs 스프레드의 평균회귀
# 두 계열이 각자 추세를 가지면 아무 관계가 없어도 수준끼리는 강하게 "상관"돼 보인다(허위회귀).

import random
import statistics

random.seed(3)
N = 500

def corr(xs, ys):
    mx, my = statistics.mean(xs), statistics.mean(ys)
    cov = sum((x - mx) * (y - my) for x, y in zip(xs, ys))
    sx = (sum((x - mx) ** 2 for x in xs)) ** 0.5
    sy = (sum((y - my) ** 2 for y in ys)) ** 0.5
    return cov / (sx * sy)

# 1) 서로 무관한 두 랜덤워크(각자 추세만 가짐) — 진짜 관계는 없다
a_level = [100.0]
b_level = [50.0]
for _ in range(N):
    a_level.append(a_level[-1] + random.gauss(0.15, 1.0))  # 독립적인 상승 추세(추세가 노이즈를 압도)
    b_level.append(b_level[-1] + random.gauss(0.10, 1.0))
a_ret = [a_level[i] - a_level[i - 1] for i in range(1, len(a_level))]
b_ret = [b_level[i] - b_level[i - 1] for i in range(1, len(b_level))]

print(f"[무관한 두 랜덤워크] 수준(level) 상관 = {corr(a_level, b_level):.3f}  (허위로 높게 나옴)")
print(f"[무관한 두 랜덤워크] 수익률(return) 상관 = {corr(a_ret, b_ret):.3f}  (실제로는 0에 가까움)")

# 2) 공적분 관계: 두 계열은 각자 비정상(추세)이지만 스프레드는 평균회귀하도록 구성
x_level = [100.0]
for _ in range(N):
    x_level.append(x_level[-1] + random.gauss(0.0, 1.0))

spread = [0.0]
for _ in range(N):
    # 스프레드가 커질수록 되돌아오는 힘(AR(1), 계수<1 => 평균회귀) + 노이즈
    spread.append(spread[-1] * 0.8 + random.gauss(0.0, 0.5))

y_level = [x_level[i] - spread[i] for i in range(N + 1)]

print(f"\n[공적분 쌍] 수준 상관 = {corr(x_level, y_level):.3f}")
print(f"[공적분 쌍] 스프레드 평균/표준편차 = {statistics.mean(spread):.3f} / {statistics.stdev(spread):.3f}")
print(f"[공적분 쌍] 스프레드가 [-3, 3] 범위 안에 머문 비율 = {sum(-3 <= s <= 3 for s in spread) / len(spread):.2%}")
print("-> 스프레드가 특정 범위를 벗어나지 않고 되돌아온다면 두 계열이 장기적으로 묶여있다는 신호(공적분).")

연습

두 자산의 가격 시계열을 받아 로그 가격 수준의 상관과 로그 수익률의 상관을 각각 계산해 값이 얼마나 다른지 비교하고, 두 계열의 스프레드가 평균으로 회귀하는지 그려 확인하라.

실무 · Verex 연결

같은 사건을 다루는 서로 다른 마켓이나 상보적 아웃컴 토큰의 가격은 장기적으로 묶여 있어야 하므로, 스프레드가 평균 회귀하지 않는다면 유동성 부족이나 정산 조건 차이를 의심할 근거가 된다.

Jayverse에서의 위치

핵심 표현

이 페이지의 영어 본문에서 배울 만한 단어와 표현, 뜻과 나온 자리.

Expression뜻 · 쓰이는 자리
co-movement동반 움직임·같이 변동함 · 두 변수가 같은 방향으로 함께 움직이는 정도. "the degree of linear co-movement between two variables"
spurious regression가짜 회귀·허위 회귀 관계 · 실제 관련 없는 두 추세가 통계상 관계 있어 보이는 함정. "the spurious regression problem"
mean-reverting평균으로 회귀하는 · 값이 벌어져도 결국 평균 수준으로 돌아오는 성질. "stationary and mean-reverting"
tied together서로 묶여 있다·연동되어 있다 · 두 시계열이 장기적으로 같이 움직인다고 말할 때. "stay tied together over the long run"
at face value액면 그대로·곧이곧대로 · 겉으로 드러난 숫자를 검증 없이 믿지 말라고 할 때. "correlation between levels shouldn't be trusted at face value"
long-run equilibrium장기 균형 · 단기적으로 벗어나도 결국 되돌아오는 안정 상태를 가리킬 때. "a long-run equilibrium exists between the two series"
grounds to suspect~을 의심할 근거 · 어떤 이상 신호가 특정 문제를 의심하게 만들 때. "that's grounds to suspect a liquidity shortfall"
LSTs유동성 스테이킹 토큰(Liquid Staking Tokens) · 스테이블코인처럼 페그 유지 여부를 확인해야 하는 자산의 예시. "peg deviations for stablecoins or LSTs"
unit root단위근 · 시계열이 평균으로 돌아오지 않고 추세를 따라 계속 벗어나는(비정상) 상태를 판정하는 통계 개념. "each series is individually non-stationary (has a unit root)"

공부한 날 원본 커리큘럼(docs/knowledge/math-50-curriculum.md)의 이 줄에 노트 링크와 ✅ 를 붙이면, 이 자리는 노트 본문으로 바로 이어집니다. 노트 없이 이 페이지에 바로 적어도 됩니다 — 다만 다시 생성하면 덮어쓰이므로, 남길 글은 docs/algorithms/ 의 마크다운으로 쓰는 편이 안전합니다.

← 1046. 마르코프 체인(개념)1048. 정수론·모듈러 산술 →