[STage특징 및 주의사항] 함수작성 및 호출시 주의사항
글쓴이 : STage 조회수 : 3366 작성일 : 2011-04-22
1번첨부 : 없음 2번첨부 : 없음 3번첨부 : 없음

이 경우도 Cross문법 적용시 주의사항과 동일한 주의가 필요합니다.

우리가 함수를 작성하고 사용할 때 크게 다음과 같이 분류할 수 있습니다.
1. 언제 어느 조건에서든 정확한 결과값을 반환하는 함수.(예:MA함수)
2. 반드시 매 봉마다 실행이 되어야만 하는 함수(예: MAFC함수)

각각의 경우를 스테이지가 제공하는 함수를 예로 설명드리겠습니다.

1. MA함수: Moving Average

Input: 값(Numeric), 개수(Numeric)

합계 = 0
For Counter = 0 To 개수 - 1
    합계 += 값[Counter]
End For

MA = 합계 / 개수

이 함수는 이동평균을 구하는 함수입니다.  코딩을 보시면 For문을 사용하여 지정된 구간내의 값들을 전부 더하여 평균을 계산하여 반환합니다.  이 함수의 성능은 "개수" 매개변수의 값에 따라 많은 차이가 납니다.  값이 5일경우와 500인 경우 100배의 속도 차이가 발생합니다.  이런 속도의 차이는 전략의 최적화 테스트시 상당한 영향을 줄수도 있기 때문에 적용시 신중하게 생각할 사항입니다.
하지만 이 함수는 지표의 코딩중 어느 위치에서 호출해도 동일한 결과를 리턴합니다.  For문을 사용해 매번 재계산을 하기 때문이죠.

2. MAFC함수: Moving Average Fast Calculation - 약자가 맞는지 잘 모르겠습니다.

Input: 값(Numeric), 개수(Numeric)

If BarIndex = 개수 - 1 Then
   합계 = 0
   For Counter = 0 To 개수 - 1
     합계 += 값[Counter]
   End For
Else
   합계 += 값 - 값[개수]
End If

MAFC = 합계 / 개수

이 함수는 MA함수와 동일한 결과값을 반환하지만 "개수"의 값에 상관없이 빠른 연산속도를 보장합니다.
원하는 개수의 봉에서 실행되는 순간( If BarIndex = 개수 - 1 Then) 한번만 For문장을 실행하고 그 이후는 For문장을 실행하지 않으므로 속도가 MA함수에 비해 굉장히 빠릅니다.

하지만 이 함수는 합계라는 변수에 매 봉마다 값을 계산하여 적용해야만 정확한 결과값을 얻을 수 있기 때문에 함수를 호출할 때 신중해야 합니다.  즉, 특정 조건식 내부에서 사용되어 특정 봉에서 실행되지 않는 경우가 있으면 원하는 결과를 얻을 수 없습니다.

원치않는 결과를 얻을 수 있는 몇가지 사례와 그 해결책을 알려드리겠습니다.

[사례1: 조건식 안에서 사용하는 경우]

if 조건식 then
   Plot1( MAFC( Close, 10 ) )
end if
vMA = MAFC(Close,10)
if 조건식 then
   Plot1( vMA )
end if

[사례2: elseif 다음 문장이 실행 안되는 경우 ]
if Close > MAFC(Close, 10 ) then
    Buy
elseif Close < MAFC(Close, 10 ) then
    Sell
end if
bUpper = Close > MAFC(Close, 10 )
bDown = Close < MAFC(Close, 10 )
if bUpper then
    Buy
elseif bDown then
    Sell
end if

[사례3: And Or 등의 연산자 사용시]
if Close > MAFC(Close, 5) And Close > MAFC(Close, 10) And Close > MAFC(Close, 60) Then
    Buy
end if
bUp1 = Close > MAFC(Close, 5)
bUp2 = Close > MAFC(Close, 10)
bUp3 = Close > MAFC(Close, 60)
if bUp1 And bUp2 And bUp3 Then
    Buy
end if

[사례4: For문 안에서 사용]
Array: aV[3]

aV[1] = 5
aV[2] = 10
aV[3] = 60

bUp = true
For Len = 1 To 3
    if Close <= MAFC(Close, aV[Len]) Then bUp = false
End For

if bUp then Buy
Array: aV[3]

aV[1] = 5
aV[2] = 10
aV[3] = 60

bUp = true
For Len = 1 To 3
    if Close <= MA(Close, aV[Len]) Then bUp = false
End For

if bUp then Buy


이 외에도 기타 비슷한 사례들이 있을 수 있는데, 모두 이유는 동일합니다.

[사례3]은 And나 Or연산자의 특성 때문에 나타나는 현상인데
- And는 좌/우의 조건이 모두 참값일때만 참이므로 좌측의 조건이 거짓이면 우측의 조건을 실행하지 않습니다.
- Or는 좌/우의 조건중 하나만 참이면 결과가 참이므로 좌측조건이 참이면 우측 조건을 실행하지 않습니다.
그래서 if~elseif 문장처럼 경우에 따라 원치않는 결과가 나올수 있습니다.

[사례4]는 MAFC함수 내부의 "합계"라는 변수가 aV[Len]에 영향을 받아 엉뚱한값으로 변경되기 때문에 For문장 안에서는 사용할 수가 없습니다.  빠른 실행속도와 For문장을 실행해야 한다면 아이디어가 필요할것 같습니다.  대신에 MA함수를 사용하면 원하는 결과를 얻을 수 있습니다.

