BLOG main image
ddd (50)
CUDA programming (0)
알고리즘 트레이딩 (5)
Cherry Picker 개발 (23)
TSimulator 개발(종료) (11)
IT 노트 (1)
잡동사니 (2)
사진 (4)
일기 (4)
이력서 (0)
Visitors up to today!
Today hit, Yesterday hit
daisy rss
tistory 티스토리 가입하기!
'시스템 전략'에 해당되는 글 6건
2013. 12. 16. 13:36

2011 년 3월..  TradeStation 이 아닌 자기만의 트레이딩툴을 만들고 싶었던 그 때 증권 API 의 존재를 우연히 알게되고, 하루라도 빨리 화면으로 뭔가 표현해보고 싶은 마음에 급조한 프로그램이 있다. 시스템 트레이딩툴은 아니고 종목, 주문 수량,  주문 가격, 주문 타입 등을 선택하고 거래할 수 있는 수동매매툴이다. 지금은 모든 프로젝트가 Cherry Picker 라는 이름으로 통합됐고 더 이상 GUI 는 채용하고 있지 않지만 그 당시에는 TTrader 라는 이름을 지어줬었고, 허접하지만 아래 그림과 같이 GUI 로 정보를 표현할 수 있게 했다. 이 프로그램은 증권 API 테스트를 위해 급조된것에다가 시스템 전략의 수행도 불가능하므로 당연히 현재는 사용하지 않는다. 그래도 묻혀지는 것이 아쉬워 수행되는 모습을 남겨보고자 한다.



( 참고로 현재 운용중인 트레이딩 툴인 Cherry Picker 는 GUI 가 아닌 CUI 방식이며, 로그파일에 현 상황들이 실시간으로 기록이 된다. GUI 가 있으면 화려해보이고 프로그램다운 모습이지만 데이터를 보여주기 위해 필요한 리소스(CPU 등 컴퓨터 자원)가 결코 적지 않으며 무엇보다 시스템 전략은 전적으로 미리 코딩된 로직에 의해서만 운용되어야 함으로 GUI 에 의한 조작이 애초에 필요가 없기 때문이다. 시스템 트레이딩에 특화된 헤지펀드(특히 르네상스 테크놀로지)는 트레이딩룸 자체가 없고 오직 서버실과 전략개발을 위한 회의실, 그리고 개인 사무공간만 존재한다고 어디선가 읽은 기억이 있다. ) -> 이상 GUI 를 안만들어도 된다는 변명 ;;;



사진 2 장과 시연 동영상 1 개를 만들어봤다. 수행 프로그램 이름은 Cherry Picker 로 되어있는데, 이는 어느 시점에서 진행중인 모든 프로젝트 이름을 Cherry Picker 로 통합했기 때문이다. 



서버 접속 직전의 모습 (화면을 클릭하면 크게 볼 수 있습니다.)



첫 번째 사진은 프로그램이 증권사 서버에 접속하기 이전인 프로그램 수행 직후의 모습이다. 왼쪽 검은 화면은 각종 정보메세지를 출력하는 부분이고, 오른쪽 화면이 프로그램을 조작하거나 가격, 계좌정보, 잔고 등을 표현하는 GUI 부분이다.



서버 접속 후의 프로그램 수행중인 모습 (화면을 클릭하면 크게 볼 수 있습니다.)



두 번째 사진은 증권사 서버 접속 직후의 모습이다. 직관적으로 각 버튼 또는 창들이 의미하는바를 쉽게 알 수 있다.



증권사 서버 접속 후 간단한 거래를 하는 모습 (플레이 버튼을 누르면 재생됩니다.)



위 영상은 서버에 접속을 하고 간단한 선물거래를 하는 영상이다. 시계를 보면 9시 직전에 서버에 접속을 했으며 9시00분00초가 되자 수신되기 시작한 실시간 데이터들이 화면에 보여지며, 매수 또는 매도거래가 행해지고 계좌 및 잔고상태를 확인하는 버튼을 누르면 해당 정보가 갱신됨을 알 수 있다. 보다시피 시스템전략과는 무관한 프로그램이며 그냥 편한 수동거래툴(?) 정도로 인식하는것이 좋겠다.


다음 포스팅에서는 본격 시스템 트레이딩툴인 Cherry Picker 의 수행모습을 화면에 담아볼 것이다. (이미 이전 몇몇 포스팅에서 캡쳐사진을 올린바 있지만...) GUI 가 없기 때문에 뭔가 굉장히 단순해 보일지 모르겠지만 그 내부에서는 아주 나이스하게 시스템 전략들이 관리 및 운용되고 있다.

