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 티스토리 가입하기!
'TS'에 해당되는 글 14건
2013. 9. 23. 16:50

CherryPicker 가 기본 기능을 하기 시작함에 따라 시장분석 작업도 동시에 진행하고 있다. 시장 데이터를 분석하고 결론을 내는 작업에 푹 빠진 탓에 새로운 기능이 추가됐음에도 불구하고 포스팅을 게을리 해왔다... 밀린 일정보고를 하겠다.


이전 일정보고에서 완료되지 않은 목록 중 다음 두 가지가 있었다.


1. 멀티 틱 심볼 데이터를 이용한 HFT 전략 분석

2. 틱데이터와 분데이터를 결합한 멀티 심볼을 사용하는 전략 테스트


'Cherry Picker 시장분석' 카테고리에 '테스트 전략' 이라는 하위 카테고리를 만들었는데 위 두 가지를 그 카테고리에서 테스트할 예정이다. 이미 1 번은 '테스트 전략 - 1' 에서 테스트를 진행했다.


'테스트 전략' 카테고리는 최소 일주일에 한 번 이상 업데이트할 생각이다.


일정보고를 시작하겠다.


전략 포트폴리오 개념의 도입


Cherry Picker 에서는 Symbol Manager 에 Symbol 을 추가하고 Strategy 를 추가한다. Symbol Manager 가 TradeStation 의 Chart Window 와 같은 개념이고 Symbol, Strategy 는 TradeStation 과 명칭과 의미가 같다. 전략 포트폴리오는 아무런 설정이 없다면 Symbol Manager 에 포함된 Strategy 들이 그 구성원이 된다. 하지만 따로 성정을 해주면 서로 다른 Symbol Manager 의 Strategy 들끼리도 하나의 전략 포트폴리오로 엮을 수가 있다. 이렇게 전략 포트폴리오의 개념을 도입했고, Strategy 집단의 관리를 할 틀을 만들었다.


전략 포트폴리오의 통계값 기록 시작


개개의 전략의 성과는 당연하고 포트폴리오 단위의 성과를 파일로 기록하는 로직을 넣었다. '테스트 전략' 카테고리에 '테스트 전략 - 3' 에는 이를 활용한 분석이 있으니 참고하면 된다. 이로서 순수익 뿐만이 아니라 MDD 나 변동성 같은 성질들을 조합해서 포트폴리오를 만들 수 있게 되어 더 나은 종합 성과를 낼 기반이 마련됐다.


최근월물 선물 호가 정보를 기록하기 시작


현재 수신 및 기록하고 있는 데이터는


    a. KOSPI 200 지수 정보 (9시 1분부터 2초마다 수신)

    b. KOSPI 200 최근월물 선물 체결정보 (9시부터 체결이 발생할 때마다 수신)


인데, 굳이 '정보' 라고 표현한 이유는 증권사 API 에서 보내주는 데이터는 여러 정보들이 같이 딸려오기 때문이다. 예를 들어 KOSPI 200 최근월물 선물 체결정보에는 체결 가격 뿐만 아니라 수량, 매수 1호가, 매도 1호가, 전날대비 상승폭, 당일 시고저가 등 여러 체결관련 정보들이 포함돼서 온다. 이 정보들을 모두 기록하고 있다.

추가로 최근월물 선물 호가정보를 기록하기 시작했다. 이 정보는 매수 또는 매도 1~5 호가의 정보를 포함하며 호가 정보가 하나라도 바뀌면 바뀐 정보를 포함한 모든 정보가 통째로 수신된다. 체결정보의 몇 배의 양이 된다. 


2013년 9월 이내에 최근월물, 선물 뿐만이 아닌 KOSPI 200 지수를 기초자산으로 하는 모든 현존 파생상품의 데이터를 기록하기 시작할 것 같다.


옵션 전략을 위한 전략 프레임의 디자인 시작


현재 전략 프레임은 첫 번째 심볼이 거래대상이 되는 한 가지 상품을 사고파는 전략 프레임이다. 이는 TradeStation 과 동일하다. 선물 거래를 뛰어넘어 옵션 거래, 선물 + 옵션 거래도 가능한 프레임을 디자인해야한다. 인터페이스는 Buy/Sell 함수 인자에 종목코드를 추가로 집어넣는 방법으로 생각하고 있다. 


전략에 활용 가능한 Symbol 정보 카테고리 추가


현재 Cherry Picker 에서 사용 가능한 Symbol 정보를 게시하려고 한다. 현재는 KOSPI 200 지수, 최근월 선물 관련정보밖에 없지만 점차 확대해 나가고 10월 중으로 선물 옵션 관련 모든 정보를 추가할 것이고 올해 안으로 API 에서 얻을 수 있는 모든 정보를 추가할 예정이다.

'TSimulator 개발(종료) > 일정(종료)' 카테고리의 다른 글

TSimulator 일정 종료  (0) 2013.09.23
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 에 미치는 영향에 대한 분석을 마치겠다.


2013. 8. 3. 03:33

저번 주 월요일(2013년 07월 29일)부터 오늘까지 2주간의 실시간 데이터를 수집하고 실시간 데이터를 사용한 전략을 수행했다. 평일에 회사 업무를 마치고 집에 돌아오면 CherryPicker 폴더에는 다음과 같은 파일들이 기록되어 있다.


1. 과거 데이터 파일

    a. INDEX_MIN.txt : 코스피 200 지수의 1 분 봉데이터 기록

    b. INDEX_TICK.txt : 코스피 200 지수의 틱데이터 기록

    c. FUTURES_MIN.txt : 코스피 200 지수 선물 최근월물의 1 분 봉데이터 기록

    d. FUTURES_TICK.txt : 코스피 200 지수 선물 최근월물의 틱데이터 기록

