#주식/투자

난 내가 코딩해서 투자해: 전략구현과 백테스팅

SUNGWOO BAE
PRO

2023-02-02 · 19 MIN READ

TradingView 매뉴얼: 전략의 구조 및 따라하기

*2022-01-25 글


어떠한 전략, 혹은 지표가 특정 종목에서 어떠한 성과를 거두었는지 확인해보기 위해서는 어떻게 해야할까요?

과거 데이터들을 기반으로 이전부터 해당 전략으로 투자를 하였다면 성과가 어땠을 지 확인하는 과정인 백테스팅을 거쳐야합니다.

물론 과거에 수익이 좋았다고 해서 앞으로도 좋을 것이라는 보장은 없습니다. 과거에 운 좋게 타이밍이 잘 맞은 것이었을 수 있기 때문입니다.

그러나 평생 성과가 좋지 않은 전략과, 적어도 오늘까지는 성과가 좋은 전략이 있다면 어떠한 전략을 택하시겠습니까?


효율적시장가설에 의거, 트레이딩은 효율적이지 못하다고 주장할 수도 있습니다. 저도 시장은 효율적이라고 생각합니다.

그러나, a.해당 가설은 실증 연구 결과들을 설명하지 못하는 경우도 존재하며, b.시장은 효율적일 수 있으나 개별 종목은 효율적이지 못합니다.


TradingView 코딩은 단순히 전략을 실험해보고 적용하는데 그치지 않습니다.

여러 종목과 상황에 여러 전략을 테스팅해보고 그 결과를 확인하는 과정을 통해, 사고의 폭을 넓힐 수도 있습니다.

"어떠한 지표에서 이런 모양이 되면 주가가 오르더라" 보다,

"이 지표를 보았을 때, 어떠한 방식으로 짜여진 수식의 구조가 성과에 영향을 주었구나, 해당 시장은 어떠한 특징이 있다고 생각해 볼 수 있겠다" 라고 생각할 수 있는 밑바탕이 된다는 것입니다.


이 두가지는 큰 차이가 존재합니다. 수동과 능동의 차이입니다. 시장이 이상해서, 혹은 세력이 존재해서 손실이 났는데 다음 투자에 같은 방식으로 투자하는 것은 수동적입니다. 손실의 이유를 외부요인으로 돌렸을 뿐만 아니라, 실수를 반복하기 때문입니다. 능동적인 투자자는 시장은 항상 이상하고 세력도 항상 존재한다는 것을 인정하고, 상황이 바뀌었다면 바뀐 상황을 전략에 적용하며 대응합니다.

능동적으로 대응하는 방법에는 여러가지 방법이 있습니다. 개인마다 차이도 크기 때문에 어떻게해야 능동적이 될 수 있을지는 알려드리기가 어렵습니다.

그러나 그 많은 방법 중, 계량적으로 접근하는데 밑바탕이 될 수 있는 툴 까지는 알려드릴 수 있습니다. 그 것이 AWARE.의 역할이기도 합니다.



코드의 구조


구조를 알려드리기 앞서, 아래의 모든 글은 TradingView를 기반으로 진행됩니다.

참고: 난 내가 코딩해서 투자해: TradingView 따라잡기 (입문편)


보다 원활한 작성을 위해, 참고 게시물을 전부 읽으신 상황이라는 가정 하에 글이 작성되었음을 알립니다.


현재 최신 버전은 5이나, 개인적으로 더 정확한 전달을 위해

이후의 모든 글은 Version 4 기준으로 작성할 예정입니다.

//@version=5 에서 //@version=4 로 숫자만 바꿔서 입력해주시면 됩니다.



이번에도 머리, 몸통, 꼬리로 분류하여 설명드리겠습니다.

지표 코딩과의 차이점은 몸통과 꼬리부분에서 나뉩니다.


머리

코드의 버전과, 해당 코드가 지표인지 전략인지를 구분하고, 차트 위에 표시할 것인지, 또는 차트와 분리해서 볼 것인지를 정하는 등,

