Bet Sizing - jaeaehkim/trading_system_beta GitHub Wiki
Motivation
- ML ์๊ณ ๋ฆฌ์ฆ์ ๋์ ์ ํ๋๋ฅผ ์ ๊ณตํ๋ค๊ณ ํด๋ ๋ฒ ํ
ํฌ๊ธฐ(Bet sizing)์ ๋ฐ๋ผ ์ ํ ๋ค๋ฅธ ๊ฒฐ๊ณผ๋ฅผ ๋ณด์ผ ์ ์์
- Hyper Parameter Tuning with Cross Validation์์ neg log loss๊ฐ accuracy ๋ณด๋ค ์ข์ ์ด์ ๋ฅผ ๋งํ๋ฏ์ด ๋์ ํ๋ฅ ์ ๋ณด์ผ ๋ ๋ฐฉํฅ์ฑ์ ์ ์์ธกํ๋ ๊ฒ๋ ์ค์ํ๋ค. ์ฌ๊ธฐ์ ๋ ์ค์ํ ๊ฒ์ ์์ ๊ฒ์ด ์ด๋ ์ ๋ ์ ์ ๋์์ ๋ ๋์ ํ๋ฅ ์ ๋ณด์ด๋ ์ํฉ์์ ๋ฒ ํ
์ ํฌ๊ธฐ๋ฅผ ํฌ๊ฒ ๊ฐ์ ธ๊ฐ๋ ๊ฒ์ด ์ค์ํ๋ค. ๋ฐ๋๋ก ๋๋ค๋ฉด ์์ต์ด ๋ ์ ์๋ ์ ๋ต์ด ์์ค์ ๋ณด๊ฒ ๋๋ ์ํฉ๋ ๋ฐ์ํ ์ ์๋ค.
Strategy-Independent Bet Sizing Approaches
- ์ ๋ต ์์ฒด(Direction model)์๋ ๋
๋ฆฝ์ ์ธ Bet Sizing ๊ธฐ๋ฒ์ ์๊ฐํ๋ค. ์ด๋ Rule-Based ๋ฐฉ์์ Bet sizing๊ณผ ์ ์ฌํ์ง๋ง Triple Barrier Labeling ์ธก๋ฉด์์ ๊ทผ๋ณธ์ ์ธ ์ฐจ์ด์ ์ด ์กด์ฌํ๋ค. ๋ํ
์ผํ๊ฒ๋ bet size๋ฅผ ๊ฒฐ์ ํ ๋ discreteํ์ง ์๊ณ continuousํ๊ฒ ์ ํ๋ค.
- ์ ์ ๋ต ์์ฒด์ ๋
๋ฆฝ์ ์ธ๊ฐ?
- ์๋ฒฝํ๊ฒ ๋
๋ฆฝ์ ์ด์ง ์์ผ๋ ์๋์ ์ผ๋ก ๋
๋ฆฝ์ ์ด๋ผ๊ณ ๋ณผ ์ ์์. (vs Bet Sizing From Predicted Probabilities)
- ํด๋น Bet Sizing ๊ธฐ๋ฒ์ Event Bar(์ฐธ๊ณ :Data-Structures)์ ์ํด sampling ๋ observations๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ๋์ด์๊ณ Model์ inference ๊ฐ ๋ณด๋ค๋ Event Bar์ ๊ฐ์์ ์์กดํด์ bet sizing์ ๊ณ์ฐํ๊ธฐ ๋๋ฌธ์ ๋
๋ฆฝ์ ์ธ ํธ.
Method 1
Calculate Trading Signal Series