2. 전략 수행 로그 파일

   (하나의 전략은 1분, 3분, 5분 의 time interval, 1틱, 3틱, 5틱의 tick count 별로 수행됐다.)


    a. StrategyTest_1.txt

    b. StrategyTest_2.txt

    .

    .

    f. Investra_2_1.txt

    g. Investra_2_2.txt

    .

    .



'과거 데이터 파일'은 실시간 데이터를 수신할 떄마다 바로바로 기록을 하는 틱데이터 파일과 매 분 00초가 될때마다 기록을 하는 1 분 봉데이터 파일이 있다. 지금은 두 종류의 데이터만 취급을 하지만 검증기간이 끝나면 종목코드를 파일 이름으로 모든 과거데이터를 기록할 생각이다.

'전략 수행 로그 파일'은 등록한 전략들의 주문정보와 매 분마다 전략 속성들을 기록한 파일이다. 정확한 검증을 위해 될수있으면 많은 속성들을 기록하려고 했다. 임의의 파일 일부분을 보면 다음과 같은 형태로 로그가 기록된다. 


BWTS_BollingerBanditPro.txt 의 13 시 29 분 00 초에 기록된 로그...


1130802.00:1329.00,ExitShortNextStop,Short liq,ALL, 250.70

-------------------------1130802.00:1329.00-------------------------

=== Position Info. ===

 MarketPosition:  -1.00

 BarsSinceEntry:   5.00,EntryPrice: 250.55,AvgEntryPrice: 250.55

 BarsSinceExit:   0.00

 CurrentShares:   1.00,CurrentContracts:   1.00

 EntryDate:1130802.00,EntryTime:1323.00

 ExitDate:   0.00,ExitTime:   0.00

=== Performance Info. ===

 NetProfit:-525000.00,OpenPositionProfit:125000.00

 GrossProfit:250000.00,GrossLoss:-775000.00

 TotalTrades:  14.00,PercentProfit:  14.29

 NumWinTrades:   2.00,NumLosTrades:  12.00

-------------------------1130802.00:1328.00-------------------------

=== Position Info.(1) ===

 MarketPosition(1):  -1.00

 BarsSinceEntry(1):  52.00,EntryPrice(1): 251.05

 BarsSinceExit(1):  11.00

 EntryDate(1):1130802.00,EntryTime(1):1236.00

 ExitDate(1):1130802.00,ExitTime(1):1317.00

-------------------------1130802.00:1327.00-------------------------

=== Position Info.(2) ===

 MarketPosition(2):  -1.00

 BarsSinceEntry(2):  58.00,EntryPrice(2): 251.10

 BarsSinceExit(2):  57.00

 EntryDate(2):1130802.00,EntryTime(2):1230.00

 ExitDate(2):1130802.00,ExitTime(2):1231.00

--------------------------------------------------------------------


현재 봉에서 일어난 주문 정보를 포함하여 현재 봉의 포지션 정보, 과거 두 개의 봉들의 포지션 정보도 같이 기록한다. 기록되는 데이터의 양이 상당히 많지만 TS 를 벤치마크하는 과정에 많은 도움이 됐다.


이제 본론으로 들어가겠다. 지난 2주간 마련된 과거데이터와 전략 로그를 가지고 이것들이 기대되는 결과인지 아닌지를 판단하기위해 수행한 검증법은 다음과 같다. 사람에 따라 다소 불필요하다고 생각되어질 수 있다.



1. 1 분 봉데이터 결과 검증(1)

기록된 1 분 봉데이터가 CherryPicker 로직에 맞게 기록됐는지 검증하는 단계이다. 틱데이터 파일들을 모두 읽어들여 발생 순서대로 처리하며 1 분 봉데이터를 새로 생성시킨다. 이 때 기록된 봉데이터와 실제로 기록된 봉데이터 파일이 정확하게 일치하면 성공이다.


2. 1 분 봉데이터 결과 검증(2)

기록된 1 분 봉데이터가 올바르게 기록됐는지 검증하는 단계이다. 증권사 HTS 에서 얻는 봉데이터가 정확하다고 가정한다. HTS 에서는 쉽게 1 분 봉데이터를 얻을 수 있는데, HTS 에서 가져온 봉데이터와 CherryPicker 에서 기록된 봉데이터가 일치하면 성공이다.


3. 전략 로그 검증(1)

기록된 전략 로그파일의 내용이 CherryPicker 로직에 맞게 기록됐는지 검증하는 단계이다. 이 검증은 TS 를 잘 벤치마크 했는지에 대한 검증이 아니다. 실시간 데이터가 전략에 잘 전달이 됐고 주문 시그널이 CherryPicker 로직에 의해 정상적으로 발생됐는지를 확인하는것이 목적이다. 틱데이터 파일을 모두 읽어들여 종목구분없이 모든 틱데이터의 발생 순서대로 전략들에 전달하고 시그널을 받아 따로 로그를 만든다. 이 때 만들어진 로그파일의 내용과 기존 전략 로그파일의 내용이 완벽하게 일치하면 성공이다.


4. 전략 로그 검증(2)

TS 를 정확하게 벤치마킹 했는지 검증하는 단계이다. CherryPicker 에서 백테스트를 수행할 때 결과의 신뢰도를 높이기 위해서는 TS 백테스트 결과와 일치해야한다. 이미 60여개 전략이 10년동안 수행한 결과와 정확히 일치시킨 상태로 신뢰수준은 높지만 만에 하나를 대비하고 신뢰성 확인 차원에서도 이 작업은 앞으로도 아주 중요할 것이다.