'Cherry Picker 개발 > Cherry Picker 소개' 카테고리의 다른 글

근황  (2) 2018.01.10
Cherry Picker 와 이 블로그에 대한 설명  (0) 2013.09.27
2013. 11. 21. 11:54

API 를 이용한 시스템 트레이딩은 증권사 서버에서 정보를 받아와 그 정보를 분석한 후에 주문을 내거나 추가적인 정보를 다시 얻어오는 등 다양한 행동이 서버에서 받은 정보를 근거로 이루어진다. 그러므로 모든 행동은 절차적으로 정교하게 이루어져야한다.


시스템 분석 엔진에서 다음과 같은 신호가 발생했다고 가정하자.


===================================

"최근월물 선물의 매도 1호가로 1 계약 지정가 주문"

===================================


만약(그럴일은 없겠지만) 거래소 서버에 직접 트레이딩 프로그램을 깔 기회가 있다면 다음과 같이 코딩하면 된다. (사용해본 적이 없는 아주 엉뚱한 코드이므로 흐름만 보자)


===================================

char sPrice     [100] = ""; // 1호가를 담을 변수

char sFutCode[100] = ""; // 최근월물 선물 코드를 담을 변수


setFutCode( sFutCode, 1 );                    // 최근월물 선물 코드 세팅

setPrice     ( sPrice, sFutCode, ASK_1 );  // 1호가를 세팅


order( sFutCode, "지정가", sPrice, 1 );  // 주문함수

===================================


이렇게 간단하게 만들 수 있다. 하지만 위 코드에서 setFutCode, setPrice 부분은 서버와의 통신을 해야하는 클라이언트의 입장에서는 불가능한 함수이다.


(물론 해당함수의 내부에서 대기시키는 방법도 있고, 실시간 데이터를 받는 경우 로컬에 저장되어있는 값을 세팅한다면 위 코드도 가능하다. 하지만 전자는 다중 스레드 처리를 해줘야하고 후자는 로컬에 저장된 값과 실제 거래소의 값에 타이밍적으로 차이가 있을 수도 있다.)


그럼 위의 주문을 수행시키려면 어떤 방법이 효과적일까. 더 좋은 방법이 많겠지만 환형큐를 이용하여 모든 행동 하나하나를 action 이라고 칭하는 단위로 구분하여 순차적으로 수행시키는 것이다. 쉽게말해 '할일 리스트' 를 환형큐에 차례대로 세팅하고 큐를 관리하는 매니저한테 그것들은 순서대로 수행시키라고 명령을 하는것이다. 그럼 큐관리자는 action 하나를 처리하고 답을 얻을 떄까지 그 다음 action 은 진행시키지 않고 대기하면 된다. 위 주문을 action 단위로 나누면 다음과 같다.


action 1 : 선물코드를 모두 받아온다.

action 2 : 받은 선물코드 중에 최근월물을 찾아 로컬에 세팅한다.

action 3 : 세팅한 선물코드의 호가정보를 받아온다.

action 4 : 받은 호가정보중에 매도 1호가를 찾아 로컬에 세팅한다.

action 5 : action 2, action 4 에서 세팅한 정보로 주문을 낸다.


이렇게 하나의 주문을 내기위해 서버와 세 번의 통신(action 1, 3, 5)을 해야한다. 그래봤자 이 모든 과정이 0.1초도 안걸린다. HFT 의 세계에서는 위의 과정보다 더더욱 많이 효율적인 방법을 써야한다. 위의 예를 들면 선물코드는 장 시작 전에 이미 받아와서 모두 로컬에 세팅된 상태여서 action 1 의 과정이 필요없는 경우 등이 있다.


(참고로 실제 Cherry Picker 에서 위의 주문을 성사시키려면 action 5 만 수행하면 된다. action 1, 2 는 시스템 구동시에 이미 로컬에 저장된 상태고, action 3, 4 는 실시간 호가데이터 수신으로 역시 이미 로컬에 최신 정보가 저장된 상태이기 때문이다. action 1~4 는 circular queue 사용법을 설명하기 위한 예일 뿐이다.)


이를 그림으로 표현하면 다음과 같다. (못난그림)





15 개의 action 을 세팅할 수 있는 환형큐다. 큐안의 숫자는 action 고유번호고, action position 은 현재 수행되는 action 의 위치, set position 은 현세 세팅되는 action 의 위치를 의미한다. 큐사이즈는 마음대로 정할 수 있지만 그렇다고 1000, 2000 개까지는 필요없다. 코스피 전종목을 거래하는 거대한 시스템이라면 10000 개도 모자르겠지만... 


