2021. 6. 19. 22:10ㆍFinancial Analysis
삼중창 매매 시스템(Triple Screen Trading System)은 추세 추종과 역추세 매매법을 함께 사용하여
세 단계의 창을 참조하여 정확한 매수/매도 타이밍을 찾도록 구성되어 있다.
첫번째 창 - 시장 조류
삼중창 매매 시스템에서의 첫 번째 창에서는 추세지표를 통해 시장 조류를 분석한다.
삼중창 매매기법의 코드를 단계적으로 구현해보겠다.
import pandas as pd
import matplotlib.pyplot as plt
from mpl_finance import candlestick_ohlc
import matplotlib.dates as mdates
from Investar.MarketDB import MarketDB
class TripleScreen():
def __init__(self, company, start_date):
mk = MarketDB()
self.df = mk.get_daily_price(company, start_date)
self.company = company
self.ohlc = pd.DataFrame()
TripeScreen 클래스에서는 <사명> 과 <시작일>을 인수로 전달받는다.
MarketDB 클래스를 통해 DB에서 해당 시작일부터의 데이터를 데이터프레임의 형태로 저장한다.
def get_market_tide(self):
df = self.df
ema60 = df.close.ewm(span=60).mean()
ema130 = df.close.ewm(span=130).mean()
macd = ema60 - ema130
signal = macd.ewm(span=45).mean()
macdhist = macd - signal
df = df.assign(ema130=ema130, ema60 = ema60, macd = macd,
signal = signal, macdhist=macdhist).dropna()
df['number'] = df.index.map(mdates.date2num)
ohlc = df[['number', 'open', 'high', 'low', 'close']]
ohlc.index = pd.to_datetime(ohlc.index)
self.ohlc = ohlc
self.df = df
return
시장 조류를 분석하는 코드이다.
먼저 클래스 멤버 변수인 df를 가져와서 복사한뒤, 판다스의 ewm 함수를 이용하여 종가의 12주(60일), 26주(130일)의
EMA를 구한다. 일간 차트 기준으로 매매를 하기 때문에 EMA를 구할 때 주간 단위를 이용한다.
MACD선과 시그널선도 구해준다. 앞에서 구한 값을 데이터프레임의 컬럼에 추가한다.
만들어진 ohlc와 df를 각각 대응하는 멤버 변수에 저장해준다.
def show_candle_chart(self,subplot):
df = self.df
plt.title('Candle & MACD Chart')
plt.grid(linestyle = "dotted")
candlestick_ohlc(subplot, self.ohlc.values, width=.6, colorup='red', colordown='blue')
subplot.xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m'))
plt.plot(df.number, df['ema130'], color='c', label = 'EMA130')
plt.legend(loc='best')
def show_macd_chart(self, subplot):
df = self.df
subplot.xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m'))
plt.bar(df.number, df['macdhist'], color='m', label='MACD-hist')
plt.plot(df.number, df['macd'], color='b', label='MACD')
plt.plot(df.number, df['signal'], 'g--', label='MACD-signal')
plt.legend(loc='best')
각각 ohlc 캔들차트와 EMA선을 그리는 함수, 그리고 macd히스토그램과 MACD선, 시그널선을 그리는 함수이다.
### main함수
tw = TripleScreen('대한항공', '2019-03-06')
tw.get_market_tide()
p1 = plt.subplot(2,1,1)
tw.show_candle_chart(p1)
p2 = plt.subplot(2,1,2)
tw.show_macd_chart(p2) plt.show()
다음의 결과가 출력된다.
두번째 창 - 시장파도
삼중창 매매 기법의 두번째 창은 오실레이터를 이용하여 시장 파도를 분석하는 것이다.
스토캐스틱 30 이하에서 매수하고, 70 이상에서 매도하는 조건으로 코드를 구현해보자.
def get_market_wave(self):
df = self.df
ndays_high = df.high.rolling(window=14, min_periods=1).max()
ndays_low = df.low.rolling(window=14, min_periods=1).min()
fast_k = (df.close - ndays_low) / (ndays_high - ndays_low) * 100
slow_d = fast_k.rolling(window=3).mean()
df = df.assign(fast_k=fast_k, slow_d=slow_d).dropna()
self.df = df
return
14일 간의 최고가와 최저가를 각각 구하고, 빠른 %K와 이의 3일 동안의 평균인 느린 %D를 구한 뒤
데이터프레임에 추가해준다.
def show_stochastic_chart(self, subplot):
df = self.df
subplot.xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m'))
plt.plot(df.number, df['fast_k'], color ='c', label='%K')
plt.plot(df.number, df['slow_d'], color = 'k', label='%D')
plt.yticks([0, 20, 80, 100])
plt.legend(loc='best')
### main함수
tw = TripleScreen('대한항공', '2019-03-06')
tw.get_market_tide() p1 = plt.subplot(3,1,1)
tw.show_candle_chart(p1)
p2 = plt.subplot(3,1,2)
tw.show_macd_chart(p2)
tw.get_market_wave()
p3 = plt.subplot(3,1,3)
tw.show_stochastic_chart(p3)
plt.show()
한 가지 지표로만 매매 기준을 삼지 말고 지수 이동 평균, MACD 지표, 스토캐스틱과 같이
서로 상충하는 지표들 간의 비교를 통해 더 정확한 매매 시그널을 캐치할 수 있다.
가상 매매 구현
위 지표들을 토대로 가상으로 매매하는 코드를 구현해보자.
def sim_trade(self):
account = 1000000
stocks = 0
profit = 0
df = self.df
for i in range(len(df.close)):
if df.ema130.values[i-1] < df.ema130.values[i] and \
df.slow_d.values[i-1] >= 20 and df.slow_d.values[i] < 20:
account -= df.close.values[i]
stocks += 1
print(f"[{df.index.values[i]}] 매수 체결 - 매수가 : {df.close.values[i]} | "
f"체결 수량 : 1 | 현재 총 {stocks} 주")
elif df.ema130.values[i-1] > df.ema130.values[i] and \
df.slow_d.values[i-1] <= 80 and df.slow_d.values[i] > 80:
if stocks == 0:
continue
print(f"[{df.index.values[i]}] 매도 체결 - 매도가 : {df.close.values[i]} |"
f"체결 수량 : {stocks} | 현재 총 0 주")
account += stocks * df.close.values[i]
stocks = 0
profit = account + df.close.values[len(df.close)-1] * stocks - 1000000
print(f"삼중창 매매법 총 수익 : {profit} (원)")
26주 EMA가 상승하면서 %D선이 20 이상을 돌파 하며 추락하면 매수 시그널로,
26주 EMA가 하락하면서 %D선이 80 이하로 돌파 상승하면 매도 시그널로 인식한다.
매수 시그널에서는 한 주씩 적립 매입하고, 매도 시그널이 나오면 전량 매도를, 마지막으로 총 수익은
현재 매입한 주식의 총 가치 + 실현손익으로 계산하였다.
>>> tw.sim_trade()
[2019-10-04] 매수 체결 - 매수가 : 247000 | 체결 수량 : 1 | 현재 총 1 주
[2019-12-26] 매수 체결 - 매수가 : 277500 | 체결 수량 : 1 | 현재 총 2 주
[2020-01-29] 매수 체결 - 매수가 : 278500 | 체결 수량 : 1 | 현재 총 3 주
[2020-04-20] 매도 체결 - 매도가 : 255000 | 체결 수량 : 3 | 현재 총 0 주
[2020-12-23] 매수 체결 - 매수가 : 231500 | 체결 수량 : 1 | 현재 총 1 주
[2021-01-29] 매수 체결 - 매수가 : 233500 | 체결 수량 : 1 | 현재 총 2 주
[2021-03-23] 매수 체결 - 매수가 : 275000 | 체결 수량 : 1 | 현재 총 3 주
[2021-04-23] 매수 체결 - 매수가 : 275000 | 체결 수량 : 1 | 현재 총 4 주
[2021-05-25] 매수 체결 - 매수가 : 305500 | 체결 수량 : 1 | 현재 총 5 주
[2021-06-11] 매수 체결 - 매수가 : 299500 | 체결 수량 : 1 | 현재 총 6 주
삼중창 매매법 총 수익 : 19000 (원) Process finished with exit code 0
실험 결과, 변동성이 크지 않은 상승장에서는
- 추세 추종 매매법
- 삼중창 매매법
- 반전 매매법
변동성이 큰 박스권 종목에서는
- 삼중창 매매법
- 추세 추종 매매법
- 반전 매매법
변동성이 큰 하락장에서는
- 반전 매매법
- 삼중창 매매법
- 추세 추종 매매법
모든 종목에 대해서는 아니지만, 각 매매기법은 대략적으로 이러한 양상을 보였다.
이처럼 시장 움직임에 따라서 적합한 매매 기법이 존재하므로
전략에 맞는 알고리즘을 선택하는 것이 중요하다.
'Financial Analysis' 카테고리의 다른 글
5-1. [트레이딩 전략 구현] 심리투자 법칙 : 시장지표 (0) | 2021.06.14 |
---|---|
4-3. [트레이딩 전략 구현] 볼린저 밴드 매매 기법 : 반전 매매 기법 (0) | 2021.06.13 |
4-2. [트레이딩 전략 구현] 볼린저 밴드 매매 기법 : 추세 추정 매매 기법 (0) | 2021.06.13 |
4-2. [트레이딩 전략 구현] 볼린저 밴드 지표 : %b, 밴드폭(bandwidth) (0) | 2021.06.13 |
4-1. [트레이딩 전략 구현] 볼린저 밴드 지표 (0) | 2021.06.13 |