실시간 전략은 봉의 움직임을 가정하지 않는다. 하지만 TS 의 분봉 백테스트는 봉의 움직임을 가정한다. 그러므로 이 단계의 검증 역시 봉가정을 사용한다. 정확하게 일치해야할 세 종류의 전략 로그는 다음과 같다.


a. 틱데이터를 사용한 전략 로그 (CherryPicker 의 REAL_MODE)

b. 1 분 봉데이터를 사용한 전략 로그 (CherryPicker 의 TEST_MODE)

c. TS 에서 1 분 봉데이터를 읽어들여 수행한 전략 로그


P.S. 본인은 TS 에 실시간 데이터를 feeding 할 수 있는 환경이 아니라 봉가정을 사용하지 않은 TS 전략 결과를 얻을 수 없었다. 그래서 TS 벤치마킹을 위한 자료는 TS 백테스트 자료로 제한한다.



이상 지난 2 주간 본인이 해왔던 나름 강력하다고 주장하는 검증방법이다.

2013. 7. 17. 18:24

직전 일정에서 구현하겠다고 했던 세 가지는 다음과 같다.


1. tick bar 의 생성

2. 직전 봉에서 접수된 주문을 실시간로 체결하는 기능 추가

3. 두 개 이상의 tick bar 또는 tick bar 와 분봉을 한 전략에서 동시에 사용하는 기능 추가


그리고, 위 세 가지를 구현하면 그 다음 구현에 포함되는 세 가지는 다음과 같다.


4. API 에서 받아온 틱데이터를 REAL 모드 전략에 전송

5. tick 멀티심볼을 이용한 간단한 HFT 전략 수행 및 검증

6. 분봉 안에 틱데이터 정보를 넣어 봉가정 없이 정확한 분봉 백테스트가 가능하게 함


지난 3주간 Cherry Picker 에 구현해 놓은 부분을 빨간 색으로 표시했다.

그럼 구현된 부분과 구현되지 않은 부분에 대한 간략한 설명을 하겠다.


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


1. tick bar 의 생성

구현 자체는 아무런 어려움이 없었다. 시간에 관계없이 지정된 수 만큼의 틱이 쌓이면 봉으로 만들어서 전략에 적용하면 끝이기 때문이다. TS 에서의 틱전략 결과와의 비교는 구조적 결함은 없었기 떄문에 비교적 순조롭게 통과했다.


2. 직전 봉에서 접수된 주문을 실시간로 체결하는 기능 추가

이 기능은 bar assumption 없이 실제로 들어오는 틱에 의해 주문이 체결되는 기능이다. 이 기능을 사용하려면 틱데이터 정보가 있어야한다. OHLC 정보만으로는 bar assumption 만으로만 체결 순서를 짐작해야한다. 실제 거래를 하기위해 반드시 필요한 기능이다. TS 를 실시간으로 돌릴 때는 TS 역시 bar assumption 을 사용하지 않고 이 방법으로 주문을 체결시킨다. (밑에 6번에서 설명하지만 bar assumption... 굉장히 잘 만든 가정같다.)


3. 두 개 이상의 tick bar 또는 tick bar 와 분봉을 한 전략에서 동시에 사용하는 기능 추가

TS 에서 지원하지 않는 기능이다. Cherry Picker 는 기본적으로 이 기능이 가능하게끔 설계되었다. 하지만 기능이 정확하게 동작했는지 검증하기에 많은 시간이 걸리므로 일단은 keep 해뒀다. 이 기능은 Cherry Picker 를 개발하기 시작한 이유중 하나에 해당하는 기능이니만큼 신중을 가하고싶다. 8월부터 구현을 시작할것 같다.


4. API 에서 받아온 틱데이터를 REAL 모드 전략에 전송

이 기능은 지난 주말동안 구현했고 그저께인 월요일부터 회사에서 몰래(?) 테스트중이다. 예전 진행했던 TTrader 프로젝트의 주기능인데 Cherry Picker 로 통합된 이후에 처음 코드를 다시 들여다봤다. 최적화 작업을 조금 해 주고 어렵지 않게 symbol, symbol manager 에 연결할 수 있었다. 전략을 하나만 적용시켜봤는데 사진과 같이 무리없이 데이터가 잘 들어오고, 봉이 잘 생성되고, 전략이 잘 수행되고, 주문도 잘 체결되는걸 보니.. 흐믓.

아무리 데모전략이지만 첫 거래 10분만에 -25 만원... 손절이 잘 되고 있다 :)

약간의 설명은 jisu 로 시작한 줄은 1분이 갱신되고 처음으로 들어온 데이터가 KOSPI200 이라는 말이고 futures 로 시작한 줄은 1분이 갱신되고 처음으로 들어온 데이터가 KOSPI200 선물이라는 말이다. 그냥 디버깅 코드이다. 




5. tick 멀티심볼을 이용한 간단한 HFT 전략 수행 및 검증

지금은 intraday bar 전략을 실시간 테스트중인데, 별 문제가 없으면 7/22 (다음주 월) 부터 테스트에 들어갈 것이다.


6. 분봉 안에 틱데이터 정보를 넣어 봉가정 없이 정확한 분봉 백테스트가 가능하게 함

이 기능은 좋다! TS 에 없는 기능인데, 백테스트시에 틱정보만 있으면 분봉 전략이라고 해도 bar assumption 을 사용하지 않고 틱데이터에 따라 체결처리를 할 수 있다. '분봉전략의 백테스트는 봉가정이 완벽하지 않기 때문에 정확하지 않다.' 는 말에 조금은 반박할 수 있게 됐다. 물론 그 구하기 어려운 틱 정보가 있어야만한다.:)