결론적으로 이런식으로 action 을 다루는 로직을 구현했고 정보창에 다음과 같이 표시되어 쉽게 현재상태를 알수 있게 만들었다.





부가설명을 하자면 'XX[YYY] will be executed' 는 '큐의 XX 번째에 있는 YYY 라는 action 이 수행된다.' 라고 해석하면 된다. action 번호를 다 외우지는 않았지만 111 은 호가조회 action 125 는 받아온 호가를 주문관련변수에 세팅하는 action 124 는 주문하는 action 일것이다. 그리고 숫자열 상단의 '@' 표시는 환형큐의 action position 을 의미하고 숫자열 하단의 '*' 표시는 환형큐의 set position 을 의미한다.


이런식으로 모든 행동을 관리하면 상당히 복잡한 주문도 절차에 의해 간단하게 수행될 수 있다. :)



2013. 11. 8. 11:38

SetTimer 함수를 도입하려고 한다.


SetTimer 는 수행시키는 순간부터 일정시간이 흐른 후에 callback 함수가 수행되거나 윈도우 메세지를 받을 수 있게한다. 단순 sleep 함수랑 다른점은 지정한 시간이 경과되고 타이머가 울릴(?)때까지 프로세스는 다른작업이 가능하다는 점이다. sleep 함수는 타이머가 울릴 때까지 (main thread 만 존재한다면)모든 작업이 중지된다. SetTimer 처럼 동작이 가능한 이유는 SetTimer 가 수행되면 thread 가 별도로 생성되기 때문이다. 


이 함수의 설명을 들으면 이것저것 적용을 시켜볼만한 부분이 떠오르는데 대략 정리하면 다음과 같다.


1. 장 시작, 장 마감, 동시호가 시작, 동시호가 끝 등의 알림

2. 분봉 생성을 위한 타이머의 역할

3. 장 종료 후에 파일 쓰기 버퍼에 쌓여있는 데이터들을 flush 하기위한 알림

4. 주문 후 일정시간이 지나도 체결이 되지 않으면 주문 취소

5. 진입 후 일정시간 후에 청산

6. 연속조회 또는 연속주문 제한에 걸리지 않기위해 delay 를 줄 때

7. 그 외 각족 알고리즘 전략에 활용


증권 API 에서 지수값을 실시간 데이터로 받기 시작하면 2 초에 한 번씩 수신이 되는데 이것은 훌륭한 타이머 역할을 한다. 실시간 지수 데이터에 기록된 시간은 거래소에서 사용되는 시간이고 다른 모든 증권 데이터들도 그 시간을 기준으로 동작하기 때문이다. 그래서 본인은 지수 데이터의 초단위가 '00' 초가 되는 순간 필요한 작업들을 수행한다.


이 훌륭한 타이머로 가능한 작업은 위 항목 중에 2 번에 해당된다. 안타깝게도 지수 타이머(?)는 장 시작과 동시에 작동하는게 아니고 장 시작시간 + 1 분, 즉 9 시 1 분부터 시작하고 파생상품 시장 종료 이전에(15시 정각) 끝나버리기 때문에 위 항목 중 1 번에는 적용이 안된다. 따라서 2 번을 제외한 모든 항목에서 이 SetTimer 함수는 아주 유용하게 쓰일것 같다. 참고로 2 번 이외의 항목들은 선물 실시간 데이터에 기록된 시간을 이용해서 구현했었다.

2013. 9. 27. 07:58

Cherry Picker 란?


정의 :

'증권 API 를 이용한 실시간 알고리즘 트레이딩' 및 '과거 틱데이터, 분데이터를 이용한 알고리즘 전략 시뮬레이션'을 수행하기 위해 개발된 라이브러리 (LIB 또는 DLL 형태)


이해하기 쉬운 정의 :

전략 아이디어만 몇 줄의 코드로 작성하면 나머지 모든 귀찮고 복잡한 처리들을 알아서 수행시켜주는 똘똘한 녀석. 여기서 말하는 '나머지' 일들이란...

(1) 증권사에 접속

(2) 전략에서 요구하는 어떠한 데이터든지 수량에 관계없이 실시간으로 자동연결

(3) 전략을 실시간으로 감시하다가 주문조건이 맞으면 자동으로 증권사에 주문

(4) 포지션 관리는 물론 복수의 전략을 포트폴리오로 단위로 묶어서 관리가 가능

(5) 실제 운용뿐 아니라 과거의 성과를 알아보기 위한 가상테스트가 가능

정도...


개발 시작 날짜 :

2011년 2월부터 현재까지