한가지 더 말씀드리면 MA함수처럼 내부에서 For문을 사용하여 어느시점에 어떤형태로 호출해도 정확한 값을 반환하는 함수일 지라도 아래의 예처럼 사용된 경우 For문 안에서 함수를 호출하면 잘못된 결과가 나올 수 있습니다.

[사례5: CloseD 함수(분봉 이하의 종목에서 일단위 종가를 얻는 함수)]

01:  Parameter: DaysAgo(Numeric)
02:  Array: CloseArray[50](-1)
03: 
04:  If DataCompression <= 2 Then
05:     If Date > Date[1] Then
06:        For Value1 = 50 To 1 Step -1
07:           CloseArray[Value1] = CloseArray[Value1-1] 
08:        End For
09:        CloseArray[0] = Close[1]
10:     End If
11:  
12:     If DaysAgo <= 50 AND DaysAgo > 0 Then 
13:        CloseD = CloseArray[DaysAgo - 1]
14:     End If
15:     If DaysAgo = 0 Then 
16:        CloseD = Close
17:     End if
18:  End If
이 함수를 For문장 안에서 호출한 경우 06번 라인의 For문장 때문에 틀린결과가 리턴됩니다.

bBuy = true
For i = 1 to 3
    if Close < CloseD(i) then bBuy = false
End For

if bBuy then Buy
일자가 변경되는 봉(If Date > Date[1] Then)에서 3번의 For문을 돌면서 CloseD를 실행하게 되면 07번 라인의 수행결과 3일이 지난결과 처럼 배열 요소가 Shift되고 그 자리를 09라인의 수행으로 인해 동일한 전일 종가 3개가 배열요소 0, 1, 2번째에 입력됩니다.

CloseD를 For문장에서 호출하고자 한다면 다음과 같이 수정하면 됩니다.

01:  Parameter: DaysAgo(Numeric)
      Variable: vCurBar(0)
02:  Array: CloseArray[50](-1)
03: 
04:  If DataCompression <= 2 Then
         If CurrentBar <> vCurBar Then
05:        If Date > Date[1] Then
06:           For Value1 = 50 To 1 Step -1
07:              CloseArray[Value1] = CloseArray[Value1-1] 
08:           End For
09:           CloseArray[0] = Close[1] 
               vCurBar = CurrentBar
10:        End If
         End If
11:  
12:     If DaysAgo <= 50 AND DaysAgo > 0 Then 
13:        CloseD = CloseArray[DaysAgo - 1]
14:     End If
15:     If DaysAgo = 0 Then 
16:        CloseD = Close
17:     End if
18:  End If
즉, 새로운 일자가 시작되는 봉에서 For문장에 의해 여러번 값이 변경되지 않도록 수행한 CurrentBar를 변수에 저장하고 그 변수와 CurrentBar가 변경되었을 경우만 수행되도록 수정한 것입니다.
예를 들려고 한것인데, 스테이지 함수의 티를 발견했네요.  시스템에서 제공하는 함수이니 저런 방식으로 수정후 다운로드 해야겠습니다.


번호 제목 첨부 작성자 작성일 조회
24  당일종가청산, 당일청산 안내 도움말 스테이지 2013-09-13 2320
23  야간장 매매시 [당일청산], [당일종가청산] 관련.. 스테이지 2013-07-01 2143
22  STage 도움말 - 시간보정 신규옵션 안내 스테이지 2012-02-02 2209
21  STage 도움말 - 사용자 함수 옵션 설정안내 스테이지 2011-12-09 2103
20  STage 도움말 - IF문 관련 주의사항 안내 스테이지 2011-09-15 2411
19  STage 도움말 - 최적화 사용 안내 스테이지 2011-09-05 2389
18  STage 도움말 - 주문함수 안내 스테이지 2011-08-26 2971
17  STage차트 종목연동기능 안내 스테이지 2011-08-04 2567
16  STage-GOM 유의사항 공지 - 주문기능제한 스테이지 2011-08-01 2398
15  STage-GOM 사용안내 (최초 사용시) 스테이지 2011-08-01 2482
14  STage - GOM 사용도움말 배포 안내 스테이지 2011-07-28 3661
13  STage 동영상 #3 - STage 시스템주문 사용법 스테이지 2011-07-01 3040
12  STage 동영상 #2 - STage 차트 사용법 #2 스테이지 2011-07-01 2713
11  STage 동영상 #1 - STage 차트 사용법 스테이지 2011-07-01 3272
10  STage 메뉴얼 - STage 시스템 주문 설정 스테이지 2011-06-23 2905
9  STage 메뉴얼 - 사용자지표 만들기 스테이지 2011-06-01 2855
8  STage 사용법 매뉴얼 스테이지 2011-05-26 3349
7  STage 도움말 배포 안내 스테이지 2011-05-13 3615
6  [STage특징] 라인 오브젝트의 활용 스테이지 2011-05-05 3120
5  [STage특징] 함수를 객체로 활용하기 스테이지 2011-04-27 2839
4  [STage특징 및 주의사항] 함수작성 및 호출시 주.. STage 2011-04-22 3367
3  [STage특징 및 주의사항] Cross 문법 STage 2011-04-22 2772
2  [STage특징 및 주의사항] STage 2011-04-22 3144
1  STage 많은 관심 부탁드립니다. 상상나무 2011-03-22 2797
1