틱 정보가 있다면 TS 에서도 이 기능을 구현 자체는 가능하다. 틱 전략코드를 잘 수정하고 주무르면 가능하기는 한데 Cherry Picker 에서는 분봉전략 코드를 수정할 필요가 없이 실제 체결순서 여부를 정확히 알 수 있다.

물론 그 시장에 미치는 나의 영향력이 없다는 가정하에서...



이상 블로그 갱신 끝.


P.S.

요즘 빠져있는 '이매뉴얼 더만' 이 쓴 '퀀트(영어제목은 My life as a quant)' 라는 책.. 좋다.

이 분야에 관심이 없는 사람은 재미가 없겠지만 퀀트들이 주로 어떤 일을 하는지 저명한 퀀트의 눈으로 간접경험이 가능하다.

'Cherry Picker 개발 > 일정(종료)' 카테고리의 다른 글

13년 12월 ~ 14년 1월 일정  (0) 2013.12.11
10~11 월 일정 (2013년)  (0) 2013.11.21
SetTimer 함수를 도입  (0) 2013.11.08
의미있는 일정  (0) 2013.06.17
새 통합 프로젝트 "Cherry Picker" 킥오프  (0) 2012.12.22
2013. 6. 17. 22:55

현재까지 구현이 완료된 내용을 크게 요약하면 다음과 같다.


1. 하나 또는 두 개 이상의 분봉 심볼을 이용한 전략 수행 가능.

2. 전략 수행모드는 두 가지( REAL, TEST )로 나뉜다.

    REAL 모드 : API (또는 csv 파일)에서 받은 틱데이터를 실시간으로 봉으로 만들며 전략을 수행한다.

                      TS 를 HTS 와 연동해 실제러 거래할 때를 생각하면 된다.

    TEST 모드 : csv 파일에서 추출한 데이터를 봉으로 만들어 미리 메모리에 올려놓고 전략을 수행한다.

                      TS 의 백테스트를 생각하면 되는데, REAL 모드보다 속도가 우월하다.

3. 전략 수행에 있어 신뢰성(TS 결과와의 일치성)을 높이기 위해 다음을 수행했다.

    * TS 전략 코드를 담은 '인베스트라', 'building winning trading systems with tradestation' 에 소개된

      모든 전략을 포함한 총 59 개의 전략을 TS 로 수행했고 매 봉마다 모든 변수값 및 reserved word 를

      로그로 남겼다.

    * 위와 같이 로그로 남긴 방대한 양의 데이터는 CherryPicker 에서 마찬가지로 59 개의 전략을 수행하며

      기록한 로그와 비교한다. 출력 템플릿은 두 프로그램에서 동일하게 구현했으므로 두 결과가 완벽하게

      일치해야만 신뢰성을 보장받을 수 있게된다.

    * 백테스트에 사용된 데이터는 코스피 200 선물 5년분이며

        * 하나의 심볼만 사용하는 전략은 1, 3, 5 분봉으로 각각 수행했다.

        * 두 개의 심볼을 사용하는 전략은 첫 번째 심볼은 1 분봉, 두 번째는 2 분봉으로 수행했다.

        * 세 개의 심볼을 사용하는 전략은 첫 번째 심볼은 1 분봉, 두 번째는 2 분봉, 세 번째는 3 분봉을 사용했다

        * 멀티심볼 수행시 각 심볼 데이터의 신뢰성 확보를 위해 2 개 그리고 3 개의 심볼을 사용하는 전략을

          만들고 각각의 심볼은 1, 2, 3, 5, 7, 10, 20, 30, 50 100 분봉에서 모든 경우의 수를 대입하여 수행했다.

        * 구현한 함수값의 신뢰성을 높이기 위해 매 분마다 모든 TS 함수만 수행하는 전략을 만들었다.

    * 위에 언급된 내용 이외에도 버그(로그 결과 불일치)가 발생하고 버그가 수정되면 그 즉시 테스트 케이스로

       재연시켜 다시는 같은 문제가 발생하지 않게 했다. 그리고 기능 추가 및 버그 수정시마다 전 테스트를 다시

       수행하여 다른 부분에 미치는 영향은 없는지도 체크한다.

    * 2013년 6월 17일 현재 상기 테스트는 모두 통과된 상태이며 전략 수행 로직의 완성도는 높다고 볼 수 있다.


이상이 현재까지의 CherryPicker 에 대한 설명이며 앞으로 약 한 달동안 추가할 기능은 다음과 같다.


1. tick bar 의 생성

    : tick bar 를 이용하면 intraday bar 또는 daily bar 에 비해 다이나믹한 전략 구현이 가능하다. TS 와

      마찬가지로 tick count 를 기준으로 tick bar 를 만들 수 있게 할 것이다. 기존 분봉 생성 로직을 아주

      조금만 손보면 구현이 가능하다.

2. 직전 봉에서 접수된 주문을 실시간로 체결하는 기능 추가

    : 현재는 하나의 봉이 완성되면 직전 봉에서 접수한 주문을 봉 가정에 따라 체결시키는, 즉 실제 거래에서는

      사용하지 않고 백테스트시에 사용되는 체결로직만이 존재한다. 하지만 실제 거래에서는 봉 가정은 필요없고

      직전 봉에서 접수된 주문들은 실시간 틱데이터로 만들어지는 봉에 의해 체결된다. 아무리 봉 가정이 실제와

      비슷하다고 해도 틱데이터 움직임보다 정확할 수는 없으며 이는 백테스트 결과가 부정확한 이유이기도

      하다. REAL 모드에서 정확한 주문 체결을 위해 실시간 틱데이터를 이용한 체결로직을 구현한다.