개발 언어 :

첫 반 년은 Java 로 개발하다가 그 후로 C++ 로 전환


기능(2013년 12월 12일 현재) :

* 데이터

    * 증권사 API 에서 제공하는 모든 실시간 정보 이용 가능 (알고리즘 트레이딩 카테고리의 '심볼리스트' 참조)

    * 과거데이터를 이용한 가상거래에서도 모든 데이터를 사용 가능

    * 전략에 사용되는 데이터 형태는 틱, 분, 시간, 일 등 모든 형태로 가공이 가능

* 함수

    * 모든 금융공학 관련 함수 이용 가능

    * 사용자 정의함수 추가 기능

    * 함수 내부에서 과거데이터 참조기능(average(close, 5) 형태)

    * 함수 내부에서 다른 함수의 재귀호출 가능

* 전략

    * 전략이란 전략에 사용되는 정보가 갱신될 때마다 수행되는 부분을 의미(TradeStation 과 동일한 형태)

    * 전략의 기본형태는 데이터 처리 -> 조건분석 -> 진입 or 청산

    * 같은 포트폴리오에 포함된 전략끼리는 포트폴리오 정보를 공유

    * 복수의, 다양한 형태(틱, 분 등)의 데이터를 하나의 전략에서 사용 가능

* 주문

    * 증권사 API 를 통해 복수의 종목을 동시에 주문 가능

    * 과거데이터를 이용한 가상거래시에는 프로그램 내부에서 주문 및 체결을 가정함

    * 포트폴리오 내부의 전략들의 주문이 상쇄되는 주문일 경우 무효처리되도록 감지

* 조회 및 전략 모니터링

    * CUI 형태로 전략 및 포트폴리오 상황 모니터링이 가능

    * CUI 형태로 체결, 미체결, 잔고, 손익결과 조회 가능


사용자 인터페이스 :

아래 5 개의 클래스가 사용자가 취급해야하는 클래스의 전부다.


Symbol : 이 클래스에 데이터를 등록한다.

Strategy : 이 클래스를 파생시킨 후 'run' 함수를 재정의 하면 재정의된 함수는 특정 타이밍마다 수행된다.

SymbolMgr : Symbol 과 Strategy 를 이 클래스에 등록시켜 관리한다.

TFile : 백테스트시 과거데이터 파일의 경로를 이 클래스에 세팅 후, Symbol 에 등록한다.

XingManager : 증권사와 데이터 통신을 담당한다.


블로그를 만든 이유


이 블로그는 제가 현재 개발하고 있는 Cherry Picker 라는 트레이딩 및 분석툴의 개발과정과 Cherry Picker 를 이용한 시장분석 및 트레이딩 성과 등을 포스팅하므로서 저와 같이 시스템 트레이딩 및 트레이딩툴 개발에 관심이 있는분들과 정보를 공유하는 목적을 가지고 있습니다.


블로그 메뉴 소개


* 알고리즘 트레이딩 -> Cherry Picker 를 이용한 알고리즘 트레이딩 및 분석 예제

    * 전략구현 프로세스 -> 빠른 전략 구현을 위한 전략구현 프레임(전략 구현 가이드)

    * 심볼 리스트 -> 현재 Cherry Picker 에서 전략 구현 시 사용 가능한 심볼 정보

    * (1) 알고리즘 트레이딩 전략 1

    * (2) 알고리즘 트레이딩 전략 2

    * (3) ...

* Cherry Picker 란? -> Cherry Picker 에 대한 설명

    * Cherry Picker 소개 -> Cherry Picker 및 블로그에 대한 소개

    * Cherry Picker 샘플 -> Cherry Picker 의 사용 예

* Cherry Picker 개발 -> Cherry Picker 개발 정보

    * 일정 -> Cherry Picker 의 개발 일정

    * 개발노트 -> Cherry Picker 개발에 관련된 내용

* TSimulator 개발 -> Cherry Picker 이전명칭으로 그에 대한 개발 정보 (업데이트 종료)

    * TSimulator 소개 -> TSimulator 에 대한 설명

    * 일정 -> TSimulator 의 개발 일정 (업데이트 종료)

    * 개발노트 -> TSimulator 개발에 관련된 내용 (업데이트 종료)

* 전략 시스템 성과 -> TradeStation 및 Cherry Picker 를 이용하여 테스트한 실제 운용전략 성과

    * 전략 pool -> 수익여부와 관계없이 백테스트한 모든 전략들의 특징과 성과를 모아뒀다.

    * 실거래를 위한 성과기준 -> 전략 pool 에서 실거래 가능한 전략을 추출하기 위한 성과기준

    * 실거래 전략 xxx -> 실거래를 위한 성과기준을 통과한 전략들의 상세 성과를 보고

    * 실거래 전략 포트폴리오 -> 실거래 전략들로 구성된 포트폴리오의 성과

