유튜브에서 발견한 backtest 전략 추가하기 #3
사이드 프로젝트 링크 : https://www.github.com/fromitive/backtest
코드 작성 전 고려해야 할 사항
지난 시간에는 Stocastic RSI 값이 실제 거래소 값과 차이가 있어서 이를 줄여보았다.
이번에는 buy signal이 어디에 발생했는지 확인 후 수정할 사항이 없나 살펴볼 것이다.
결과는 아래의 그림과 같으며, BUY 시그널이 연속적으로 나타나는 구간이 다수 존재하는걸 볼 수 있다.
이렇게 되면 사고 팔때, 돈이 부족하거나, 백테스팅의 결과가 불규칙적으로 나타날 수 있으므로1 인접한 BUY 시그널은 없애도록 하자
그렇다면 아래의 요구사항을 추가하여 가상코드를 작성하자.
가상 코드 작성
구매한 주식을 어느 시점에 팔지는 처음 글에서도 설명했으나, 아래의 매도 조건을 참고하여 작성한다.
준비작업 : EMA 200 곡선, Stocastic RSI, RSI
- 매수
1. ema 200 값보다 캔들이 위에 있어야 함
2. stocastic rsi가 25 미만이어야 함
3. k(파란색 선)가 d(주황색 선)보다 위에 있어야 한다(이전 캔들과 비교하여 돌파 하는 걸 캐치하면 될 것 같다.)
- 매도 :
1. 매수를 진행하고 나서 3퍼센트 이상 넘으면 매도하라고 하는데 여기서는 2 퍼센트 이상일 때 매도 한다.
2. 손절을 1퍼센트 밑으로 떨어질 때 매도
매도는 매수
를 해야 할 수 있으므로, 매수
한 주식을 기준으로 수익율을 계산한다.
만약 매도 조건이 나타나지 않았을 경우, 어떻게 해야 할까? 그건 위의 추가 요구사항을 응용하여
다음 BUY 시그널이 일정 캔들차트 개수 이상 떨어져 있을 경우 그자리에서 매도하는 걸로 결정한다.
그렇다면 아래와 같이 추가 요구사항이 생겨야 한다.
1. 인접한 캔들차트에 BUY시그널이 붙어있으면, KEEP으로 변환한다.
2. 다음 BUY 시그널이 인접한 차트에 있지 않고, 이전 BUY 시그널이 SELL을 하지 않았을 경우
그 즉시 SELL을 하고, 다음 캔들에 BUY 시그널을 넣는다.
이제 본격적으로 가상코드를 작성한다. buy시그널을 발견하면, bucket이라는 공간에 담아서 수익율이 기준점 이상이거나 손절 포인트 이하일 경우 매도 한다.
이로서 추가 요구사항을 만족하며 유튜브에서 소개한 전략을 코드로 옮길 준비가 완료 된 것이다.
코드는 아래와 같다. 22번 줄 부터 46번 줄까지가 추가한 매도 루틴이다.
백테스팅 결과 확인
해당 전략을 그래프로 그린 결과, 얼추 수익을 창출(?)하는 것 같은 그래프가 완성되었다. 이제는 해당 전략이 적절한지 검증하기 위해 vectorbt 모듈을 추가로 사용 할 것이다.
vectorbt 사용
vectorbt는 지금 만들고 있는 프로젝트와 동일하게 주식에 대한 전략을 검색해주는 모듈이다.
동작 구조는 다음과 같다.
매수 신호가 나오면, 그 다음날은 매도 신호가 나와야 수익율 계산을 한다. 두 번 매수하거나, 두 번 매도하는 신호가 나오면 무시가 된다. 즉, 매수 신호와 매도 신호가 짝을 지어야 한다.
위의 동작 구조에 만족시키도록 전략 함수를 작성하였고, vectorbt를 이용해 해당전략이 적절하게 동작했는지 확인한다.
코드는 아래와 같다.
주의사항
해당 코드는 이해하기 쉽게 하기 위한 가상코드이고 실제 코드와는 차이가 있습니다.
import vectorbt as vbt
# stock_df.close - dataframe 중 close(종가) 값 세팅
# buy_result - stock_df와 같은 인덱스를 가지며 매수일 경우 True 그렇지 않을 경우 False인 DataFrame
# sell_result - stock_df와 같은 인덱스를 가지며 매도일 경우 True 그렇지 않을 경우 False인 DataFrame
pf = vbt.Portfolio.from_signals(stock_df.close,buy_result,sell_result)
pf.stats() # 결과검증
코드에 대한 결과값은 다음과 같이 나타나며, 수익을 내지 못했음을 확인했다.
Start 2023-06-19 09:00:00
End 2023-07-12 22:00:00
Period 1124
Start Value 100.0
End Value 98.500282
Total Return [%] -1.499718
Benchmark Return [%] 9.296149
Max Gross Exposure [%] 100.0
Total Fees Paid 0.0
Max Drawdown [%] 6.122818
Max Drawdown Duration 413.0
Total Trades 17
Total Closed Trades 17
Total Open Trades 0
Open Trade PnL 0.0
Win Rate [%] 41.176471
Best Trade [%] 2.734218
Worst Trade [%] -1.909587
Avg Winning Trade [%] 1.230347
Avg Losing Trade [%] -0.996401
Avg Winning Trade Duration 26.428571
Avg Losing Trade Duration 20.7
Profit Factor 0.849372
Expectancy -0.088219
dtype: object
자세한 그래프를 그리기 위해서는 아래와 같이 pf.plot().show()
를 호출하면 나타나게 된다.
다음은?
아쉽게도 해당 전략은 수익을 내지 못했다. 그 이유는 이 전략은 롱 포지션
이며 상승장
에서 통하는 전략이기 때문이다.
따라서, 다음 게시글은 유튜브에 나와있는 것처럼 하이킨아시 차트
를 적용하여, 상승장, 하락장을 구별하여 매수하는 기능을 추가할 것이다.
-
밑에서 설명하겠지만 백테스팅 검증 시
vectorbt
를 이용해서 검증하기 때문이다. ↩