3. 두 개 이상의 tick bar 또는 tick bar 와 분봉을 한 전략에서 동시에 사용하는 기능 추가

    : TS 에서 char window 에 tick chart 를 생성했다면 더 이상의 심볼을 추가하는 것은 불가능하다. 이 기능을

      추가함으로서 비로소 본 프로젝트를 시작한 보람을 느끼게 될 것 같다. 우선적으로 구현하고 싶은 조합은

      다음과 같다.

      a. 심볼 1 : tick bar, 심볼 2 : tick bar

      b. 심볼 1 : tick bar, 심볼 2 : 1 분봉

      전략 루프는 a 의 경우 심볼 1, 2 중 어느것이 와도 수행될 것이며 매 루프에서 발생하는 모든 주문은

      유효하다. 그리고 전략변수의 값도 main symbol 여부와 관계없이 유지될 것이다.

      b 의 경우도 a 의 경우와 같은 로직을 탈 것이다. 허나 추후 필요에 의해 1 분봉이 갱신될 떄 수행되는

      전략 루프에서 생성된 주문 및 수정된 변수는 유효하지 않거나 유지되지 않게 할 수 있다.


위 기능들이 추가되면 이제 실제 거래를 해보는 단계에 나아갈 것이다. 정리해보면


1. API 에서 받아온 틱데이터를 REAL 모드 전략에 전송

2. tick 멀티심볼을 이용한 간단한 HFT 전략 수행 및 검증

3. 분봉 안에 틱데이터 정보를 넣어 봉가정 없이 정확한 분봉 백테스트가 가능하게 함


위  세 과정이 끝나면 당분간은 전략 개발에 전념할 생각이다.

2013. 5. 30. 10:47

이번에는 멀티심볼에서 특정 함수 수행시 주의할 또다른 점에 대해 정리해 보겠다.


TS 내장함수 중(read only 함수) 다음과 같은 구현이 있는 함수가 있다.



형태 '가'

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

if( CurrentBar = 1 ) then

begin

....

end;

else

begin

...

end;

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


함수가 이런 형태를 가졌다면 보통 매 봉마다 무조건 수행이 되야하는 함수이다. ( TS 에서는 이러한 함수를 series function 이라 부른다. )

내장함수의 이런 방식은 TS 8.7 버전에서 보이고 옛 버전인 2000i 버전에서는,



형태 '나'

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

if( CurrentBar >= 1 ) then

begin

...

end;

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


같은 형태이며, 이 방식이 좀 더 맞는 방식이라고 생각하는데, 그 이유는 CurrentBar 가 0 일 때 아무것도 수행하지 않으므로 0 을 리턴할 수 있기 때문이다. 하지만 8.7 버전의 형태(형태 '가')는 CurrentBar 가 0 인 경우 else 부분이 수행되는 로직이다. 이 경우 리턴되는 함수의 값이 대부분 0 이 아닐 것이고 이 내장함수의 의도는 CurrentBar 가 2 이상일 때 else 부분이 수행되는것이므로 첫 번째 전략을 돌 때는 이와 같은 형태의 함수의 사용은 주의를 요한다.


TS 에서 어떤 생각을 가지고 이런 구현을 했는지 궁금할 따름...


여기서 더욱 재밌는 점이 있다. 1분 심볼과 5분 심볼을 사용하는 전략을 예로 들겠다. 

이 결과는 TS 8.7 버전의 경우이므로 그 이전버전은, 즉 형태 '나' 방식의 내장함수를 사용하는 TS 는 다른 결과가 나올 수 있다.


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

전략의 첫 번째 루프:

첫 번째 심볼의 CurrentBar 는 1.

두 번째 심볼의 CurrentBar 는 0.

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


여기서 두 번째 심볼을 사용하는 형태 '가' 의 내장함수(RSI 라 가정하자)는 0 이 아닌 값을 리턴할 것이다.

예를 들어 0 이 아닌 0.5 을 리턴한다고 가정하자. 그럼 다음 과 같은 결과가 나온다.


Value1 = RSI Data2;


Value1 은 0.5 이다.


그럼 다음 전략 루프를 보자.


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

전략의 두 번째 루프:

첫 번째 심볼의 CurrentBar 는 2.

두 번째 심볼의 CurrentBar 는 0.

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


아직 두 번째 심볼의 CurrentBar 는 0 으로 아직 새로운 봉이 생성되지 않았다. 그러므로 첫 번째 루프에서 구한 값과 같은 값을 리턴해야하는것이 정상이다. 하지만 실제 리턴되는 값은 다음과 같다.


Value1 = RSI Data2;


Value1 은 0 이다.


첫 번째 루프에서의 0.5 는 어디로 간 것일까... 참고로 이후 두 번째 심볼의 CurrentBar 가 1 이 되기 전까지 'RSI Data2' 의 값은 계속 0 을 리턴한다. 즉, 내부 결과값들이 모두 초기화 됐다는 말이다. 필자가 TS 를 벤치마킹한 프로그램을 구현하면서 내린 결론은 다음과 같다.


1. 전략 코드에 if 문이 쓰이고 위와 같은 RSI 함수가 if 문 내부에서 쓰였다고 가정하자.

2. 전략이 if 문 내부로 분기되지 않는다고 해도 RSI 함수 내부는 수행되어야한다.