* 일기 -> 가끔 생각하는 이야기들

* 잡동사니 -> 개인적인 관심사

    * 기타 -> 기타정보

2013. 9. 24. 08:10

Cherry Picker 에서 전략, 심볼, 심볼 매니저를 사용하는 방법은 다음과 같다.

각 과정의 설명과 함께 소스코드를 넣어봤다.


1. SymbolManager 객체 생성

2. SymbolManager 에 MaxBarsBack, 최초자본금, 결과파일저장경로 등을 세팅

3. Symbol 객체 생성 및 속성을 초기화

4. SymbolManager 에 Symbol 을 추가

5. Strategy 객체 생성

6. SymbolManager 에 Strategy 를 추가

=== 데이터 수신 대기상태 ===

7. 데이터를 수신하면 Symbol 에 업데이트

8. SymbolManager 의 메서드인 run 을 수행시키면 세팅된 Strategy 들이 한 번의 루프를 수행


소스코드는 대략 다음과 같다.


/* SymbolManager 객체 생성 및 세팅 */

SymbolManager sSymbolMgr;

sSymbolMgr.setResPath( "C:\res\..." );

sSymbolMgr.setResName( "File Name" );

sSymbolMgr.setMaxBarsBack( 500 );

sSymbolMgr.setBarsCnt4Loop( 50 );

sSymbolMgr.setInitialCapitlal( 10000000 );


/* Symbol 객체 생성 및 초기화 (Tick Symbol 두 개 생성)*/

Symbol sSymbolOne( KOSPI200_FUT, ETRADE, TICK, 1 );

Symbol sSymbolTwo( KOSPI200, ETRADE, TICK, 1 );


/* SymbolManager 에 Symbol 을 추가 */

sSymbolMgr.addSymbol( &sSymbolOne );

sSymbolMgr.addSymbol( &sSymbolTwo );


/* Strategy 객체 생성 */

TrendStrategy       sStrategyOne;

ArbitragteStrategy sStrategyTwo;


/* SymbolManager 에 Strategy 를 추가 */

sSymbolMgr.addStrategy( &sStrategyOne );

sSymbolMgr.addStrategy( &sStrategyTwo );


.

.

.


KOSPI200 선물 데이터 수신시 수행되는 CallBack 함수 (위에서 생성한 객체들은 클래스의 멤버변수라고 가정)

void CallBackFunction( ... )

{

    /* 수신된 가격 및 기타 정보를 세팅 */

    sSymbolOne.setPrice( 111 );

    sSymbolOne.setCVolume( 222 );

    .

    .

    .

    sSymbolOne.updateBar();


    /* Symbol 이 Bar 를 생성할 타이밍인지 체크 (분봉의 경우 Symbol 정보세팅 이전에 수행되어야 함)*/

    if( sSymbolOne.isBarOver() == true )

    {

        /* Tick 봉 생성 및 틱 count 초기화 */

        sSymbolOne.createBar();

        sSymbolOne.reset();


        /* Symbol 이 업데이트 됐으므로 전략 수행 (기타 처리들을 해줘야 하지만 여기선 간략화 했다) */

        sSymbolMgr.run();

    }

}



수도코드는 대략 위와 같다. 여기서 sSymbolMgr 객체에 추가된 전략들(sStrategyOne, sStrategyTwo)로 포트폴리오를 구성했다고 가정하고 통계값이 갱신될 때마다 sSymbolMgr 객체 내부에서는 포트폴리오 통계값을 파일에 기록한다. 현재 기록되고 있는 통계값은 다음과 같으며 얼마든지 필요에 의해 확장될 수 있다.


전략 포트폴리오 관련 통계값

* PfoNetProfit : 포트폴리오 총 순수익

* PfoGrossProfit : 포트폴리오 총 수익

* PfoGrossLoss : 포트폴리오 총 손실

* PfoInitialCapital : 포트폴리오 최초 자본금(고정)

* PfoCurrentCapital : 포트폴리오 자본금 잔고

* PfoMaxCapital : 포트폴리오 최고 자본금

* PfoDrawDown : 포트폴리오 DD

* PfoMaxDrawDown : 포트폴리오 MDD

* PfoPercentDrawDown : 포트폴리오 % DD

* PfoPercentMaxDrawDown : 포트폴리오 % MDD