- Time t์์ ์์ฑ๋ Triple Barrier์ ๊ฐ์๋ฅผ ์ธ๋ ๊ฒ์ด ๊ธฐ๋ณธ์ ์ธ ์๋ฆฌ์ด๋ค. ๋ค๋ง, ์ฌ๊ธฐ์ Long Triple Barrier์ Short Triple Barrier์ ๊ฐ์๋ฅผ ๊ฐ๊ฐ ์ธ์ด์ผ ํ๋ค. ์ด๋, Long,Short์ธ์ง๋ Model์ inference๊ฐ ์์ด์ผ ํ๋ค. ์ ์ ๋จ์๋ก ๊ฐ์ด ์ฐ์ถ๋ ๊ฒ์ด๊ณ ์ด๋ฅผ Gaussian distribution์ ํ์ฉํด weight๋ก mapping ํ๋ค.
Mapping : Trading Signal -> Bet Size
- ์ ๊ฐ์ฐ์์ ๋ถํฌ๋ฅผ ํ์ฉํ๋๊ฐ?
- ๊ณ์ฐ๋ Trading Signal์ if else: ์์ด continuousํ๊ฒ mapping ๊ฐ๋ฅํจ
- ์ ํผํฉ ๊ฐ์ฐ์์ ๋ถํฌ๋ฅผ ํ์ฉํ๋๊ฐ?
- ๋จ์ํ๊ฒ ๊ฐํ ์๊ทธ๋์ ๊ฐํ ๋ฒ ํ
์ผ๋ก ํ๊ธฐ ์ํด์ ๋จ์ผ ๊ฐ์ฐ์์ ๋ถํฌ๋ฅผ CDF(cumulative distribution function) ๊ฐ์ผ๋ก ๋งคํํ์ฌ ์ฌ์ฉํ๋ฉด ๋จ.
- ๋ค๋ง, ์ฌ๋์ ํ๋์ ๋ชจ๋ฐฉํ๋ฉด Buy Signal์ด ๋งค์ฐ ๊ฐํด์ง ์ํ๋ผ๋ฉด ๋ ๊ฐํด์ง๊ธฐ ์ด๋ ค์ด ์ํฉ์ด๋ผ๊ณ ํด์ํ ์ ์์ผ๋ฉฐ Buy Signal์ด ๋งค์ฐ ์ฝํด์ง ์ํ๋ผ๋ฉด ๊ฐํด์ง๊ธฐ ์ฌ์ด ์ํฉ์ด๋ผ๊ณ ํด์ํ ์ ์๋ค. ์ด๋ฅผ ๋ฐ์ํ๊ธฐ ์ํ mapping model๋ก๋ ํผํฉ ๊ฐ์ฐ์์ ๋ถํฌ๋ฅผ ํ์ฉํ๋ฉด ๋๋ค.
Method 2
- ์กฐ๊ธ ๋ ๊ฐ๋จํ๊ณ ์๊ธ ๊ด๋ฆฌ ๋ฐฉ์์์ ์์ฃผ ์ฌ์ฉํ๋ ์์ด๋์ด๋ฅผ ์ ๋ชฉํ๋ฉด ๋ค์๊ณผ ๊ฐ๋ค.
- long/short bet triple barrier์ ์ต๋ ๊ฐ์๋ฅผ ํ์ฉํด ๋น์จ๋ก ๊ณ์ฐํ๋ ๋ฐฉ์์ด๋ค.
- backtest ๊ด์ ์์ ์ ์ต๋ ๊ฐ์๋ฅผ ๋ฏธ๋ฆฌ ์ ์ ์์ผ๋ฏ๋ก Look-ahead bias๋ฅผ ๊ณ ๋ คํ์ฌ ๊ฐ์ ์ ํด์ผ ํจ.
Concurrent Label์ฒ๋ผ barrier๋ฅผ ์น๊ธฐ ์ ๊น์ง๋ vector์ ์ ์ง ๊ธฐ๊ฐ ๋์ 1๊ฐ์ ์ฑ์๋ฃ๊ฒ ๋๋ค. Triple Barreir ๊ธฐ๋ฒ์ ๊ณต์กดํ๋ ๊ธฐ๊ฐ์ด ๋ฌด์กฐ๊ฑด ํฌํจ๋๊ฒ ๋๋๋ฐ ์ด๋ Long Event ๋ฐ์ ๊ฐ์์ Short Event ๋ฐ์ ๊ฐ์์ ์ฐจ์ด๋ฅผ ํ์ฉํด bet sizing์ ๊ฒฐ์ ํ๋ ๊ฒ.
Bet Sizing From Predicted Probabilities
- Quant Researcher๊ฐ ๊ฐ๊ณตํ ๋ค์ํ Feature๋ฅผ ๋ฐํ์ผ๋ก ํ์ต๋ model์ probability๋ฅผ ์ ๊ทน ํ์ฉํ์ฌ ์ด๋ฅผ bet size๋ก mapping ํ๋ ๋ฐฉ๋ฒ์ด๋ค. ์ด์ ์ model์ ํ๊ฐํ ๋ neg log loss (์ฐธ๊ณ : Scoring and Hyper Parameter Tuning) ๋ฐฉ์์ผ๋ก ํ์๊ธฐ ๋๋ฌธ์ model probability๋ฅผ bet size๋ก mappingํ๋ ๊ฒ์ ํฉ๋ฆฌ์ ์ด๋ค.
Method 3