3. C++ 상에서 이것이 가능하게 만들기 위해서는 (물론 더 좋은 방법이 있겠지만 필자가 구현한 대로라면) 이런 형태의 함수는 각각 ID 를 가지게 하고 ( 예를들어 RSI( Close, 10 ) 과 RSI( Close, Value1 ) 은 Value1 의 값이 10 이라고 해도 다른 ID 를 가지게 한다.) 함수 내에 사용되는 심볼이 갱신이 될 때마다 전략 루프 돌기 전에 수행을 시켜줘서 미리 값을 구해놓아야한다. 여기서 모든 함수들의 ID 를 구하는 작업이 필요한데, CurrentBar 가 0 이던 아니던 무조건 첫 한 번은 수행을 시켜서 ID 를 구하는 로직을 TS 에서는 사용하지 않았을까 싶다. 그래서 결국 수행되지 말아야할 CurrentBar 가 0 인 상황에서도 함수가 수행되었고, ID 를 구한 상태에서는 내부적으로 가지고 있는 결과값 배열을 전부 0 으로 초기화를 시킨것이 아닐까... 라는 소설을 써본다. 사실 필자는 이런 TS 의 결과를 보고 위와 같은 방식으로 코딩을 해놓았다.


결론적으로 위와 같은 오류를 피하기 위해서는 다음 두 방법을 사용하자.


1. 형태 '가' 와 같이 된 내장함수를 사용하지 말고 모두 형태 '나' 와 같은 커스텀함수를 만들어서 사용한다. (내장함수가 형태 '나' 라면 그냥 둬도 된다.)

2. 전략 자체를 사용된 심볼의 current bar 가 1 이상일 경우에만 수행되게 만든다.


첫 번째 봉이 나오자마자 주문이 나갈 일은 거의 없겠지만 시스템 버그를 미연에 방지하기 위해서는 어쩔 수 없는듯하다..

2013. 5. 25. 08:41

멀티심볼 데이터를 TS 함수에서 사용할 때 주의할 점이 있다. build-in 함수를 포함하여 user-defined 함수를 만들때도 반드시 참고해야하는 사항이다. 결론부터 말하면


1. 함수 인자에 두 번째 심볼 데이터(ex. close data2)를 직접 넣으면 함수 내부적으로 사용되는 심볼 데이터는 모두 두 번째 심볼 데이터를 사용한다.

2. 함수 인자에는 두 번째 심볼 데이터, 함수 내부에서는 첫 번째 심볼 데이터가 사용되길 바란다면 두 가지 해결방법이 있다. 

    a. 별도 변수에 두 번째 심볼데이터를 대입한 후 그 변수를 함수 인자로 사용한다.

    b. 인자로 바로 두 번쨰 심볼데이터를 사용하고 function( ... ) data1 과 같이 사용한다.



이제 위에 언급한 내용들을 좀 더 자세히 설명하겠다.

예를 들어 다음 과 같은 인터페이스를 가진 함수가 존재한다고 하자.


testFunction( NumericSimple aNum );


그리고 이 함수 내부에서는 다음과 같이 심볼 데이터인 close 를 사용한다고 가정하자.


input: aNum


testFunction = close * aNum;


인자로 넘어온 aNum 이라는 변수에 종가를 곱하여 리턴해주는 단순한 함수이다. 그럼 다음과 같은 사용을 해보면 어떤 결과가 나올까? ( close 는 200, close data2 는 300 이라 가정)


Value1 = testFunction( 10 ); 


Value1 에 리턴된 값은 함수 내부계산이 10 * 200 이므로 2000 이 될것이다.


Value1 = testFunction( close );


이번엔 close * close 가 계산되어 40000 이 리턴될 것이다. 그렇다면 다음은 어떨까?


Value1 = testFunction( close data2 );


직관적으로는 300 * 200 으로 60000 이 되야하지만 실제 계산은 300 * 300 이 되어 90000 이 리턴된다.

이를 의도한대로 계산되어지게 하려면 다음과 같은 방법을 사용해야한다.


== 첫 번째 방법 ==

Value99 = close data2;

Vallue1 = testFunction( Value99 );


== 두 번째 방법 ==

Value1 = testFunction( close data2 ) data1; 


첫 번째 방법에서 사용된 Value99 는 심볼 데이터가 아니므로 함수 내부에서 사용되는 심볼 데이터는 default 인 첫 번째 심볼을 사용한다. 

두 번째 방법에서 함수 뒤에 사용된 심볼 데이터 번호(여기서는 data1)는 은 원래 함수에 사용된 인자들이 심볼 데이터인 경우, 인자들을 모두 해당 심볼 데이터 번호로 바꾸고 함수 내부에 사용된 심볼들도 마찬가지로 해당 심볼 데이터 번호로 바꾸는 기능을 한다. 하지만 이렇게 심볼 데이터 번호가 바뀌는 대상은 default 심볼 데이터를 사용한 경우이고 특정 심볼 데이터 번호가 붙어있는 심볼 데이터(ex close data2) 는 다른 심볼 데이터로 변경되지 않는다. 그러므로 두 번째 방법의 경우 인자는 다른 심볼로 변환되지 않고, 함수 내부 심볼만 변경되어 의도한 값을 얻어낼 수 있는것이다.

2013. 5. 24. 00:17

TS 의 easy language 를 사용하여 전략을 짤 때 시장가로 주문하는경우를 제외하고 stop 이나 limit 으로

주문할 경우 주문가를 코드상에 입력하게 되어있다. 보통 다음 세 가지 방식 중 한 가지로 주문가를 입력할 것이다.


1. symbol 정보를 사용한 주문가격

    ex. buy next bar close stop, buy next bar close stop + 1 ...


2. 변수를 사용한 주문가격

    ex. buy to cover next bar sExitPrice stop, ...


3. 함수의 리턴값을 바로 주문가격으로 사용

    ex. sell short next bar average( close, 10 ) stop, ...


1 번의 경우 예외없이 입력한 가격 그대로 주문가격이 된다. close 가 250.25 면 250.25 로 주문가격이 되는것이다. 그렇다면 2, 3 번의 경우는 어떨까? 250.25 가 아닌 250.26 또는 250.2488 이런식이라면? 