위의 통계값들은 포트폴리오 관점 뿐만 아니라 개개 전략 관점에서도 각각 전략 객체들이 자신의 값을 가지고 있다. 


여기서 의문점이 들 수 있다. 서로 다른 SymbolManager 들의 전략들끼리 포트폴리오를 구성하고 싶을 때도 분명 있을 것이다. 아니 반드시 있다. 그럴 경우에는 다음 함수를 사용하면 된다.


double sPfoNetProdit;


sSymbolMgrOne.setPfoNetProfit( &sPfoNetProfit );

sSymbolMgrTwo.setPfoNetProfit( &sPfoNetPfofit );


위와 같이 통계값을 저장하고자 하는 변수를 생성하고 각 SymbolManager 에 세팅을 해주면 SymbolManager 들은 내부 변수가 아닌 외부 변수에 통계값을 저장하기 시작한다.


이상으로 전략 포트폴리오 개념 도입에 대한 개발노트를 마치겠다.

2013. 9. 19. 21:05

시스템 전략이 완성되면 성능을 알아보기위해 과거데이터를 이용한 백테스트를 수행한다. 트레이드 스테이션에서 백테스트를 수행하면 Performance Report 가 만들어지는데 다음과 같이 생겼다.





이런 화면 외에도 아주 많은 화면들을 통해서 백테스트된 전략의 성과를 여러 측면에서 평가할 수 있다.


여러 성과측정 도구들이 있지만 가장 먼저 눈에 들어오는건 Total Net Profit 이다. 시스템 전략의 제 1 의 목적이 수익을 발생시키는 것이기 때문이다. 이 외에도 중요한 성능지표로서 Percent Profitable, Profit Factor, 등 다른 여러 측정도구도 함께 참조한다. 그리고 다음과 같은 항목이 있다.





수익의 최근 고점에서부터의 손실폭 중 최대치(Max Draw Down... 줄여서 MDD)을 아주 중요하게 보는데, 쉽게 풀이하자면 이 전략에서 수익없이 손실이 나는 최대 금액이라고 얘기할 수 있다. 그 최대 손실액이 발생하기 시작하는 시점이 해당 전략을 이용한 시스템 트레이딩의 시작시점이 될 수도 있는데, 이 경우 투자자는 트레이딩을 시작하자마자 MDD 만큼의 손실을 입다는 말이된다. 당연히 최초자본금액이 MDD 보다 작다면 파산을 하게되므로 큰 MDD 는 트레이딩 내내 불안감을 떨칠 수 없으며 작은 MDD 는 비교적 여유를 가질 수 있는 심리적 요인이 된다. MDD 를 줄이려는 노력은 성공적인 전략을 개발하기 위해 반드시 필요하다.


이번 테스트에서는 복수의 전략으로 포트폴리오를 구성할 경우 각 전략들의 상관관계가 포트폴리오의 MDD 에 미치는 영향을 분석해본다.


실증분석에 앞서 간단하고 극단적인(?) 예를 들어 테스트 시나리오를 설명하겠다. '전략 a' 가 있고 최초자본금은 10 이고 다음과 같이 잔고의 변화가 있다고 가정한다.


 잔고

시간 1 

시간 2 

시간 3 

시간 4 

시간 5 

전략 a

10

11 (고점 갱신)

10


이 경우 DD(Draw Down) 값은 다음과 같이 변한다. (DD 공식 : 최근 최고 잔고에서 현재 잔고를 차감)


 Draw Down

 시간 1

시간 2 

시간 3 

시간 4 

시간 5 

 전략 a

0

0 (고점 갱신) 

3 (MDD)

1


위 두 표를 그래프로 보면 다음과 같다.




(X출 : 기간, Y축 : 잔고 및 DD)


시간 1 ~ 5 까지의 MDD 는 '3' 이다. 이 경우 잔고가 11 까지 상승한 후 MDD 가 발생하여 잔고가 8 까지 하락했지만 '시간 1' 에 MDD 가 발생했다면 잔고가 7 까지 하락하게된다.


이제 전략을 하나 더 추가하여 총 2 개의 전략으로 구성된 전략 포트폴리오를 만들 것이다. 추가할 후보전략 2 개는 다음과 같은 잔고흐름을 가진다.


잔고

시간 1 

시간 2 

시간 3 

시간 4 

시간 5 

전략 b 

10

8

11 (고점 갱신)

8

10

전략 c 

10 

11 (고점 갱신)

12 (고점 갱신) 

10


'전략 b' 는 '전략 a' 와 완전히 같은 움직임을 보인다. '전략 c' 는 완전히 반대의 움직임을 보인다. 상관관계 분석결과는 다음과 같다. (로그수익률의 상관관계)