전반적으로 지표(혹은 전략)의 큰 틀을 정하는 부분입니다.


몸통

전반적인 코드를 입력하는 부분입니다. 다양한 함수를 이용하여 수식을 구성하고, 해당 수식을 특정 단어로 정의하는 단계입니다.

함수를 입력하시다가 Ctrl+클릭 으로 함수에 대한 매뉴얼을 확인해 보실 수 있습니다.


이 다음으로 지표에서 꼬리에 해당되었던 부분은 전략에서 몸통에 해당됩니다.

단어로 정의한 수식들을 구현할 수 있으나 전략에서의 이 과정은 선택사항입니다. 보다 나은 가시성을 위해 구현하는 것을 권장드립니다.

수식을 그림으로 표현하기 위해서는 plot함수를 사용하여야 하며, 이 때 지표의 스타일이나 색, 선 굵기, 투명도 등을 정할 수 있습니다.


꼬리

단어로 정의한 수식들을 활용해 상황을 만들고, 해당 상황에 어떠한 행동 (매수, 매도 결정 등)을 할 것인지 정하는 부분입니다.



코딩 따라해보기



전략에서는, 어떠한 순간에 진입을 하고 실현을 했는지 화살표로 표기됩니다.

청색 화살표는 Long 포지션 (매수)

적색 화살표는 Short 포지션 (공매도)

보라색 화살표는 실현 혹은 손절을 의미합니다.


위 사진과 같이 두가지 이동평균선을 활용한 전략을 구현하는 과정을 보여드리겠습니다.


먼저 코드는 아래와 같습니다.


//@version=4

strategy("이동평균선", overlay=true)

 

N = input(title = “short ma”, defval = 20, type = input.integer)

N2 = input(title = “long ma”, defval = 50, type = input.integer)

S = sma(close, N)

S2 = sma(close, N2)

plot(S, color = color.red, linewidth = 2)

plot(S2, color = color.blue, linewidth = 2)

 

longCondition = S > S2

if (longCondition)

   strategy.entry("L", strategy.long)

strategy.close("L", when = S < S2)


해석하자면 다음과 같습니다.


//@version=4번째 버전

전략구현함수 ("전략이름", 차트위표시여부=)

 

N = 변수값함수(제목 = “short ma”, 기본값 = 20, 종류 = 정수)

N2 = 변수값함수(제목 = “long ma”, 기본값 = 50, 종류 = 정수)

S = 단순이동평균(종가, N일)

S2 = 단순이동평균(종가, N2일)

구현함수(S)

구현함수(S2)


longCondition = S > S2

만약 (longCondition)

   전략 진입 ("전략이름", 매수전략)

전략 실현("전략이름", 언제? = S < S2)


추가:

공매도는 strategy.short 입니다. strategy.long과 같은 방식으로


shortCondition = 상황 입력
if (shortCondition)
   strategy.entry("S", strategy.short)

으로 구현하실 수 있습니다.


조금 더 자세히 설명드리겠습니다.


머리


전략구현함수는 strategy입니다. strategy 함수 내에서는 틱마다 재계산 등 추가적으로 설정할 수 있는 부분들이 존재하나,

이는 코딩이 끝난 이후 조정이 가능하기에 기본적인 인수만 알려드리겠습니다.


몸통


몸통 부분은 난 내가 코딩해서 투자해: TradingView 따라잡기 (입문편) 에서 언급한 몸통~꼬리 부분에 해당됩니다.

이에 따라 생략하도록 하겠습니다.


꼬리


몸통에서 20일 이동평균선을 S, 50일 이동평균선을 S2라고 정의하였습니다.

우리가 원하는 진입 상황은 20일 이동평균선(S)이 50일 이동평균선(S2)보다 높은 상황입니다.

이에 따라 이 진입 상황을 정의해야할 필요가 있습니다.


longCondition = S > S2


추가:

만약 단순히 큰 것이 아니라, 교차를 상황으로 정의하시길 바라는 분들은, 해당 식을 다음과 같은 식으로 대체할 수 있습니다.

longCondition = crossover(S, S2)

crossover(S, S2) 는 "SS2를 상향 교차" 라는 뜻입니다.


여기까지 완료되었다면, 전략을 구현할 필요가 있습니다.

만약 진입 상황이라면..

if (longCondition)

전략 진입 !

   strategy.entry("L", strategy.long)

이 때, 앞에 어느정도 스페이스바를 눌러 열을 맞춰주셔야 아래와 같은 오류가 발생하지 않습니다.



"L"이라는 이름의 전략이고, 매수하는 전략(strategy.long)이라는 뜻입니다.


샀다면, 언젠가는 팔아야겠죠?

strategy.close("L", when = S < S2)


20일 이동평균선이 50일 이동평균선보다 높은 상황 (S > S2) 에 샀으니,

20일 이동평균선이 50일 이동평균선보다 낮은 상황 (S < S2) 일 때 팔아야겠습니다.


S < S2이라는 상황일 때, "L"이라는 이름의 전략을 종료(strategy.close)한다는 뜻입니다.


추가:

위에서 교차를 상황으로 정의하신 분들은

longCondition = (S > S2)

longCondition = crossover(S, S2)

라고 바꾸셨었죠?

파는 경우도 동일하게,

strategy.close("L", when = S < S2)

