๐ ๋ณผ๋ฆฐ์ ๋ฐด๋์คํด์ฆ CODE
๋นํธ์ฝ์ธ ๋ฐ์ดํฐ์ ๋ํด ๋ณผ๋ฆฐ์ ์คํด์ฆ ์ ๋ต์ ์ ์ฉํ๊ณ , ์ฑ๊ณผ๋ฅผ ๋ถ์
โ ๊ธฐ๋ฅ:
- ๋ณผ๋ฆฐ์ ๋ฐด๋(20, 2) ๊ณ์ฐ
- ์คํด์ฆ ๋ฐ์ ํ์ง (๋ฐด๋ ํญ์ด ์ผ์ ์๊ณ๊ฐ ์ดํ)
- ๊ฐ๊ฒฉ์ด ์๋จ/ํ๋จ ๋ํ ์ ๋งค๋งค
- ์ฑ๊ณผ ๋ถ์ (์์ต๋ฅ , ์น๋ฅ , ์ต๋ ์์ค ๋ฑ)
๐น ์ฝ๋ ์คํ ์์
- ๋นํธ์ฝ์ธ ๋ฐ์ดํฐ ๋ค์ด๋ก๋ (yfinance ์ฌ์ฉ)
- ๋ณผ๋ฆฐ์ ๋ฐด๋ ๊ณ์ฐ
- ์คํด์ฆ ๋ฐ์ ํ์ธ ๋ฐ ์ง์ ์กฐ๊ฑด ์ค์
- ์ ๋ต ๋ฐฑํ ์คํธ
- ์ฑ๊ณผ ๋ถ์ ๋ฐ ์๊ฐํ
๐ Python ์ฝ๋
import pandas as pd
import numpy as np
import yfinance as yf
import matplotlib.pyplot as plt
# 1๏ธโฃ ๋นํธ์ฝ์ธ ๋ฐ์ดํฐ ๋ค์ด๋ก๋
symbol = "BTC-USD"
data = yf.download(symbol, start="2022-01-01", end="2025-01-01")
# 2๏ธโฃ ๋ณผ๋ฆฐ์ ๋ฐด๋ ๊ณ์ฐ (20์ผ ์ด๋ํ๊ท + ํ์คํธ์ฐจ)
window = 20
std_dev = 2
data['SMA'] = data['Close'].rolling(window).mean()
data['STD'] = data['Close'].rolling(window).std()
data['Upper'] = data['SMA'] + (data['STD'] * std_dev)
data['Lower'] = data['SMA'] - (data['STD'] * std_dev)
data['Band_Width'] = data['Upper'] - data['Lower']
# 3๏ธโฃ ์คํด์ฆ ๋ฐ์ ํ์ง (๋ฐด๋ ํญ์ด ์ผ์ ์๊ณ๊ฐ ์ดํ)
squeeze_threshold = data['Band_Width'].rolling(window).mean() * 0.8
data['Squeeze'] = data['Band_Width'] < squeeze_threshold
# 4๏ธโฃ ๋งค๋งค ์ ํธ ์์ฑ (์คํด์ฆ ํ ๋ํ ์ฌ๋ถ ํ์ธ)
data['Long_Entry'] = (data['Squeeze']) & (data['Close'] > data['Upper'])
data['Short_Entry'] = (data['Squeeze']) & (data['Close'] < data['Lower'])
data['Position'] = 0
data.loc[data['Long_Entry'], 'Position'] = 1 # ๋กฑ ํฌ์ง์
\data.loc[data['Short_Entry'], 'Position'] = -1 # ์ ํฌ์ง์
data['Position'] = data['Position'].shift(1).fillna(0) # ์ ํธ ๋ค์๋ ์ง์
# 5๏ธโฃ ๋ฐฑํ
์คํธ: ์ผ๋ณ ์์ต๋ฅ ๊ณ์ฐ
data['Returns'] = data['Close'].pct_change()
data['Strategy'] = data['Position'].shift(1) * data['Returns']
cumulative_strategy = (1 + data['Strategy']).cumprod()
cumulative_market = (1 + data['Returns']).cumprod()
# 6๏ธโฃ ์ฑ๊ณผ ์งํ ๊ณ์ฐ
final_return = cumulative_strategy.iloc[-1] - 1
win_rate = (data['Strategy'] > 0).sum() / (data['Strategy'] != 0).sum()
max_drawdown = (cumulative_strategy / cumulative_strategy.cummax() - 1).min()
print(f"๐ ์ต์ข
์์ต๋ฅ : {final_return:.2%}")
print(f"โ
์น๋ฅ : {win_rate:.2%}")
print(f"โ ๏ธ ์ต๋ ์์ค(Drawdown): {max_drawdown:.2%}")
# 7๏ธโฃ ์ฑ๊ณผ ์๊ฐํ
plt.figure(figsize=(12, 6))
plt.plot(cumulative_strategy, label='Bollinger Squeeze Strategy', color='blue')
plt.plot(cumulative_market, label='Market (BTC)', color='gray', linestyle='dashed')
plt.legend()
plt.title('Bollinger Squeeze Strategy Performance')
plt.xlabel('Date')
plt.ylabel('Cumulative Returns')
plt.show()
๐ ๊ฒฐ๊ณผ ๋ถ์
- ์ต์ข ์์ต๋ฅ : ๋ฐฑํ ์คํธ ๊ธฐ๊ฐ ๋์์ ์ ๋ต ์ฑ๊ณผ
- ์น๋ฅ : ๋กฑ/์ ์ง์ ์ ์ฑ๊ณตํ ๋น์จ
- ์ต๋ ์์ค: ์ ๋ต์ ์ต๋ ํ๋ฝํญ (Drawdown)
- ์๊ฐํ: ์ ๋ต ์์ต๋ฅ vs. ์์ฅ ์์ต๋ฅ ๋น๊ต