상관계수 

전략 a

전략 b 

전략 c 

전략 a

1

 

 

전략 b 

1

1

 

전략 c 

-0.96

-0.96

1


포트폴리오 이론에 따르면 안정적인(표준편차가 낮은) 주식 포트폴리오를 구성하기 위해 기존 포트폴리오와의 상관계수가 높은, 즉 포트폴리오와 같은 움직임을 가진 주식 종목의 편입을 피하고 상관계수가 낮은 주식을 편입해야한다. 어느 시점의 수익률 부호가 반대라면 포트폴리오의 변동성이 커지는것을 막을 수 있기 때문이다.

마찬가지로 어떤 시스템 전략 포트폴리오가 낮은 수익률 상관관계를 가진 전략들로 이루어져있다고 가정하자. 어떤 시점에 한 전략이 손실을 입어 DD 가 발생하는 상황일 때 다른 전략은 수익을 내어 DD 발생을 억제시킬 수 있기때문에 결과적으로 각 전략의 MDD 의 합보다는 낮은 포트폴리오 MDD 를 기대할 수 있다. 전략 a, b 로 구성된 포트폴리오와 전략 a, c 로 구성된 포트폴리오의 잔고흐름과 MDD 는 다음과 같다.


포트폴리오 잔고 

시간 1 

시간 2 

시간 3 

시간 4 

시간 5 

전략 a + b

20

16

22

16

20

전략 a + c

20

19

19

20

20


포트폴리오 DD

시간 1 

시간 2 

시간 3 

시간 4 

시간 5 

전략 a + b

0

4

0

6 (MDD)

2

전략 a + c

0

(MDD)

1

0


그래프로 표현하면 다음과 같다.


(X축 : 기간, Y축 : 잔고 및 DD)


상관계수가 최대값인 1인 전략과 포트폴리오를 구성한 경우 포트폴리오 MDD 는 각 전략 MDD 의 단순 합인 6(= 3 + 3) 이 됐고 상관계수가 낮은(-0.96) 전략과 포트폴리오를 구성한 경우 포트폴리오 MDD 는 1 로 낮아졌다. 상관계수 최소값인 -1 일경우 포트폴리오 MDD 는 0 이 될것이다. 


실증분석을 시작하겠다.


위 예제에서 '전략 a' 에 해당하는 전략을 먼저 선정해야한다. 이전 글인 '테스트 전략 - 2' 편에서 사용했던 필터가 있는 이동평균 전략을 다시 사용하겠다. 전략구현 프로세스는 2 번째 version 을 따른다.


==============================================================================================

1. 전략을 구현할 때 필요한 데이터(symbol)는 무엇인가?

  • KOSPI200 선물

2. 필요한 데이터 중 실시간으로 변하는 데이터와 그렇지 않은 데이터는 무엇인가?

  • 실시간으로 변하는 데이터

        Symbol Data 1 : KOSPI200 선물

  • 실시간으로 변하지 않는 데이터

        없음

3. 기초자본금은 얼마인가?

  • 10,000,000 원

4. (백테스트인 경우) 테스트 기간은?

  • 2004년 08월 02일 ~ 2005년 03월 02일 (120일)

5. 전략에서 사용될 symbol 은 분봉인가 틱봉인가?


    Minute Bar


6. 전략에서 사용될 symbol 의 time interval 은?


    Symbol Data 1 : KOSPI200 선물 (5 Minute Bar)


7. 첫 전략루프를 수행할 때 필요한 과거봉 개수는?


    50 개


8. 최근 몇 개까지의 과거봉을 참조할 수 있나?


    300 개


=== Strategy Flow ===


1. 장 시작 후 바로 전략을 수행시킬 것인가? 일정하거나 상황에 따라 다른 term 을 두고 수행시킬 것인가?


    바로 시작


2. 장 종료시까지 전략을 수행시킬 것인가? 일정하거나 상황에 따라 다르게 전략을 중지시킬 것인가?


    장 종료까지 수행


3. 거래대상은 무엇인가?


    Symbol Data 1


4. 거래계약수는 몇 개인가?


    1 개


5. 매수(매도) 준비신호는?


    5 이동평균이 10 이동평균을 상회(하회) 할 때


6. 매수(매도) 신호는?


    3 이동평균이 5 이동평균을 상회(하회) 할 때


7. 환매도(환매수) 신호는?


    진입 후 10 개 봉이 지나면 청산

==============================================================================================




먼저 이 전략의 수익과 DD 그리고 MDD 를 그래프로 표현해보겠다.


