- Outlier에 따른 롱-숏 쏠림 현상
- how?
- 3ways (신호를 만든 뒤에 적용하는 통계적 변환과정)
(1) raw signal 생성 → (2) 분포 안정화/정규화(rank, zscore 등) → (3) 중립화(neutralization) → (4) 포지션 생성
- 순위 매기는 방법 (ordering method) -> 비모수적
예컨대, 데이터의 극단적인 이상치(Outlier)가 들어있는 데이터셋의 경우, 정규분포 가정을 충족한다고 말하기 어렵습니다. 따라서 이 경우에는 순위 매기는 방법으로 이상치를 처리해 줄 수 있습니다
- rank
-returns와 rank(-returns)위의 첫번째 알파로는, 수익률(returns)이 매우 큰 특정 주식들에 포트폴리오의 가중치(weight)가 과도하게 몰릴 수 있습니다. 그래서 그 특정 주식들이 알파 퍼포먼스에 과도한 영향력을 미치게 됩니다. 이걸 막기 위해 ‘rank’라는 오퍼레이터(연산자)를 씌워서 “수익률”을 가중치로 사용하지 않고 “수익률의 순위”에 따라 투자하겠다 라고 아이디어를 수정한 것이 두번째 알파입니다. Rank()는 각각의 개별 주식 종목들 가운데 순위를 매겨 0부터 1사이의 값으로 유니폼하게 분포된 값을 출력해 줍니다. 결과를 보시면 rank() 오퍼레이터를 사용함으로써 이상치를 처리해 주었고, 이에 따라 알파 퍼포먼스가 꽤 개선되었음을 확인 할 수 있습니다.
- quantile
X가 전체에서 몇 % 위치냐”라는 퍼센타일이라서, 샘플을 많이 뽑으면 10퍼센타일 근처 값도 20퍼센타일 근처 값도 90퍼센타일 근처 값도 똑같은 빈도로 나오게(각 10%씩) 설계되어 있는 거고, 그래서 원래 X의 PDF가 어디에 몰려있든 그 몰림은 F가 x축을 눌러/늘려서 0~1 구간에 “퍼센타일 좌표”로 재배치해버리기 때문에 U가 고르게 퍼진다는 게 포인트야.“원래 데이터의 순서 정보를 퍼센타일로 바꾼 뒤, 그 퍼센타일을 이용해 원하는 분포 좌표로 다시 배치한다”**는 의미이고, 목적은 원래 데이터의 이상치나 비정규 분포 문제를 제거하면서 순서 정보만 보존하는 것이다.최종적으로 사용하는 것은 **그 분포에서 대응된 “숫자값 자체”**이고, 그 값이 바로 **알파 신호(signal) 혹은 포지션 강도(weight)**로 쓰인다; 예를 들어 quantile(x, normal)을 하면 각 종목은 퍼센타일을 통해 **정규분포의 x축 값(z-score)**로 매핑되는데, 어떤 종목이 상위 95%라면 약 +1.64, 하위 5%라면 −1.64 같은 값이 나오고 이 숫자가 그대로 롱/숏 방향과 포지션 크기를 결정한다. 즉 결과 벡터가 [-1.8, -0.7, 0.1, 0.9, 1.5 ...] 같은 값들이 되는데 양수는 롱, 음수는 숏, 절댓값이 클수록 포지션을 더 크게 잡는 신호가 되는 것이다; 그래서 quantile의 목적은 순위 정보를 유지하면서 이상치 때문에 특정 종목에 과도한 weight가 몰리는 것을 막고, 안정적인 스케일의 신호 값을 만들어 포트폴리오 배분에 쓰기 위함이다.**`quantile(x, normal)`에서 사용하는 정규분포는 항상 표준정규분포 (N(0,1))**이고 데이터에 맞게 평균이나 표준편차를 다시 추정해서 바꾸는 것이 아니다; 과정은 단순히 **rank(x)로 퍼센타일 (u\in(0,1))을 만든 뒤 표준정규의 역 CDF (Φ^{-1}(u))**를 계산하는 것이며 예를 들어 퍼센타일이 **0.9면 약 1.28, 0.5면 0, 0.1이면 −1.28**처럼 미리 정해진 값으로 매핑되고 이 숫자가 그대로 알파 신호로 쓰인다. 그래서 quantile(normal)은 **데이터의 평균·분산을 이용하는 것이 아니라 순위 정보만 유지하면서 값을 표준정규 스케일로 재배치하는 변환**이라고 보면 된다.
- 정규분포에 근사하는 방법 (approximation to normal distribution)
- zscore
평균이 0이고 표준편차가 1이라고 해서 분포가 동일해지는 것은 전혀 아니다; 이것은 단지 위치(location)와 스케일(scale)만 맞춘 것일 뿐이고 분포의 모양(shape)—예를 들어 왜도(skewness), 첨도(kurtosis), 꼬리 두께(heavy tail) 같은 특성은 그대로 남는다.
- 피셔 변환공식
**피셔 변환(Fisher transform)**은 값이 **−1과 1 사이에 제한된 변수(특히 상관계수)**를 **로그 기반 비선형 변환으로 펼쳐서 분포를 더 대칭적이고 정규분포에 가깝게 만드는 변환**이다; 공식은 (y=\tfrac12\ln\frac{1+x}{1-x}=\operatorname{atanh}(x))이고, 예를 들어 상관계수 (x)는 −1과 1에 가까워질수록 값이 압축되어 분포가 비대칭이 되지만 이 변환을 하면 **중앙 근처 값은 크게 변하지 않고 ±1 근처 값은 크게 늘어나면서** 분포가 더 대칭적으로 변한다. 그래서 통계적으로는 **상관계수의 분산이 위치에 따라 달라지는 문제를 완화하고 정규근사를 가능하게 만들어 추정이나 검정이 쉬워지게 하는 역할**을 하며, 퀀트 데이터에서는 **correlation 기반 신호나 −1~1 범위 지표를 더 안정적인 스케일로 변환하기 위해** 사용된다.
- 제한하는 방법 (limiting method)
- trimming
- 특정 임계치보다 높거나 낮은 데이터의 특정 부분을 제거하는 방법으로, if_else를 통해서 구현 가능
- winsorizing
트리밍과 달리, 극단값을 버리는 것이 아니라 다른 컷오프값으로 대체합니다. winsorize(x, std=4) 연산자를 통해, 데이터의 특정 표준편차를 넘는 극단값에 대하여 처리할 수 있습니다. 예를 들어, [3, 5, 7, 10, 100]라는 데이터가 있다고 해봅시다. b와 c의 경우 산술 평균인 a보다 이상치에 대해 훨씬 안정적이라고 할 수 있습니다.
-> 현재 상태에서는 +- 4 표준편차
산술 평균: (3+5+7+10+100)/5 = 25
20% 트리밍 평균: (5+7+10)/3 = 7.33
20% 윈저라이징 평균: (5+5+7+10+10)/5 = 7.4
- 특정 시점에 과적합되지 않아야함
- Out of Sample Score
Out of Sample Score는 현재 BRAIN에서 Fast Expression Code를 시뮬레이션했을 때엔 알 수 없는 Semi-OS 기간에 대하여 In Sample Score와 동일하게 평가됩니다. OS의 경우에도 IS와 마찬가지로 같은 계산식에 의해 Merged Alpha의 1. Sharpe 2. Returns/Drawdown ratio, 3. Turnover에 따라 점수가 매겨집니다. (OS D1 Score + OS D0 Score/3)
말의 핵심은 **알파가 진짜인지 과적합인지 제출 시점에는 알 수 없도록 BRAIN이 시스템을 설계해 놓았다는 것**인데, 알파를 만들 때 우리는 과거 데이터 중 **최근 5년(컨설턴트는 10년)을 In-Sample(IS)**로 보고 그 구간에 맞게 알파를 만들고 테스트하지만, 플랫폼은 우리가 보지 못한 **그 이후 구간을 Semi-OS와 Real-OS로 따로 가지고 있다가 알파를 제출한 뒤 시간이 지나면서 그 구간에서의 실제 성과를 확인**하게 만들기 때문에, IS에서는 좋아 보이던 알파가 OS에서 성과가 무너지면 나중에야 “아 이게 과적합이었구나”라는 것이 드러나게 된다; 그래서 알파를 제출할 때는 **과거 데이터에만 맞춘 복잡한 전략이 아니라 앞으로도 작동할 가능성이 높은 구조적인 알파를 만들어야 하고**, IQC Stage 2에서 최종 점수의 **50%를 OS 성과로 평가하는 이유도 IS에서만 잘 맞춘 과적합 알파를 걸러내기 위해서**라는 뜻이다.
-show test는 사실 완전한 OS가 아니라 IS 안에서 일부 기간을 따로 떼어 “가짜 테스트 구간”처럼 보여주는 기능이라서 목적은 진짜 OS 평가가 아니라 IS 데이터에 과하게 맞춰지는 것을 조금이라도 방지하기 위한 내부 검증 장치에 가깝다; BRAIN에서는 기본적으로 5년 IS 전체를 사용해 백테스트를 하지만 그중 1~2년 정도를 test로 분리해서 train(나머지 3~4년)에서 만든 알파가 그 test 구간에서도 성과가 유지되는지 확인하게 해 주는 것이고, 다만 이 test 구간도 결국 같은 IS 데이터 안에 있는 것이기 때문에 계속 showtest를 보면서 알파를 수정하면 결국 그 구간에도 다시 fitting이 일어나므로 완전한 과적합 방지 장치는 아니며, 진짜 과적합 여부는 플랫폼이 숨겨 둔 Semi-OS와 이후 Real-OS에서만 최종적으로 드러난다.
- how to avoid overfitting
- a) 테스트 기간 활용
- 테스트 기간을 클릭하여 성과를 확인한 후, 다시 시뮬레이션을 돌려 모델을 다시 적합(Fitting)하기 시작하면 테스트 데이터에도 Fitting이 발생하게 됩니다. 이로 인해 테스트 기간의 독립성이 훼손되고, 원래 테스트 기간의 의미가 희석될 수 있습니다. 따라서 테스트 데이터는 검증용으로만 사용하는 것을 권장합니다.(1번만 확인)
- b) in-sample 샤프 비율 기준 증가
여기서 말하는 **“In-Sample 샤프 비율 기준 증가”**는 알파를 만들 때 단순히 PnL이 우상향하는지만 보는 것이 아니라 **IS 구간에서 일정 수준 이상의 Sharpe ratio를 만족하는 알파만 선택하거나 그 값을 최대화하도록 설계하라**는 뜻인데, 즉 수익률만 보고 알파를 고르면 변동성이 크거나 운으로 맞은 전략이 섞일 수 있으므로 **Sharpe = 평균 수익 / 변동성**을 기준으로 필터를 더 엄격하게 두면 노이즈 전략이 걸러지고 **위험 대비 수익이 안정적인 알파만 남게 되어 OS에서도 성과가 유지될 확률이 높아진다**는 의미다.
- c) 더 긴 히스토리 데이터로 모델 테스트
(컨설턴트로 전환 시) 유저에서 컨설턴트로 전환되면, 플랫폼은 5년에서 10년으로 확장된 데이터 히스토리를 사용하여 모델의 성능을 평가할 수 있습니다.
- d) 다양한 지역에서 알파를 교차 검증 (cross region validation test)
(컨설턴트 전환 시) USA 알파를 GLB, ASI, EUR, HKG, TWN, KOR 지역에서 시뮬레이션하여 검증할 수 있습니
- e) 모델의 우아함 (make the model elegant)
- Simple: 모델을 단순화하여 이해하기 쉽고 유지 관리가 용이하도록 합니다.
- Economic Rationale: 알파 아이디어/가설이 어떤 설명을 할 수 있는지 생각해 보세요. 무작위(random)로 데이터로 시뮬레이션을 실행하여 IS에서만 우상향하는 PnL차트를 만드는 일은 자제하는 것이 좋습니다.이후에는 알파 아이디어의 구현을 단순화하고 불필요한 요소(Noise, 즉 의미가 없거나 성능이 저하되는 부분)를 제거합니다.
- Unit/Scale Handling: 일관성 있는 단위/범위 관리로 데이터를 정확히 처리합니다. (추후 설명)
- f) 파라미터 및 연산자의 개수 최소화
Minimize parameters and operations to enhance efficiency and simplicity in model design.
이 말이 과적합과 연결되는 이유는 **파라미터와 연산자가 많아질수록 모델 복잡도(model complexity)가 커지고, 복잡한 모델은 데이터의 “패턴”뿐 아니라 “노이즈까지 설명해버릴 가능성”이 높아지기 때문**인데, 예를 들어 알파를 만들 때 ts_rank, decay, 여러 lookback window, 조건문, 그룹연산 등을 계속 붙이면 결국 **특정 5년 IS 데이터의 미세한 움직임까지 맞춰버리는 구조**가 되어 IS에서는 Sharpe가 높게 나오지만 보지 못한 Semi-OS나 Real-OS에서는 그 패턴이 재현되지 않아 성과가 무너질 확률이 커진다; 반대로 **데이터필드와 연산자를 최소화한 단순한 알파**는 특정 데이터에 맞춰 미세조정할 자유도가 적기 때문에 노이즈에 덜 맞춰지고, 결과적으로 **IS와 OS 사이의 성과 괴리가 줄어들어 과적합 가능성이 낮아진다**는 논리다.Power Pool Alpha는 WorldQuant BRAIN에서 “단순한 구조의 알파를 많이 모아(pool) 운용하는 방식”을 전제로 만든 알파 유형으로, 일반 알파처럼 복잡한 수식을 만드는 것이 아니라 데이터필드 3개 이하, 연산자 8개 이하 같은 강한 단순성 제약을 두고 작은 신호 알파를 만드는 것이 특징이며 이렇게 만든 여러 개의 단순 알파들을 모아서 포트폴리오처럼 운용하면 각각의 신호는 약해도 상관관계가 낮은 알파들이 합쳐져 안정적인 성과를 만들 수 있다는 아이디어에서 나온 개념이다.
Robustness와 coverage
- 알파모델의 가정이 깨지는 상황이 발생할 수 있음.평온한 상승장에서는 잘 작동하지만 금융위기·코로나 급락 같은 극단적 변동성 구간에서 Sharpe가 붕괴하거나 drawdown이 폭발하면 regime-robust하지 않은 것이고, 반대로 상승장·하락장·고변동성·저변동성 등 서로 다른 시장 레짐에서도 수익구조와 risk metric이 크게 깨지지 않으면 이는 시간적 또는 레짐 강건성을 갖는 알파라고 한다.
- 정의
알파 신호(signal)는 유니버스의 모든 종목에 대해 계산되지만 실제 포지션은 그중 일부만 잡히는 경우가 많다는 뜻이다; 이유는 많은 종목에서 신호가 0에 가깝거나, if_else, tradewhen, rank, hump 같은 연산 때문에 값이 0 또는 매우 작게 만들어지거나, 중립화·정규화 과정에서 사실상 투자되지 않는 종목이 생기기 때문인데 이렇게 실제로 롱/숏 포지션이 들어가는 종목 수를 coverage 또는 long/short count라고 부른다; 그래서 “포지션 잡는 종목 수를 늘린다”는 말은 신호가 0이 되는 종목을 줄이거나(예: 조건 완화), cross-section 변환(rank, scale 등)을 써서 더 많은 종목에 의미 있는 값이 나오게 만들어 실제 롱/숏이 걸리는 종목을 늘린다는 의미다.
- 방식
- truncation
예를 들어 총 자본이 100이고 truncation=0.1이라면 원래 의도는 한 종목당 최대 10%까지만 투자하는 것이다; 그런데 어떤 알파가 실제로 포지션을 잡는 종목이 A,B,C,D,E 5개뿐이라고 하자(나머지는 신호가 0이라 포지션 없음), 그러면 이 5개 종목에 롱/숏 포지션을 합쳐서 총 100% 자본을 배분해야 하는데, 만약 truncation을 엄격히 지켜서 각 종목을 10%로 제한하면 최대 투자 가능한 금액은 5 × 10% = 50%밖에 안 되어 나머지 50% 자본을 어디에도 투자할 수 없는 문제가 생긴다; 그래서 시스템은 현실적으로 포트폴리오가 100% 투자되도록 상한을 완전히 강제하지 못하고 일부 종목 비중을 10% 이상으로 키우게 되며, 결국 5종목이면 평균적으로 약 20% 정도씩 배분되는 식으로 10%를 넘어가는 종목이 생길 수 있다는 의미이고, 그래서 문서에서 말하는 “포지션 잡는 종목 수를 늘려라(coverage 높여라)”는 말은 투자되는 종목이 10개 이상 정도는 되도록 만들어야 truncation=0.1이 실제로 제대로 작동한다는 뜻이다.요지는 truncation이 제대로 작동하려면 coverage(실제로 포지션 잡는 종목 수)가 충분히 많아야 한다는 한 문장으로 정리된다;맞다, 직관적으로 보면 낙수효과처럼 생각해도 거의 맞다; 먼저 알파 신호로 초기 비중이 계산되고 어떤 종목들이 truncation 상한(예: 10%)을 넘으면 그 종목들은 10%에서 더 이상 못 올라가게 “캡(cap)”이 씌워지는데, 이때 원래 그 종목에 들어가려던 초과 자본이 생기고 그 자본이 상한에 아직 안 걸린 다른 종목들로 비례적으로 흘러 들어가면서 전체 포트폴리오 합이 다시 100%가 되도록 재조정되는 구조라서, 종목이 충분히 많으면 큰 신호 종목은 10%에서 멈추고 남은 자본이 아래 종목들로 퍼지는 낙수 구조가 되고 truncation이 정상적으로 작동하지만, 반대로 종목 수가 너무 적으면 자본을 받아줄 종목이 부족해서 일부 종목이 10%를 넘게 되는 상황이 생길 수 있다.
- Statistical arbitrage(통계적 차익거래)
가격의 절대적 가치가 아니라 **통계적 관계(평균회귀, 상대적 mispricing, cross-section 패턴)**를 이용해 많은 종목을 동시에 롱/숏으로 운용하는 전략을 말하며 핵심은 개별 종목 예측이 아니라 많은 종목에서 작은 예측 우위를 반복적으로 모아 수익을 만드는 것이다; 그래서 페이지의 문장은 “알파가 더 많은 종목에서 포지션을 가지도록 coverage를 늘리면 여러 종목의 롱/숏 예측이 동시에 작동해 statistical arbitrage 구조가 잘 구현된다”는 의미이고, 반대로 coverage가 낮으면 몇 개 종목에 자본이 집중되어 특정 종목 성과에 의해 PnL이 좌우되는 단순 베팅이 되며 통계적 차익거래의 장점(분산·평균화·노이즈 상쇄)이 제대로 나타나지 않는다는 것을 말하고 있다.
- coverage가 낮다는 의미는 적은 양의 데이터 포인트로 백테스팅을 수행하였다는 의미이기 때문에 이에 overfitting의 위험에 대해서도 주의해야함
- data
낮은 커버리지의 원인은 보통 여러분이 활용한 데이터 필드의 자체 커버리지가 낮기 때문인데요, fundamental 및 analyst 데이터와 같이 업데이트 frequency가 낮은 데이터필드에서 나타나는 현상입니다. 따라서 이러한 경우에는 raw data를 그냥 알파에 활용하기 보다는 ts_backfill operator를 활용하여 데이터필드의 결측치를 채워주는 변환을 한 뒤에 알파에 활용해보시는 것 여기서 **데이터필드의 커버리지가 낮다**는 것은 “유니버스에 있는 많은 종목·날짜에서 그 데이터가 **값이 없고 NaN(결측치)** 상태로 존재한다”는 뜻인데, 예를 들어 price나 volume 같은 데이터는 **거래가 있는 거의 모든 종목에서 매일 값이 존재**하므로 커버리지가 거의 100%에 가깝지만, fundamental(재무제표)이나 analyst 데이터는 **분기·연 단위로만 업데이트되고 기업마다 발표 시점도 다르기 때문에** 어떤 날에는 A기업만 값이 있고 B,C,D는 값이 없거나 오래된 값만 존재하는 식의 **희소한(panel에 구멍이 많은) 데이터 구조**가 된다; 이런 상태에서 raw 데이터를 그대로 알파에 쓰면 값이 존재하는 종목만 신호가 계산되고 나머지는 NaN이라 실제 포지션 종목 수가 매우 줄어 **coverage가 낮아지게 되는데**, `ts_backfill`은 “최근 과거에 존재했던 값을 일정 기간 동안 앞으로 채워 넣어” 예를 들어 **분기 데이터가 발표되면 다음 분기 전까지 그 값을 계속 사용**하게 만들어 결측을 줄이고 더 많은 종목에서 신호가 계산되도록 하여 커버리지를 높이는 역할을 한다.
- 커버리지 확인 방식
- Coverage를 가장 쉽게 확인할 수 있는 방법은 IS Summary 표에 나오는 long/short count를 확인해보는 것 입니다. 여러분이 simulation setting에서 설정한 universe가 long count와 short count의 합과 비슷한지 확인해보시면 현재 본인의 알파 커버리지에 대해서 파악할 수 있습니다. long count와 short count의 합이 설정된 universe보다 현저히 작다면 지금 알파 커버리지가 낮다는 의미이고, 여러분의 포트폴리오 내에서 특정 종목에 자본이 몰렸을 가능성이 높다고 해석하실 수 있습니다.
- https://support.worldquantbrain.com/hc/en-us/community/posts/11807866133911--BRAIN-TIPS-6-ways-to-quickly-evaluate-a-new-dataset
- Robustness와 sub-universe sharpe
- Sub-universe 퍼포먼스를 개선 시키기 위해서는 먼저, 효율적인 Liquid한 주식들에서도 잘 working할 만큼 강력한 알파 아이디어와 데이터를 잘 고르는게 중요합니다. 여기서 말하는 **“효율적인(liquid) 주식”**은 단순히 유동성이 크다는 의미만이 아니라 시장 정보가 빨리 가격에 반영되는, 즉 가격이 비교적 효율적으로 형성되는 대형·거래 활발한 종목들을 말하는데 보통 거래량이 많고 시총이 크고 애널리스트 커버리지도 많은 종목들이 여기에 해당한다; 그래서 universe를 TOP3000에서 TOP1000처럼 줄이면 평균적으로 이런 종목 비중이 높아지는데, 문장이 말하고 싶은 핵심은 좋은 알파라면 이런 효율적인(=이미 많은 정보가 반영된) 종목들에서도 여전히 예측력이 있어야 한다는 것이고, 예시의 rank(ts_rank(sales/assets,252)) 알파처럼 “매출/자산이 증가하는 기업을 롱”하는 신호를 쓰면 대형·유동성 높은 기업들은 이미 그 값이 높게 평가되어 있을 가능성이 커서 오히려 그 그룹 안에서는 short 신호가 많이 나오거나 예측력이 약해질 수 있으므로, liquidity 같은 기준으로 그룹을 나눠 **같은 유동성 수준의 종목끼리 비교(neutralize)**하면 liquid 주식에서도 신호의 예측력이 더 잘 나타날 수 있다는 의미다.이러한 이유로, 비교군을 수정해줌으로서 Liquid 주식들에서의 prediction power를 올리는 개발을 할 수 있을 것 같습니다.
- slow factor / fast factor
**slow factor / fast factor**는 팩터 신호가 **얼마나 빨리 변하고 얼마나 자주 포지션이 바뀌는지**에 따른 구분으로, **slow factor**는 변화 속도가 느리고 정보가 오래 지속되는 팩터로 보통 **펀더멘털 데이터(재무제표, 밸류에이션, ROE, book-to-market 등)**처럼 **분기·연 단위 업데이트 → 낮은 turnover → 장기 보유 전략**에 사용되며 신호의 **decay가 느린 특징**이 있고, 반대로 **fast factor**는 **가격·거래량·단기 수익률 같은 시장 데이터**에서 나오는 **빠르게 변하는 신호**로 **일별 또는 intraday 업데이트 → 높은 turnover → 단기 트레이딩**에 사용되며 예를 들어 **short-term momentum, reversal, volatility spike, volume shock** 같은 것이 여기에 해당하고, 실무에서는 보통 **slow factor는 구조적 프리미엄을 잡는 장기 신호, fast factor는 단기 가격 비효율을 잡는 신호**로 보고 두 종류를 **결합해 포트폴리오 안정성과 수익원을 동시에 확보하는 전략**을 많이 사용한다.