인터넷을 찾아봤을 때 명료한 설명이 없어 본인이 가정하고 테스트한 로직을 끄적여보겠다. 100% 정확하지는 않지만 테스트케이스 양은 상당하니 어느정도는 믿어볼만 하다.


처음 TS 내부로직 분석을 시작할 즈음에는 다음과 같이 결론을 내렸었다. (KOSPI200 선물을 기준으로 삼았다)


=== 입력가 -> 주문가 변환 로직 (구버전) ===


1. stop 주문의 경우

    * buy 주문은 입력가격과 같은가격의 호가 또는 입력가격보다 큰 가격 중 가장 가까운 호가

    * sell 주문은 입력가격과 같은가격의 호가 또는 입력가격보다 작은 가격 중 가장 가까운 호가

2. limit 주문의 경우

    * buy 주문은 입력가격과 같은 가격의 호가 또는 입력가격보다 작은 가격 중 가장 가까운 호가

    * sell 주문은 입력가격과 같은 가격의 호가 또는 입력가격보다 큰 가격 중 가장 가까운 호가


예를 들면 buy stop 을 하는데 입력가격이 250.26 라 가정하면 250.26 은 호가단위가 아니므로 250.26 보다 큰 가격 중 가장 가까운 호가가 주문가가 되는것이다. 그러면 주문가는 250.30 이 되겠다.


이런 로직을 CherryPicker 에 반영시키고나서 한동안은 별 탈이 없었는데, 테스트케이스를 늘리는 과정에서 TS 주문가격과 달라지는 문제가 터져버렸다. buy stop 에서 입력가는 250.00045 였는데 위 로직대로라면 주문가는 250.05 여야하는데 실제로는 250.00 이 주문가격이 돼버린 것이다. 약간의 테스트 끝에 마지막으로 반영시킨 로직은 다음과 같고 이 로직은 현재까지 별 다른 문제를 보이지 않고 있다.


=== 입력가 -> 주문가 변환 로직 (신버전) ===


1. stop 주문의 경우

    * buy 주문은 입력가격에서 0.0005 를 차감한 후에 앞서 설명한 로직을 따름

    * sell 주문은 입력가격에서 0.0005 를 더한 후에 앞서 설명한 로직을 따름

2. limit 주문의 경우

    * buy 주문은 입력가격에서 0.0005 를 더한 후에 앞서 설명한 로직을 따름

    * sell 주문은 입력가격에서 0.0005 를 차감한 후에 앞서 설명한 로직을 따


구버전의 로직과의 차이는 0.0005 를 더하거나 빼주는것 밖에 없다. 의외로 간단하지만 약간의 트릭을 써야한다. 

CherryPicker 에 반영된 코드를 몇 줄 가져와보면 다음과 같다.


ex ) buy stop 일 때,입력가격을 인자로 받는 함수인 firUp 의 구현


double fitUp( double aPrice )

{

    double sDnPrice = (float)aPrice - 0.0005f;

    int        sIntPrice = (int)( sDnPrice * 100.00 );

    int        sTemp    = sIntPrice / 5;


    return (double)( ( sTemp * 5 ) + 5 ) / 100.00;

}


보다시피 0.0005 를 빼주거나 더해주는 작업을 할 때는 float 타입으로 변환시켜 약간 부정확한(?) 연산을 해야만한다. TS 개발자의 의도를 알 수는 없지만 저렇게 해야만 TS 와 같은 결과를 낳을 수 있다.

TS 는 7 버전부터 데이터를 double 타입으로 다루기 시작했는데 전부 배제시키지는 않은 모양이다.


buy stop 의 예제를 그림으로 알기쉽게 표현하면 다음과 같다. (그림을 넣을 필요는 없지만 태블렛 노트북을 산 의미를 부여하기 위해 몇 컷 넣어본다..;;)





2013. 5. 19. 08:19

거의 반년만의 포스팅같다.


먼저 간략하게 추가된 사항을 나열하겠다.


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

추가된 사항

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


1. 주문입력값이 호가와 일치하지 않는 경우, (예를 들어 KOSPI200 선물은 200.22 일 때) 내부적으로 가격 조정을 하는데 이 알고리즘을 테스트 후 적용했다.


2. 멀티심볼을 적용하는데 있어 생기는 문제점들을 해결했다. 각 심볼들이 MaxBarsBack 을 채우고나서 CurrentBar 및 BarNumber 가 1로 시작을 하게되는데, 기존 가정이 틀린 부분이 있어 수정 및 테스트 완료했다.

그리고 TS 8.7 버전에서 BarNumber 증가에 관한 버그를 발견한것 같은데, 멀티심볼의 경우 두 번째 이후의 심볼은 경우에 따라 CurrentBar 와 BarNumber[0] 가 일치하지 않는다. 이런 버그까지 CherryPicker 에서 재현되도록 적용할 필요는 없을것 같다.


3. 멀티심볼을 구성하는 경우 다음 두 규칙을 따르게 했다.


(1) 거래 대상 심볼은 가장 작은 time interval 을 가지고 있어야한다.

    : 내부적으로 최소 time interval 을 가진 봉이 완성되면 주문 및 체결이 이루어지는 구조다.

(2) 큰 time interval 의 심볼의 time interval 은 작은 time interval 의 심볼의 time interval 의 배수가 되는걸 추천.

    : time interval 이 1 과 3 인 전략은 3이 1의 배수이므로 3분 봉이 완성될 때 언제나 1분봉도 같이 완성되어

      (1) 규칙을 언제나 만족시킨다. 하지만 time interval 이 3 과 5 의 심볼을 가진 전략은 5, 10, 15, 20 분에도 

      전략은 루프를 돌지만 5, 10, 20 분에는 주문 및 체결조건을 만족해도 주문 및 체결이 이루어지지 않는다.