(X축 : 기간, Y 축 : 잔고, DD, MDD)


'전략 a' 의 MDD 는 7,500,000 원이다. 이제 전략 포트폴리오를 구성하기 위해 이번에는 5 개의 후보전략을 사용하겠다. 후보전략들의 잔고는 다음과 같다.


(X축 : 기간, Y 축 : 잔고)


하나하나 구별하기는 힘들지만 다양한 수익률 곡선을 그리는 전략들이며 마지막에는 잔고가 10,000,000 원을 넘어 결국 수익으로 끝나는 전략들임을 알 수 있다. 각 전략들의 DD 를 그래프로 그려보면 다음과 같다.


(X축 : 기간, Y 축 : DD)


역시 알아보기는 힘들다. 각 선의 최고점이 해당 전략의 MDD 이다.


이제 본격적인 분석을 위해 각 전략의 로그수익률의 상관관계를 분석해보겠다.



 상관계수

 전략 a 

 전략 b

 전략 c

 전략 d

 전략 e

 전략 f

 전략 a 

 1

 

 

 

 

 

 전략 b

 0.195

 1

 

 

 

 

 전략 c

 -0.063

 -0.051

 1

 

 

 

 전략 d

 0.147

 0.652

 -0.147

 1

 

 

 전략 e

 0.233

 0.411

 -0.028

 0.437

 1

 

 전략 f

 -0.006

 0.531

 -0.069

 0.401

 0.178

 1


파란색으로 칠해진 부분이 '전략 a' 와의 상관관계다. 


상관관계가 높은 순으로 보면 e - b - d - f - c 순이다. 여기서는 상관관계가 높을수록 MDD 감소비율이 작을 것으로 가정했으므로,'전략 a' 와 포트폴리오를 구성했을 때 구성전략의 MDD 의 단순합에서 포트폴리오 MDD 로의 차감비율이 가장 작은 순서 역시 e - b - d - f - c 순이 되어야 한다. 다음은 각 조합의 포트폴리오 분석결과를 나타낸 표다.


전략 a 와의 상관계수

MDD 단순합

포트폴리오 MDD

MDD 차감비율

전략 a+a

1

15,000,000

15,000,000

0%

전략 a+b

0.195

13,075,000

10,500,000

19.69%

전략 a+c

-0.06

10,275,000

4,875,000

52.55%

전략 a+d

0.148

14,850,000

10,375,000

30.13%

전략 a+e

0.234

10,875,000

8,875,000

18.39%

전략 a+f

-0.007

14,150,000

8,475,000

40.10%


기대했던대로 전략 a 와의 상관관계가 작은 포트폴리오가 MDD 차감비율이 커지는 결과가 나왔다. '전략 a' 와의 상관관계를 높은 순으로 MDD 차감비율을 나타낸 그래프는 다음과 같다.



다음 그래프는 가장 많은 MDD 비율 하락을 보여준 전략 a+c 조합의 포트폴리오의 DD, MDD, 단순 DD 합, 단순 MDD 합을 보여준다.


(X축 : 기간, Y 축 : 포트폴리오 DD, MDD, 단순합 DD, MDD)


위 그래프를 보면 시간이 흐를수록 포트폴리오 MDD 와 단순 MDD 합의 차이가 커짐을 알 수 있고, DD 의 흐름을 비교해보면 (특히 마지막 부분) 단순합 DD 는 상승하는 반면 포트폴리오 DD 는 억제되고 있는듯한 움직임이 보인다.


공교롭게도 모든 부분이 예상과 일치했지만 무수히 많은 전략들을 같은 방식대로 조랍해봐야하며 그런 과정에서 이번 분석의 헛점들도 많이 발견될 것이다.



결론


전략 포트폴리오 구성시에 구성전략들의 상관계수가 높으면 포트폴리오 구성에서 오는 MDD 감소비율은 작아지는 경향이 있고 반대로 구성전략들의 상관계수가 낮으면 포트폴리오 구성에서 오는 MDD 감소비율이 커지는 경향이 있다.

대표적으로는 추세전략과 비추세전략의 포트폴리오 구성이 이런 구성에서 이득을 얻는데, 승률이 낮은 추세전략이 손실을 쌓아가는 동안 높아지는 Draw Down 을 높은 승률의 비추세전략이 상쇄시키면 포트폴리오 Draw Down 역시 낮게 유지할 수가 있다. 이상으로 전략 포트폴리오를 구성하는 전략들의 상관관계가 포트폴리오 MDD 에 미치는 영향에 대한 분석을 마치겠다.


prev"" #1 next