- x labeling outcome์ด 1,-1๊ณผ ๋ฐ์ ์๋ ๊ฒฝ์ฐ์ ํต๊ณ๋(test static) ์ ๋ค์๊ณผ ๊ฐ์ด ์ ์ํ ์ ์๊ณ Z๋ ํ์ค์ ๊ท๋ถํฌ ์ด๋ค.
- side์ ๋ํ ์์ธก x๊ฐ๊น์ง ๋ฐ์ํ์ฌ bet size๋ฅผ ๊ฒฐ์ ํ๋๋ก ๋ค์๊ณผ ๊ฐ์ด ์์ผ๋ก ํํํ ์ ์๋ค.
- ์ด๋ฐ mapping์ ํตํด์ p=0.501 ๊ณผ ๊ฐ์ด ์ฝ๊ฐ์ ์ฐ์๊ฐ ์๋ ๊ฒฝ์ฐ๋ bet size๋ฅผ '๋ง์ด' ์ค์ด๊ณ p=0.7๊ณผ ๊ฐ์ด 0.2 ์ ๋์ ์ฐ์๋ฅผ ๋ณด์ด๋ ๊ฒฝ์ฐ๋ ๊ต์ฅํ ์ ์ผ๋ฏ๋ก bet size๋ฅผ '๋ง์ด' ๋์ด๋ ๋ฐฉ์ ์ ์ฌ์ฉํ๊ฒ ๋๋ค.
def getSignal(events, stepSize, prob, pred, numClasses, numThreads, **kwargs):
"""
:param events:
:param stepSize:
:param prob: pd.Series with index=events.index
:param pred: pd.Series with index=events.index
:param numClasses: fit._classes
:param numThreads:
:param kwargs:
:return:
"""
if not prob.shape[0]:
return pd.Series()
signal0 = (prob - 1. / numClasses) / (prob * (1. - prob)) ** 0.5
signal0 = pred * (2 * norm.cdf(signal0) - 1)
return signal1
- ์ฝ๋ ๋ถ์
- ์ฒซ ๋ฒ์งธ signal0๋ ํต๊ณ๋์ ๋ง๋๋ ์ฐ์ฐ
- ๋ ๋ฒ์งธ signal0๋ ํ์ค์ ๊ท๋ถํฌ cdf์ ๋์
ํ์ฌ ๋ฒ ํ
๋น์จ๊ณผ ํจ๊ป ์์ pred๋ฅผ ๊ณฑํ์ฌ side์ ๋ํ ์ ๋ณด๋ ํ ๋ฒ์ ํํ
Method 4 : Averaging Active Bets
- Triple Barrier ๊ธฐ๋ฒ์ Box๋ฅผ ํ์ฑํ๊ธฐ ๋๋ฌธ์ ์ธ์ ๋ concurrentํ ์ํฉ์ด ๋ฐ์ํ๋ค. ์ด๋, ์ด๋ฏธ ๋ฒ ํ
ํ๊ณ ์๋ ์ํฉ์์ ํฌ๊ฒ 2๊ฐ์ง ์ฒ๋ฆฌ ๋ฐฉ๋ฒ์ด ์๋ค.
- ์ํฉ : p=0.6 -> m=0.3์ผ๋ก ๋ฒ ํ
์ค์ด์๋๋ฐ p=0.7 -> m=0.7 ์ ํธ๊ฐ ๋์จ ๊ฒฝ์ฐ
- ์ฒซ ๋ฒ์งธ : ๋ฎ์ด์ฐ๊ธฐ ๋ฐฉ๋ฒ์ ํ์ฉํ๋ฉด ๊ณผ๋ํ ๊ฑฐ๋๋์ ์ ๋ฐํ๋ ์ต๊ทผ ์ ๋ณด๋ก ๋น ๋ฅด๊ฒ ์
๋ฐ์ดํธ ํ ์ ์๋ค. ์ฆ,๋งํผ ์ถ๊ฐ ๋ฒ ํ
์ ํ๋ ๊ฒ
- ๋ ๋ฒ์งธ : averaging ๊ธฐ๋ฒ์ ํ์ฉํ๋ฉด ์
๋ฐ์ดํธ๋ ์กฐ๊ธ ๋ฆ์ด์ง๋ ๊ฑฐ๋๋์ ๊ณผ๋ํ๊ฒ ๋๋ฆฌ์ง ์์ผ๋ฉด์ ํ์ฌ ์ํฉ์ ์ด๋์ ๋ ๋์ํ ์ ์๋ค๋ ์ฅ์ ์ด ์๋ค. ์ด ๊ฒฝ์ด, (0.3+0.7)/2 = 0.5์ด๋ฏ๋ก ํ์ฌ 0.3์์ 0.2๋งํผ๋ง ์ถ๊ฐ ๋ฒ ํ
์ ํ๊ฒ ๋๋ค.
def mpAvgActiveSignals(signals, molecule):
'''
At time loc, average signal among those still active.
Signal is active if:
a) issued before or at loc AND
b) loc before signal's endtime, or endtime is still unknown (NaT).
'''
out = pd.Series()
for loc in molecule:
df0 = (signals.index.values <= loc) & ((loc < signals['t1']) | pd.isnull(signals['t1']))
act = signals[df0].index
if len(act) > 0:
out[loc] = signals.loc[act, 'signal'].mean()
else:
out[loc] = 0
return out
- ์ฝ๋ ๋ถ์
- for loc in molecule:์ ํตํด์ time t์ธ ์ํฉ์์ ๋ชจ๋ signal์ index๋ฅผ ์ฐพ๋ ์ฐ์ฐ ์งํ
out[loc] = signals.loc[act, 'signal'].mean()
signal์ด ์๋ ๊ฒฝ์ฐ์ ์ด๋ฅผ mean ํด์ฃผ๋ ์์
์งํ
Size Discretization
def discreteSignal(signal0, stepSize):
signal1 = (signal0 / stepSize).round()*stepSize
signal1[signal1 > 1] = 1
signal1[signal1 < -1] = -1
return signal1
- ๋ถ๊ฐ์ ์ธ ๋ฐฉ๋ฒ
- stepSize๋ก rounding์ ํด์ ํฐ ์ํฅ์ด ์๋ Signal์ด ์์ ๋ ๋ฌด์ํ ์๋ ์๊ณ ์ธ๋ฐ์๋ ๊ฑฐ๋๋์ ์ค์ผ ์ ์์
Dynamic Bet Sizes and Limit Prices
- ๊ธฐ๋ณธ์ ์ธ ์๋ฆฌ๋ Triple Barrier๋ฅผ ํ์ฑํ ๋ ์๋ Probability๋ฅผ ํ ๋ฒ๋ง ์์ธกํ๊ณ Barrier๊ฐ ๋๋ ๋๊น์ง ํด๋น ์์ธก์ ์ ์งํ๋ค. (๋ค๋ฅธ ์๊ทธ๋์ด ๋ค์ด์์ average๋ก ์ธํด ๋ฐ๋๋ ๊ฒ์ ์ ์ธ)
- Dynamic Bet์ Triple Barrier ๊ตฌ๊ฐ ์์์ ์์ฅ ๊ฐ๊ฒฉ p์ ๋ฐ๋ผ ์์ธก ๊ฐ๊ฒฉ f๋ฅผ tick ๋จ์๋ก ์
๋ฐ์ดํธ ํ๋ฉด์ f๋ฅผ ๋ฐํ์ผ๋ก bet size๋ฅผ ๋ค์ ๊ณ์ฐํ๊ณ ์
๋ฐ์ดํธ ํ๋ ๋ฐฉ์
- ํด๋น ๋ฐฉ๋ฒ์ ์ด๋ก ์ ์ผ๋ก๋ ๊ต์ฅํ ํฉ๋ฆฌ์ ์ด๋ production level๋ก ๊ฐ๋ฐํ๊ธฐ์ ๋งค์ฐ ๋ง์ ๋ฆฌ์์น๊ฐ ํ์ํ ๊ฒ์ผ๋ก ์์๋จ. ์ถํ ์ฐ๊ตฌ ๊ณผ์ .