* 위 추가된 사항 '3' 에서 설명한 '루프를 돌지만 주문 및 체결이 되지않는 상황' 에서의 로직은 단순하다. 최소 time interval 심볼이 봉을 완성되지 않은 상태에서 다른 time interval 을 가진 심볼이 봉을 완성하면 해당 상황을 만족시키게 되는데, 이 때 발생하는 주문은 그냥 무시하고, 이전에 주문한 조건이 수행되지 않게끔 한다. 그리고 해당 루프를 돌 때 전략 변수들을 조작할 수도 있는데 값 변경은 실제로 이루어지게 설계하되, 다음에 최소 time interval 을 가진 심볼이 봉을 완성하면 변경된 값을 undo 처리하여 복원한다.


4. session 이 끝나는 시간을 심볼의 time interval 크기에 따라 조절할 필요가 있다. 1, 3, 6, 30 분 심볼을 예로 들어보자. 선물 동시호가가 시작되면,


* 1 분 심볼의 경우 15:00, 15:01, 15:02, 15:03, 15:04, 15:05, 15:15 에 봉이 완성

* 3 분 심볼의 경우 15:00, 15:03, 15:06, 15:15 에 봉이 완성

* 6 분 심볼의 경우 15:00, 15:06, 15:18 에 봉이 완성

* 30 분 심볼의 경우 15:00, 15:30 에 봉이 완성


위와 같이 봉이 완성이 되는데, TS 에서 session end time 을 15:20 으로 설정을 하면 1, 3, 6 분 심볼의 경우 영향이 없지만 30분 심볼의 경우 마지막 봉이 15:30 이 아니는 15:20 으로 되어 정확한 봉 완성 시각이 설정되지 않는다. 그러므로 큰 time interval 을 사용할 경우 session end time 을 그에 따라 적절하게 늘릴 필요가 있다.




이상이다. 10 년 이상의 데이터를 이용하여 TS 에서 print로 찍어낸 로그와 일치시키는데 지금까지 가장 많은 시간이 걸렸다. 멀티심볼 적용도 테스트가 끝난 현 상황에서 필자에게 할당된 시간의 100% 를 내부로직 기능 추가에 할애하기보다 '돈'을 벌 수 있는 로직을 공부하는 시간을 절반가량 할애할 생각이다. 추가해야할 함수도 많기에 앞으로의 포스팅은 추가된 함수 및 전략을 중심으로 진행하되 간간히 내부로직 기능 추가를 포스팅할 생각이다.

2012. 9. 10. 13:36

TS 의 기능은 많다 그것도 아주 많이.. 그 많은 기능들을 하나하나 개인이 벤치마킹하기에는 좀 부담스러운건 사실이다. 하지만 대부분 일반적인 시스템 거래에서는 쓰이지 않으며 또 쓰인다 한들 현재 진행중인 프로젝트의 기능 테스트만 제대로 구축한 상태라면 1. 기능 추가, 2. 전체 기능 테스트 수행 <-- 이거면 끝이다.


현재 프로젝트를 진행하면서 굵직굵직한 기능들을 추가하면서 완전한 TS 또는 그 이상의 기능에 도전해왔다.

지금까지의 TSimulator 는 멀티 심볼 기능을 지원했지만, 1분봉만 사용할 수 있는 제한적 기능이었다.

하지만 이 기능만으로 TS 의 주문 알고리즘과 함수 알고리즘을 테스트 하기에는 무리가 없었다.


하지만 주문 알고리즘, 함수 알고리즘은 끝낸 시점에서 남은 작업은 복수의 time frame 을 심볼에 등록할 수 있게 만드는 일이다. 이 작업이 끝나면 남은 굵직한 작업은 다음과 같다.


1. 전략의 결과 분석 툴

2. 실시간 데이터와의 접목


1번의 전략의 결과 분석 툴은 시간문제일 뿐 어려운 작업은 없다. 여기서 중요한건 TS 에서 제공하는 결과 분석 툴 이상의, 다양한 툴을 앞으로 개발해 나가는 것이다.

2번의 실시간 데이터와의 접목... 이거 역시 시간문제인데, 하나의 문제점이 있다면 TS 에서의 실시간 거래 결과와 또 비교를 해봐야 하는데, 과거 데이터야 이미 어마어마한 테스트 자료가 있지만 실시간 처리가 잘 되는지는 매일매일 신경을 써줘야하는 부분이다. 하지만.. 이것도 밀어붙이면 다 해결될 일... 


각설하고.. 결과적으로는 멀티 심볼 적용 작업이 완료되었다. 이제부터 당분간은 테스트 케이스를 늘려나가는 작업에 들어갈 것 같다. 이 작업이 참 재미있는게, TSimulator 결과 TS 의 그것과 일치하면 일치하는대로 좋지만 뭔가 허전하다. 회사 팀장님이 새로 개발중인 프로그램에서 버그가 많이 나오면 호신호라고 말씀하신게 심히 공감이 간다. 너무 일이 잘 진행이 되면 불안한 기분이랄까.. 무튼 그렇게 완성도를 높혀가는게 정석이라고 여겨진다.


이전에 포스팅 한 글 중에 CEP 엔진을 이용한 시스템 트레이딩 개발을 시작하려고 한다는 글이 있을것이다. 그런데 TSilmulator 에서 작은 버그들이 계속 터지면서 그동안 나름 바빴서 아직 시작을 못했다..^^;; 당분간 테스트 케이스를 늘려가면서 천천히 시작해야할것 같다.. 시기는.. .9월 말쯤부터...?

prev"" #1 #2 next