strategy.close("L", crossunder(S, S2)

라고 바꿔주시면 됩니다.

crossover crossunder헷갈리지 않게 주의해주시기 바랍니다.

crossunder은 하향교차를 의미합니다.


이후 "차트에넣기"를 클릭하시면 코드로 짠 식이 전략으로 적용됩니다.



적용 이후 설정



차트에넣기 직후, 혹은 전략테스터 - 오버뷰 를 클릭하시면 다음과 같은 화면에 도달하게 됩니다.


순익

최종 수익을 뜻합니다.

청산된 트레이드 전체

총 몇 번의 거래가 있었는지에 대해 확인 할 수 있습니다.

승률

승률입니다. 전체 거래 횟수 중 수익이 난 거래의 수를 의미합니다.

수익 팩터

Profit Factor, 수익계쑤를 의미합니다.

수치가 높을수록 수익변화의 변동성이 적다는 것을 의미합니다.

최대 손실폭

MDD( Maximum Draw Down)이라고도 불립니다. 계좌의 고점대비 최대 하락이 얼마였는지를 알려줍니다.

MDD가 74.73%라는 것은 백테스팅 기간 중 최대 74.73%의 손실까지 본적이 있음을 뜻합니다.

평균거래

평균적으로 한 거래 당 어느정도의 수익 혹은 손실이 났는지에 대한 항목입니다.

거래시 평균봉수

진입 후 실현까지 평균적으로 얼마나 종목을 가지고 있었는지 알려줍니다.

일봉에 59이니 평균적으로 한 신호 당 59일을 보유하고 있었다는 것이 됩니다.


여기서 잠시, 사진에 강조표시를 한 톱니바퀴를 클릭하시면 다음과 같은 화면에 도달하게 됩니다.



이 화면을 통해 우리가 코딩한 전략 또는 지표의 설정을 바꿀 수 있습니다.

전략이라면 설정값에 의해 백테스팅 결과가 상이해집니다.


인풋

몸통에서 정의한 내용의 수치 혹은 변수를 변경할 수 있습니다.

코딩을 자세히 할 수록 인풋에서 변경 가능한 부분이 증가합니다.

N = input(title = “short ma”, defval = 20, type = input.integer)

N2 = input(title = “long ma”, defval = 50, type = input.integer)

에서, 각 이동평균선의 titleshort malong ma로 이름을 지어주었기 때문에 위와 같은 이름으로 표기되는 것입니다.

2050의 숫자를 변경하시면, 각 이동평균선의 기간이 변경하신 숫자대로 적용됩니다.


속성


초기자본금

시작 자금을 정할 수 있습니다.

베이스통화

USD, KRW 등 어떠한 통화를 기준으로 할 것인지 정할 수 있습니다.

오더사이즈

거래 당 진입할 비중을 의미합니다.

오더사이즈에서는 계약, 통화, 자기자본%로 나뉘며, 계약은 몇 계약 진입할 것인지, 통화는 얼마만큼 진입할 것인지, 자기자본%는 몇 퍼센트만큼 진입할 것인지를 정할 수 있습니다.

피라미딩

동일한 방향에 대한 추가진입여부를 의미합니다.

커미션

거래 수수료를 의미합니다. 거래할 때마다 발생하는 수수료로, 증권사 혹은 거래소마다 수수료가 상이하기에 그에 맞게 설정하시면됩니다.

리밋오더검증

주문체결이 되었어야했는데 급등락(갭상승 혹은 하락)으로 인해 안된 경우 재계산을 위한 항목입니다.

슬리피지

거래 주문이 들어가는 시점과 거래가 체결되는 시점이 다르기에 실제 거래 성과와 차이가 생길 수 있습니다.

이에 따라 슬리피지를 몇 틱으로 하느냐에 대해 백테스팅 검증을 해볼 수 있습니다.

롱포지션증거금

공매수 증거금을 입력하는 항목입니다.

숏포지션증거금

공매도 증거금을 입력하는 항목입니다.

재계산

주문 직후 혹은 한 틱 이내로 진입을 계산하여 결과에 반영하는 항목입니다.

보수적인 백테스팅을 선호하시는 분들은 체크하지 않는 것을 권장드립니다.



모습


plot한 지표의 색, 형태, 투명도 등을 변경할 수 있으며,

차트 위에 화살표를 표시할 것인지, 글자 등을 표기할 것인지 정할 수 있습니다.


보임

지표 및 전략 plot에 관련된 항목입니다.




성과요약



오버뷰와 설정을 확인하였으니, 이제 성과요약을 확인하도록 하겠습니다.

스크롤을 통해 하단으로 이동할 수 있습니다. 여기서의 롱은 매수(공매수), 숏은 공매도를 의미합니다.

오버뷰에서 다룬 내용을 제외하고 중요한 내용만을 말씀드리자면 다음과 같습니다.


총수익, 총손실

수익의 합계와 손실의 합계입니다. 둘을 더하면 손익이 됩니다.

바이앤홀드리턴

백테스팅 기간동안 전략을 사용하는 대신 종목을 보유하고있었을 때의 손익을 의미합니다.

샤피레이쇼

Sharpe Ratio입니다. 펀드성과지표 중 하나로, 변동성 대비 초과수익을 확일할 수 있습니다.

Sortino Ratio

소르티노 지수입니다. Sharpe Ratio와 같이 변동성대비 수익을 검증하나, 수익률이 음수일 때의 변동성만을 적용합니다.

하방리스크 대비 초과수익률을 확인할 수 있습니다.

평균수익/평균손실 비율

손익비입니다. 수치가 높을수록 손실보다 수익이 많다는 뜻입니다.

마진콜

선물거래의 경우, 증거금이 부족할 때 강제로 청산당하는 경우가 존재합니다.

현물거래인 경우는 해당사항 없습니다.


거래목록

거래목록에서는 백테스팅 내역을 확인할 수 있습니다.

각 거래목록을 클릭하여 해당 거래가 발생한 시점의 차트를 확인할 수 있습니다.




누군가 구독자 여러분께 투자 어떻게하냐고 물었을 때,

"난 내가 스스로 코딩해서 투자해"에서 그치지 않고

"난 내 프로그램이 알아서 투자해줘"라고 말할 수 있을 때 까지 AWARE.가 함께하겠습니다.


TradingView 코딩으로 시스템 트레이딩까지 가능하거든요.