트레이딩을 위한 조합론과 확률 이론(2부): 범용 프랙탈
콘텐츠
- 소개
- 트레이딩에서 프랙탈을 사용 가능한지 평가하기
- 범용 프랙탈을 구축하기 위한 이론적 근거
- 범용 프랙탈을 구현하는 코드 작성하기
- 대칭 프랙탈을 기반으로 첫 번째 공식 도출하기
- 모든 양수 및 실수 인수에 대해 파생된 공식의 성능 평가하기
- 범용 프랙탈에서 발전한 고급 프랙탈
- 결과 요약
- 결론
- 참조
소개
이전 기사에서 우리는 트레이딩 작업에 프랙탈 함수를 사용하는 구체적인 특징을 이해하는 데 도움이 되는 확률 이론의 기초에 대해 알아보았습니다. 여기서도 동일한 주제를 연속으로 다룰 것이며 저는 필요한 모든 가격 책정 프로세스를 설명할 수 있는 몇 가지 자급 자족적인 프랙탈 함수를 보여드리겠습니다. 명확한 정량적 추정치에 근거하지 않고 모호하기도 한 여러 질문에 답할 수 있는 공식을 만들고 이를 일반화 및 단순화하기 위해 노력할 것입니다.
트레이딩에서 프랙탈을 사용 가능한지 평가하기
이제 이전 기사의 결과를 요약하고 보다 간결하고 범용적인 형태로 자료를 만들어 가며 주제를 계속 이어가겠습니다. 여러분들은 이전 기사에서 프랙탈을 구성한 예시를 기억하시나요? 이러한 프랙탈은 실용적인 용도는 거의 없지만 이 경우 우리는 주로 우리가 결정한 구조 구성 규칙에 관심이 가게 됩니다. 결과적으로 이러한 규칙은 세 가지 유형의 프랙탈에 적용할 수 있습니다:
- 대칭 테두리가 있는 프랙탈
- 비대칭 테두리가 있는 프랙탈
- 위쪽 또는 아래쪽 테두리가 있는 프랙탈
이러한 프랙탈은 다음과 같은 프로세스를 설명하는 데 적용될 수 있습니다:
- 제한 적인 자금 상황을 고려한 다양한 시나리오의 확률을 평가할 수 있는 기능이 있는 트레이딩 모방의 가속화 (하단 경계는 추가 거래가 불가능한 수준의 자금을 나타내는 것일 수 있기 때문에)
- 프랙탈 내에서 평균 스텝 수 추정(예: 원하는 손익을 얻기까지 평균적으로 얼마나 많은 주문이 있는지 추정할 수 있음)
- 각 스텝의 총 평균값 추정 (예를 들어, 작은 포지션, 즉 포인트 또는 가격 차에서 스톱 레벨이 작은 포지션에 대한 통계를 기반으로 평균 포지션 보유 시간을 계산할 수 있습니다.
- 단일 경계 프랙탈을 기반으로 한 옵션의 수익성 평가
- 기타 기능
범용 프랙탈을 구축하기 위한 이론적 근거
이전 글에서 도출한 구성 규칙을 사용하고 이를 보완하여 프랙탈이 어떻게 구성되는지 살펴보겠습니다. 또한 저는 제 공식에서 작은 실수를 발견했는데 이로 인해 테두리의 하향 또는 상향 비대칭이 불가능 했었습니다. 도출된 공식은 정확한 것으로 판명되었으며 따라서 모든 프랙탈에 적용 가능합니다. 사실 이것은 모든 프랙탈을 구현할 수 있는 함수입니다. 가능한 모든 프랙탈은 일반 프랙탈의 특수한 경우입니다. 위에서 정의한 세 가지 프랙탈 유형을 사용할 경우 이 세 가지 특수한 경우를 구현하기 위한 일반 프랙탈의 조건은 다음과 같습니다:
- M = N & [ M > S & N > S ]
- ( m > n || n > m ) & [ m > s & n > s ]
- ( m > S && n <= S ) || ( n > S && m <= S )
이 세 가지 유형의 프랙탈은 개략적으로 다음과 같이 생겼습니다:
이상적으로 'S'는 무한대가 되어야 합니다. 다음 변수들은 이전 글에서 설명하지 않은 변수들입니다. 저는 여기에 관련 설명을 통해 일반 공식을 사용해서 특수 케이스를 얻는 방법을 알려드리도록 있도록 하겠습니다. 프랙탈은 마치 원자 폭탄처럼 연쇄 반응의 원리에 따라 작동하는 함수입니다. 만약 설정된 연쇄 반응이 너무 깊으면 컴퓨터가 이러한 방대한 계산을 처리하지 못할 수 있습니다. 특별히 중요한 경우가 아니라면 몇 분, 몇 시간, 심지어 며칠까지 매우 오랜 시간 동안 계산됩니다. 프랙탈에서 연쇄 반응을 올바르게 시작하려면 우리는 두 가지 기본 값을 찾아야 합니다:
- Half - 채널 너비의 절반
- Middle - 중간 라인에 해당하는 "U" 값입니다.
Half 값은 이전 글에서 결정한 세 가지 경우 모두에 대해 쉽게 계산할 수 있습니다: m과 n의 산술 평균입니다:
- Half = (n + m) / 2
두 번째 값을 구현하려면 우리는 세 가지의 로직 변형을 사용해야 합니다. 그러나 첫 번째 변형과 두 번째 변형은 하나로 결합될 수 있습니다. 따라서 우리에게는 두 가지 변형이 있습니다:
- n >= m
- n < m
다음으로 'U' 축이 위쪽을 향하고 n 값이 채널의 위쪽이고 m이 아래쪽이라고 가정하면 우리는 가능한 m과 n의 두 가지 경우에 대해 두 가지 비율을 구할 수 있습니다:
- Middle = Half - m
- Middle = - ( Half - n )
이들 값은 내부적으로 사용하기 위해 프랙탈 함수에 전달됩니다. 왜냐하면 이들 값이 없을 경우 이전 글에서 설명한 내부 분기 로직이 구현될 수 없기 때문입니다. 함수 프로토타입은 다음과 같습니다:
- double Fractal(double Half, double Middle, int m, int n, int s,double p,int S, int U, double P)
따라서 우리는 프랙탈이 올바르게 시작되게 하기 위해 세 가지 필수 값을 전달해야 합니다:
- Half - 채널 너비의 절반
- Middle - 중간 라인에 해당하는 "U" 값
- m - 아래쪽 테두리까지의 스텝 수
- n - 상단 테두리까지의 스텝 수
- s - 단일 체인에 대해 모든 방향에서 허용되는 최대 스텝 수
다른 값들은 이들 값들이 동적이며 프랙탈 레벨에 따라 달라질 수 있다는 것을 나타내기 위해 대문자로 표시됩니다. 정의는 다음과 같습니다:
- S - 현재 확률 사슬에 누적된 스텝 수; 다음 프랙탈 레벨로 넘어가게 될 수
- U - 체인 시작점과 끝 사이의 현재 거리, 다음 프랙탈 레벨로 넘어갈 거리
- P - 베르누이 체계에 기반한 전체 체인 확률의 누적 곱; 다음 프랙탈 레벨로 전달됨
따라서 프랙탈을 올바르게 시작하려면 우리는 함수에 다음 값을 입력해야 합니다:
- S = 0(시작이므로 아직 스텝이 없음)
- U = 0(같은 이유로)
- P = 1(제로 체인이고 다음 스텝이 모두 완전한 그룹을 구성해야 하므로)
가격 또는 트레이딩을 시뮬레이션 하는 프랙탈의 일반적인 규칙 개발을 마무리하기 위해 이전 글에서 얻은 규칙을 간단히 다시 작성해 보겠습니다. 이러한 규칙은 프랙탈 내부에서 사용됩니다. 규칙은 동일한 스텝에 대한 몇 가지 공식을 기반으로 합니다:
- f = u + d - 미래 조합 트리의 스텝 수입니다 (거리는 프랙탈 범위의 가장 가까운 경계까지의 거리에 따라 결정됩니다).
- s = u - d - 하강 및 상승 구간으로 표현되는 최종 스텝 수입니다.
우리는 "U"를 반복하기로 결정했습니다. 또한 남은 스텝의 수가 이를 지원하는 경우 우리는 "s" 값을 새로운 "U"로 사용하여 다음 프랙탈 레벨로 전달할 것입니다. 이를 위해 우리는 'd'를 포함하지 않는 'u'에 대한 수식을 정의해야 합니다. 이렇게 하려면 첫 번째 방정식에서 'd'를 표현하고 이를 두 번째 방정식에 대입합니다:
- s = 2*u - f
현재 값이 0인 경우 이 값을 새로운 "U" 값으로 사용하여 더 전달할 수도 있습니다. 따라서 더 전달해야 하는 값을 얻으려면 이 "s"를 "U"에 추가해야 합니다:
- NewU = s + U - 다음 프랙탈 레벨로 넘어가기 위한 새로운 "U"
이전 글에서 이미 정의한 것처럼 이 표현식은 'f'의 세 가지 가능한 값을 기준으로 세 가지 값을 사용합니다. 저는 이전 글에서 아이디어를 설명하기 위해 다이어그램을 수정했습니다:
이제 이 다이어그램은 매우 적절합니다. 왜냐하면 대부분의 문제를 해결하는 데 유용한 모든 가능한 프랙탈 구성을 우리가 결정하기 때문입니다. 이 다이어그램에 따르면 우리는 "f"에 대해 세 가지 경우를 정의합니다:
- f = ( n - 1 ) - U
- f = ( m - 1 ) + U
- f = Half - 1
이 세 가지 경우는 다음 조건이 충족될 때 나타납니다:
- U > Middle
- U < Middle
- U = Middle
이제 우리는 다음 프랙탈 레벨로 전달할 마지막 두 값을 결정하고 프랙탈에서 숫자가 수집되는 방식을 생각해 봐야 합니다. 마지막 두 값은 다음과 같이 계산됩니다:
- NewP = P * C(f,i) * Pow(p,i) * Pow(1-p,f-i) - 다음 프랙탈 레벨로 전달될 새로운 체인 확률 "P".
- NewS = S + f = S +(floor(Mid) - 1) - 다음 프랙탈 레벨로 넘어갈 새로운 "S"
숫자를 공통 변수로 수집하기 전에 숫자를 비슷한 블록으로 수집해야 하지만 이 경우에는 우리는 한 스텝만 수행하므로 베르누이 체계가 필요하지 않다는 점에 유의하세요. 표현의 순서는 중요하지 않으며 같은 블록에 있어야 합니다. 숫자는 '1'과 '2'의 경우에만 수집할 수 있으며 몇 가지 추가적인 설명이 필요합니다:
- U = n - 1
- U = - ( m - 1 )
첫 번째 경우 한 스텝만 거치므로 앞의 세 가지 값은 계산하기가 더 쉽습니다:
- NewU = U - 1
- NewP = P * p
- NewS = S + 1
두 번째 경우에는 약간의 차이가 있습니다:
- NewU = U + 1
- NewP = P * ( 1 - p )
- NewS = S + 1
모든 프랙탈이 일반화됨에 따라 각 프랙탈은 두 가지 유형으로 나뉩니다:
- 복도의 위쪽 경계를 넘을 총 확률을 계산하는 프랙탈
- 복도의 아래쪽 경계를 넘을 총 확률을 계산하는 프랙탈
이러한 각 유형은 원본과 연계된 프랙탈 유형에 하나씩 더 대응됩니다:
- 위쪽 경계를 넘기 위한 평균 스텝 수를 계산하는 프랙탈
- 아래쪽 경계를 넘기 위한 평균 스텝 수를 계산하는 프랙탈
이 네 가지 프랙탈 유형은 합산된 숫자의 형태가 다릅니다. 확률을 수집할 때 우리는 "P*p"와 "P*(1-p)"만 더할 수 있습니다. 다른 두 프랙탈의 경우 다음 프랙탈 레벨로 넘어가기 위해 우리는 추가 변수가 필요합니다. 이 프랙탈에서는 우리는 방향이 반대인 동일한 크기의 스텝을 사용하므로 확률은 "p" 또는 "1-p"입니다. 그러나 "p"가 0.5가 아닌 경우 이는 서로 다른 특성을 가질 수 있는 두 개의 서로 다른 이벤트임을 의미합니다. 여기서 특성이란 주어진 이벤트에 대응하는 몇몇 무작위의 변수 집합을 의미합니다. 이러한 값 중 하나가 포지션 수명입니다. 이러한 값의 개수는 얼마든지 가능하며 필요한 경우 우리는 이를 시간으로 간주할 수 있습니다. 이 부분은 몇 가지 간단한 스텝을 거쳐 간소화될 수 있습니다. 합산할 수는 다음과 같은 형식을 갖습니다:
- P * p * NewS
- P * ( 1 - p ) * NewS
보시다시피 확률은 완료된 스텝 체인에 스텝 수를 곱한 값입니다. 그러나 이 공식은 위쪽과 아래쪽 스텝의 확률이 동일한 경우에만 적용됩니다. 다른 경우에는 우리는 두 개의 서로 다른 구조를 사용하여 스텝 업과 스텝 다운을 나타내거나 두 숫자를 모두 저장하는 구조를 만들어야 합니다. 두 번째 경우 프랙탈 함수는 숫자가 아닌 데이터 컨테이너를 반환합니다. 컨테이너는 확장이 필요하지 않습니다. 또한 저는 필요한 모든 매개변수를 저장할 수 있는 컨테이너를 민들었는데 이를 통해 유사한 코드로 여러 함수를 만들 필요가 없습니다. 대신 저는 필요한 모든 매개변수를 설명할 수 있는 모든 함수를 하나로 결합했습니다. 프랙탈의 유형과 프랙탈이 해결하는 작업은 함수의 입력 매개변수에 직접적으로 영향을 받습니다. 개념을 확장하려면 첫 번째 "S"와 그에 해당하는 "NewS"를 다음의 값들로 대체해야 합니다:
- SU - 선택한 확률 체인에서 최종적인 상향 스텝
- SD - 선택한 확률 체인에서 최종적인 하향 스텝
- NewSU 및 NewSD - 다음 프랙탈 레벨로 전달할 값
- SU + SD = S
이러한 값들은 "S"의 정의와 유사하게 정의되어야 합니다. "U > Middle"인 경우:
- NewSU = SU
- NewSD = SD + 1
"U < Middle"인 경우:
- NewSU = SU + 1
- NewSD = SD
프랙탈의 최종 업그레이드를 위해서는 6개의 값이 더 필요합니다:
- UpperMidSDown - 상단 경계에 도달하기 전에 내려갈 가능성이 있는 총 평균 스텝 수입니다.
- UpperMidSUp - 상단 경계에 도달하기 전에 올라갈 수 있는 총 평균 스텝 수입니다.
- UpperSummProbability - 상한 경계를 넘을 확률
- LowerMidSDown - 아래쪽 경계에 도달하기 전에 내려갈 가능성이 있는 총 평균 스텝 수입니다.
- LowerMidSUp - 아래쪽 경계에 도달하기 전에 올라갈 수 있는 총 평균 스텝 수입니다.
- LowerSummProbability - 아래쪽 경계를 넘을 확률
값 "1", "2", "4", "5"는 해당 스텝 수와 해당 확률의 곱의 합을 나타냅니다. 이러한 값은 그 자체로는 의미가 없지만 우리가 앞으로 알아볼 유용한 값의 공식의 구성 요소입니다. 값 "3"과 "6"은 완전한 그룹을 형성하는 두 경계를 넘을 가설의 확률입니다. 이러한 값을 사용하여 우리는 수많은 것들을 결정할 수 있습니다.
범용 프랙탈을 구현하는 코드 작성하기
프랙탈을 올바르게 실행하려면 우리는 프랙탈 실행 전에 모든 준비 작업을 실행해야 하고 이후 미리 정의된 규칙에 따라 프랙탈을 올바르게 실행하는 함수가 필요합니다. 저는 이 알고리즘의 MQL5적인 구현을 만들었습니다.
Container StartFractal(int m, int n, int s,double p)//preparing all variables and starting the fractal { int Minimum; if ( m <= n ) Minimum=m; else Minimum=n; double Middle; if ( n >= m ) Middle = (m+n)/2.0 - Minimum; else Middle = -((m+n)/2.0 - Minimum); double Half = (m+n)/2.0; return Fractal(Half,Middle,m,n,s,p,0,0,0,1.0); }
프랙탈 계산이 끝나면 함수는 필요한 모든 데이터가 포함된 컨테이너를 반환합니다:
struct Container//a container for collecting all the necessary data about the fractal { //values to be summed, for the upper bound double UpperMidSUp;//the sum of probabilities multiplied by the number of steps up of a specific chain (to cross the upper bound) double UpperMidSDown;//the sum of probabilities multiplied by the number of steps down of a specific chain (to cross the upper bound double UpperSummProbability;//the sum of the probabilities (to cross the upper border) //values to be summed, for the lower border double LowerMidSUp;//the sum of probabilities multiplied by the number of steps up of a specific chain (to cross the lower border) double LowerMidSDown;//the sum of probabilities multiplied by the number of steps down of a specific chain (to cross the lower border) double LowerSummProbability;//the sum of the probabilities (to cross the lower border) Container()//default constructor { UpperMidSUp=0.0; UpperMidSDown=0.0; UpperSummProbability=0.0; LowerMidSUp=0.0; LowerMidSDown=0.0; LowerSummProbability=0.0; } // void Summ(Container &c0,const Container &c1) const//full sum for operator overloading { c0.UpperMidSUp=c0.UpperMidSUp+c1.UpperMidSUp; c0.UpperMidSDown=c0.UpperMidSDown+c1.UpperMidSDown; c0.UpperSummProbability=c0.UpperSummProbability+c1.UpperSummProbability; c0.LowerMidSUp=c0.LowerMidSUp+c1.LowerMidSUp; c0.LowerMidSDown=c0.LowerMidSDown+c1.LowerMidSDown; c0.LowerSummProbability=c0.LowerSummProbability+c1.LowerSummProbability; } void operator+=(Container &c) { Summ(this,c); }//operator += overload };
이 컨테이너에는 두 개의 동일한 구조를 결합하기 위한 "+=" 연산자의 오버로드가 포함되어 있습니다. 이 부분은 메인 함수에 사용됩니다. 프랙탈 함수는 다음과 같습니다:
Container Fractal(double Half, double Middle, int m, int n, int s,double p,int SU,int SD, int U, double P)//Fractal { Container C; ///to pass to the next fractal level int NewU; int NewSU; int NewSD; double NewP; /// if ( U > Middle && SU + SD < s )//case 1 { if ( (n-1) - U > 0 ) { for ( int u=0 ; u <= (n-1) - U; u++ ) { NewU = -(n-1) + 2*u + 2*U; NewP = P * (Factorial((n-1) - U)/(Factorial(u)*Factorial((n-1) - U - u))) * pow(p,u)*pow(1.0-p,(n-1) - U - u); NewSU = SU + u; NewSD = SD + ((n-1) - U - u); C+=Fractal(Half,Middle,m,n,s,p,NewSU,NewSD,NewU,NewP); } } if ( (n-1) - U == 0 ) { NewU = U - 1; NewP = P * (1.0 - p); NewSU = SU; NewSD = SD + 1; Container ct; ct.UpperMidSDown=P*p*SD; ct.UpperMidSUp=P*p*(SU+1); ct.UpperSummProbability=P*p; C+=ct; C+=Fractal(Half,Middle,m,n,s,p,NewSU,NewSD,NewU,NewP); } } if ( U < Middle && SU + SD < s )//case 2 { if ( (m-1) + U > 0 ) { for ( int u=0 ; u <= (m-1) + U; u++ ) { NewU = -(m-1) + 2*u; NewP = P * (Factorial((m-1) + U)/(Factorial(u)*Factorial((m-1) + U - u))) * pow(p,u)*pow(1.0-p,(m-1) + U - u); NewSU = SU + u; NewSD = SD + ((m-1) + U - u); C+=Fractal(Half,Middle,m,n,s,p,NewSU,NewSD,NewU,NewP); } } if ( (m-1) + U == 0 ) { NewU = U + 1; NewP = P * p; NewSU = SU + 1; NewSD = SD; Container ct; ct.LowerMidSDown=P*(1.0 - p)*(SD+1); ct.LowerMidSUp=P*(1.0 - p)*SU; ct.LowerSummProbability=P*(1.0 - p); C+=ct; C+=Fractal(Half,Middle,m,n,s,p,NewSU,NewSD,NewU,NewP); } } if ( U == Middle && SU + SD < s )//case 3 { if ( int(MathFloor(Half))-1 > 0 ) { for ( int u=0 ; u <= int(MathFloor(Half))-1; u++ ) { NewU = -(int(MathFloor(Half))-1) + 2*u + U; NewP = P * (Factorial(int(MathFloor(Half))-1)/(Factorial(u)*Factorial(int(MathFloor(Half))-1 - u))) * pow(p,u)*pow(1.0-p,int(MathFloor(Half))-1 - u); NewSU = SU + u; NewSD = SD + (int(MathFloor(Half))-1 - u); C+=Fractal(Half,Middle,m,n,s,p,NewSU,NewSD,NewU,NewP); } } } return C; }
MetaTrader 5에서 코드를 확인한바로는 꽤 잘 작동합니다. 이 로직은 필요한 경우 더 확장될 수 있으며 아직 많은 발전 가능성이 남아 있습니다. 그러나 구현된 기능만으로도 우리의 목적에 충분하기 때문에 지금은 함수 입력 매개변수 목록을 짧게 유지하기로 하겠습니다. 코드를 주의 깊게 살펴보면 여러분은 이 코드가 위에서 설명한 수학적 원리를 완전히 준수하고 있음을 알 수 있을 것입니다. 이 코드는 짧지만 놀라운 효과를 발휘할 수 있습니다. 저는 코드에는 가능한 한 많은 논리와 수학이 포함되어야 한다고 생각합니다. 이것이 궁극적으로 우리에게 필요한 것입니다. 아무리 멋진 코드라도 우리가 의도한 목적에 맞게 사용할 수 없다면 쓸모가 없는 것입니다. 우리의 경우 목적은 거래에 적용할 수 있는지 여부입니다. 다음은 이를 확인하기 위한 로그입니다:
이 경우 저는 첫 번째 수신된 틱에서 전체 프랙탈을 계산하는 간단한 Expert Advisor를 만들었습니다. 이 계산은 한 번만 수행되므로 더 이상의 계산은 필요가 없습니다. 처음 6개의 숫자는 컨테이너의 일부이고 나머지는 이 숫자에서 파생된 숫자입니다. 여기서 저는 가장 중요한 도함수만 보여드립니다. 이를 통해 여러분이 이 여섯 가지 변수를 통해 필요한 다른 모든 변수를 수신할 수 있다는 점을 이해하는 데 도움을 드리고자 합니다. 예를 들어 '전체 그룹'을 살펴보세요. 이전 계산에 따라 경계선 중 하나에 대한 겹치지 않는 두 가설의 확률의 합이 1이어야 하기 때문에 그렇게 명명되었습니다. 이는 코드에 의해 확인됩니다. 그 뒤로 "1", "2"와 "3", "4"의 합인 두 개의 동일한 숫자가 이어집니다. 후자의 숫자는 두 번째 숫자의 합입니다 -이는 체인이 거치게 될 평균 스텝 수입니다. 제가 여기서 설정 함수의 입력 파라미터를 'm'과 'n'이 같고 대칭으로 설정한 이유는 나중에 설명하겠습니다.
대칭 프랙탈을 기반으로 첫 번째 공식 도출하기
로그 결과에 따르면 체인이 거치는 평균 스텝 수는 "4"인 경향이 있습니다. 복도는 단위 스텝에 비해 두 배가 됩니다. 단위 스텝은 'n'과 'm'이 1로 설정된 경우입니다. 다시 말해 작은 복도로 구성된 복도의 평균 스텝 수를 계산하려는 경우(이 경우 큰 복도에 정수 수의 작은 복도가 들어가고 새로운 복도도 대칭인 경우) 우리는 다음과 같이 가정할 수 있습니다:
- P[n] = P[n-1] * 2 - 새 복도가 구성되는 이전의 작은 복도 너비를 기준으로 새 복도 너비를 스텝별로 계산하는 재귀 표현식입니다.
- S[n] = S[n-1] * 4 - 새로운 복도의 평균 스텝 수를 계산하는 재귀식으로 더 작은 복도의 평균값을 통해 표현됩니다.
"P[0]=1"과 "S[0]=1"을 받아들이고 인덱스 "0"에서 재귀를 번호 매기기를 시작하면 이 재귀는 매우 유사한 두 개의 계열로 표현될 수 있습니다:
- P[n] = 2^n , n = 0 ... + infinity
- S[n] = 4^n = (2^2)^n = (2^n)^2 = P[n]^2
만약 여러분이 첫 번째 계열을 자세히 살펴보고 두 번째 계열을 올바르게 변환하면 첫 번째 계열의 요소를 사용하여 두 번째 계열을 표현할 수 있다는 것을 알 수 있습니다. 즉 우리는 다음과 같은 종속성을 얻게 됩니다: S = S(P) = P^2. 이제 이 종속성은 채널 너비를 재귀적으로 두 배로 늘리는 경우에만 참이 됩니다. 저는 이 공식을 보고 이를 임의의 큰 숫자 'n'과 'm'에 적용 가능한지 확인해보기로 했습니다. 논리적으로 두 번째 스텝에서는 "n=3", "m=3"을 설정하고 동일한 변수를 계산합니다. 이러한 입력 매개변수를 사용하면 평균 스텝 수는 "9"라는 숫자가 되는 경향이 있습니다. 여러분은 이 부분을 위의 코드를 사용하거나 아래에 첨부된 MathCad 15 프로그램을 사용하여 직접 확인할 수 있습니다. 이러한 매개변수에 대해 동일한 시리즈를 사용할 수 있습니다:
- P[n] = 3^n , n = 0 ... + infinity
- S[n] = 9^n = (3^2)^n = (3^n)^2 = P[n]^2
보시다시피 "S=S(P)=P^2"라는 동일한 관계를 얻었습니다. 우리는 간격 분할과 관련된 다른 모든 가능한 시나리오에 대해서도 동일하게 반복할 수 있지만 반드시 그럴 필요는 없습니다. 이 사실은 예를 들어 우리가 대칭 채널 내에서 가격의 평균 수명을 알고 있다면 다른 채널 내의 가격의 평균 수명을 계산할 수 있다는 것을 의미합니다. 다음과 같이 계산될 수 있습니다:
- S = S0 * K^2 - 새로운 복도의 평균 스텝 수
- T = S * T0 - 새로운 복도의 평균 수명
- T = T0 * K^2- 새로운 복도의 평균 수명을 다른 복도의 평균 수명으로 표현한 값( S0 = 1인 경우).
- S0 - 기존 복도의 평균 스텝 수
- T0 - 오래된 복도 한 스텝의 평균 수명
- P = K * P0 --> K = P/P0 - 새로운 복도가 이전 복도보다 몇 배 더 큰지 확인합니다.
- P - 새로운 복도의 너비
- P0 - 이전 복도의 너비
이제 우리는 MathCad 15를 사용하여 가설을 테스트할 수 있습니다. 먼저 이차 방정식 관계에 대한 가정을 테스트해 보겠습니다:
이제 아주 명확해 졌을 것입니다.
모든 양수 및 실수 인수에 대해 파생된 공식의 성능 평가하기
이 공식은 모든 정수 'P'에 대해 작동합니다. 하지만 float 'K'에도 사용할 수 있을까요? float "K"를 제공하는 트릭을 구현해야 합니다. 평균 수명이 알려진 가격 복도가 있고 복도 안에 "N"번 들어맞는 복도가 있지만 우리가 평균 수명은 아직 모른다고 가정해 보겠습니다. 또한 동일한 공식을 사용하여 찾을 수 있습니다. 이 논리에 따르면
- T = T0 * N^2 ---> T0 = T / N^2
- T - 평균 수명을 알고 있는 복도의 수명입니다.
- T0 - 작은 복도의 평균 수명으로, 복도는 다음과 같이 구성됩니다.
즉 우리는 더 작은 복도의 수명을 구할 수 있으며 이는 분수적인 증가 계수가 있는 세 번째 복도의 수명을 계산하는 데 필요합니다. 이제 가장 작은 복도의 수명을 찾았으므로 그 너비를 점으로 구할 수 있습니다:
- d = P / N
이후 다음과 같은 비율을 사용하여 넓어진 복도에 몇 개의 복도가 들어갈 수 있는지 계산할 수 있습니다:
- Smin = MathFloor( K * P / d ) = MathFloor( K * N )
- Lim( N --> + infinity ) [ K * N/MathFloor( K * N ) ] = 1
보시다시피 복도 폭이 줄어들고 있으며 결과에는 영향을 미치지 않습니다. 두 번째 줄은 다음에 수행할 작업을 이해하는 데 도움이 되는 매우 중요한 비율을 보여줍니다. 이부분은 우리가 소스 복도를 가능한 많은 세그먼트로 분할하면 MathFloor 함수의 결과로 버려지는 분수 부분을 무시할 수 있다는 것을 보여줍니다. 이는 통일성을 향한 한계 경향으로 나타납니다. 만약 이것이 부정확한 값으로 혼란스러우면 우리는 다른 값을 찾을 수 있습니다:
- Smax = MathFloor( K * P / d ) + 1 = MathFloor( K * N ) + 1 = Smin + 1
이제 "K * N"의 실제 값은 "Smin"과 "Smax" 사이에 있습니다. "N"이 무한대인 경우 매우 유사한 두 개의 복도가 생기고 크기가 한 세그먼트만 다르기 때문에 이 복도들의 평균 수명은 동일해지는 경향이 있습니다. 따라서 필요한 복도의 평균 수명은 이러한 복도의 평균 수명의 산술 평균에 의해 더 정확하게 결정됩니다:
- T1 =( T0 * Smin^2+ T0 * Smax^2) / 2 = T0 *( Smin^2+ Smax^2) / 2
- T1 - 우리가 결정해야 하는 복도의 평균 수명입니다.
다음 그림은 제 아이디어에 대해 설명합니다:
이제 우리는 복도의 수명을 계산하는 대체 식을 찾았습니다. 그러므로 정수 'K'에 대한 함수 값과 그 결과를 비교하고 대신 실수 'K'로 대체할 수 있습니다. 두 표현식의 결과 값이 동일하다면 우리는 정수 "K" 값에 대해 찾은 함수가 "0 ... + infinity" 범위의 모든 정수와 부동 소수점에 절대적으로 적용 가능하다는 결론을 내릴 수 있습니다. "N = 1000"에 대한 첫 번째 확인을 해 보겠습니다. 이 분할을 통해 두 숫자가 동일한지를 충분히 알 수 있을 것 같습니다, 만약 실제 그렇다면 말입니다:
보시다시피 두 숫자는 거의 동일합니다. 논리적으로는 'N' 값이 클수록 이 숫자는 더 동일해야 합니다. 이는 다음과 같은 가정을 통해서도 증명할 수 있습니다:
- Lim( N --> +infinity ) [ (T0 *( Smin^2 + Smax^2 ) / 2) / ( T * K^2 ) ] = 1
이 제한의 분자는 새로운 복도의 평균 수명을 계산하기 위한 대략적인 식이며 분모는 동일한 값을 정확하게 설명할 수 있는 식입니다. 저는 이전 스크린샷과 동일한 계산을 수행하는 간단한 함수를 만들었습니다. 하지만 이번에 이 함수는 '1'로 시작하는 'N' 의 전체 범위에 적용됩니다. 이제 프로그램 실행 결과를 확인해 보겠습니다:
모든 가정이 완전히 확인되었습니다: 정수 'K'에 대해 우리가 찾은 함수는 모든 양수 'K'에 절대적으로 적용 가능합니다. 이제 우리는 전체 범용적인 프랙탈을 설명하기 위한 수학의 기초와 같은 추가 작업의 기초로 사용될 수 있는 매우 유용한 단일 함수를 갖게 되었습니다.
범용 프랙탈에서 발전한 고급 프랙탈
범용 프랙탈의 추가 적용에 대한 유용하인 예로, "n=1", "m ---> + infinity", "s = m+1", "p=0.5"와 같은 1경계 프랙탈을 예로 들어볼 수 있습니다. 지금까지 우리는 랜덤 워크에만 적용 가능한 양방향의 동일한 확률의 스텝을 가진 프랙탈을 고려하고 있습니다. 하지만 이 프랙탈은 모든 가능성을 가지고 있습니다. 이러한 복잡한 구조에 대한 심층적인 분석으로 이동하려면 먼저 기본 사항을 고려해야 합니다. 또한 이 초기 스텝에서 우리는 유용한 공식을 얻고 이러한 프랙탈 프로세스에 대한 근본적인 결론을 내릴 수 있습니다. 저는 다른 "s" 값으로 프랙탈을 테스트한 결과 다음과 같은 데이터를 얻었습니다:
- s = 22 , FullSumm = 2.868 , UpperSummProbability = 0.831
- s = 32 , FullSumm = 3.618 , UpperSummProbability = 0.860
- s = 42 , FullSumm = 4.262 , UpperSummProbability = 0.877
- s = 45 , FullSumm = 4.499 , UpperSummProbability = 0.882
허용되는 스텝 수가 더 증가하면 계산 시간의 특이점, 즉 계산 시간이 너무 많이 증가하여 몇 시간 또는 며칠이 소요될 수 있습니다. 그러나 평균 확률 합이 증가하는 속도를 보면 여러분은 이러한 유형의 프랙탈을 사용하여 이 수열의 수렴을 평가할 수 없다는 것을 알 수 있을 것입니다. 하지만 앞서 도출한 공식을 기반으로 우리는 이전과는 다르면서도 매우 유용한 프랙탈 유형을 사용하여 컨버전스를 평가할 수 있습니다. 이 프랙탈은 "Carry trade"라는 매우 인기 있고 수익성 있는 전략의 시간을 계산하는 데도 도움이 될 수 있습니다. 먼저 그림을 보여드린 다음 설명하겠습니다:
가격 책정 프로세스가 경계의 위쪽이든 아래쪽이든 경계에서 한 스텝부터 시작된다고 가정해 보세요. 위 그림은 경계가 더 낮은 예시를 보여 주므로 더 쉽게 인식할 수 있습니다. 첫 번째 프랙탈을 자세히 살펴보세요. 각각의 회색 상자에는 추가 이벤트에 대한 두 가지 시나리오가 포함되어 있습니다:
- 가격이 상자 상단 가장자리에 도달했습니다.
- 가격이 상자 하단 가장자리에 도달했습니다.
가격이 복도의 상단 경계에 도달하면 이 지점에서 새로운 더 큰 프랙탈이 자동으로 시작되는 식으로 진행됩니다. 이 과정을 범용 프랙탈에서와 같은 방식으로 사용하면 우리는 확률 체인을 다시 볼 수 있습니다. 그러나 이제 우리의 공식은 복도에 몇 개의 스텝이 들어가는지에 따라 대칭 복도에 몇 개의 스텝을 만들 것인지를 알려줍니다(이제 한 스텝이 원래 복도에 들어가는 더 작은 복도라는 것을 알 수 있습니다).
이제 평균 스텝 수를 계산하기 위해 전체 프랙탈을 고려할 필요가 없습니다. 대신 도출된 공식을 각 프랙탈에 적용합니다. 여기서 스텝은 동일한 값은 아니지만 스텝은 다음 중첩 프랙탈의 상한 또는 하한에 도달할 때 만들어집니다. 이를 기반으로 매우 간단한 확률 체인을 만들 수 있습니다. 첫 번째 프랙탈 P[0]에서 경계에 도달할 확률은 0.5입니다. 이는 우리가 가격이 경계에 도달하기를 바라며 다음 프랙탈을 만들어야 하는 두 번째 가능한 경우가 있다는 뜻입니다. 이러한 모든 이벤트는 중첩되어 있으며 이러한 모든 체인은 완전한 그룹을 형성합니다.
두 번째 프랙탈 P[1]에서 바운드에 도달할 확률은 이전 확률에 0.5를 곱한 값과 같습니다. 이 프로세스는 무기한으로 계속될 수 있습니다. 평균 스텝 수는 도출된 공식과 체인 확률을 사용하여 결정할 수 있습니다. 이를 위해 먼저 상한선을 넘을 때와 하한선을 넘을 때의 평균 스텝 수가 같다는 점을 고려하여 각각의 개별 체인의 확률에 대한 공식을 정의합니다. 다음과 같습니다:
- PUp = PDown = P - 이 비율은 프랙탈의 상한과 하한에 닿을 확률이 중첩된 모든 프랙탈의 모든 경계에 대해 동일하다는 것을 보여줍니다.
- P[j] = 0.5^(j+1), j = 0 ... + infinity - 체인 j가 발생할 확률
- S[i] = S[i-1] + P[i] * ( S[i-1]/P[i-1] + F(D[i]) ), i = 1... + infinity - 모든 프랙탈 레벨에 대해 평균적으로 가능한 총 스텝 수를 계산하는 반복 공식( S[0] = 1*0.5 = 0.5)
- F(K) = K^2 - 평균 스텝 수를 계산하기 위해 파생된 공식
- D(i) = 2^i - 다음 프랙탈 레벨에 맞는 스텝 수
- S[i-1]/P[i-1] - 현재 분기가 발생한 경우 나머지 설명되지 않은 분기의 평균 스텝 수(현재 중첩 프랙탈 외에도 이전에 발생한 모든 스텝을 고려해야 하므로).
두 번째 프랙탈은 실제로 첫 번째 프랙탈과 동일합니다. 즉 체인(P[] array)의 확률이 동일합니다. 왜 이것이 필요할까요? "Carry Trade" 전략이 있다고 가정해 보겠습니다. 우리에게는 포지션을 포지티브 스왑으로 고정하기 위한 스왑 계좌와 스왑 프리 계좌 두 가지가 있습니다. 또한 수익성 포지션 평균 보유 기간을 계산하는 공식이 필요합니다. 이 평균 유지 시간은 평균 스텝 수 공식에서 직접적으로 도출됩니다. 이 글에서는 저는 이 문제를 자세히 다루지는 않겠습니다. 저는 단지 수학의 중요성을 보여주고 싶습니다. 이 주제에 대해서는 나중에 자세히 다루어질 것입니다. 이제 두 번째 프랙탈의 평균 확률 스텝에 대한 공식을 정의해 보겠습니다:
- S[j] = S[j-1] + P[j] * ( S[i-1]/P[i-1] + F(1) ) - 모든 프랙탈 레벨에 대해 평균적으로 가능한 총 스텝 수를 계산하는 반복 공식입니다( S[0] = 1*0.5 = 0.5).
이 경우 이 공식은 모든 프랙탈 레벨에 대해 항상 두 번째 프랙탈 K=1이기 때문에 중요한 공식의 특수한 경우에만 해당합니다. 두 프랙탈에 대해 이 수량의 합의 한계가 무엇인지 알아봅시다:
첫 번째 수열은 상한이 없고 거래가 끝이 없을 때 평균 시간이 무한대와 같다는 것을 의미합니다. 두 번째 경우에는 2와 같은 명확한 한도를 얻습니다. 즉 우리가 포지션을 포지티브 스왑으로 오픈하면 평균적으로 두 스텝 후에 포지션을 청산해야 합니다(따라서 평균 포지션 유지 시간은 2*T와 같으며 여기서 T는 포지션이 경계 중 하나에 도달했을 때 청산하는 경우의 평균 포지션 유지 시간입니다). 두 번째fh 가장 간단한 경우는 스왑 계좌에 양수가 표시되더라도 우리가 두 계좌의 포지션을 모두 청산하면 됩니다. 물론 첫 번째 옵션이 훨씬 더 매력적이지만 이를 구현하려면 두 계정 모두에서 빠르고 원활한 출금과 입금이 필요합니다. 이 옵션이 불가능하면 수익은 적지만 안정성이 높은 고전적 옵션을 사용해야 합니다.
결과 요약
기사의 시리즈의 두 번째 부분에서 우리는 트레이딩에 실제로 적용할 수 있는 결과를 포함하여 매우 흥미로운 결과를 얻었습니다. 더 중요한 것은 이제 프랙탈을 적용할 수 있는 영역이 매우 넓다는 점입니다. 우리가 수행한 작업
- 범용 프랙탈을 구축하기 위한 명확한 수학적 규칙 정의
- 명시된 수학적 원리를 기반으로 작동하는 MQL5 스타일 코드를 생성
- MetaTrader 5와 MathCad 15의 두 가지 플랫폼을 사용하여 작동하는 원리를 성공적으로 확인
- 알고리즘을 사용하여 임의의 복도의 수명을 계산하는 첫 번째 공식을 얻음
- 가능한 모든 경우에 대해 프로그래밍을 사용하여 수식을 테스트하고 검증
- 얻은 공식을 기반으로 새로운 유형의 빠른 프랙탈을 얻음
- 그 결과 계산 속도를 높이고 범용 프랙탈로 결정할 수 없는 것을 결정
- 스왑 거래 문제에 고급 프랙탈을 사용하는 특별한 사례
- 이론의 추가적인 개발을 위한 도구 확보
또한 저의 도구 상자가 크게 확장되었다는 점도 주목하고 싶습니다. 이제 우리는 다양한 확률 스텝(추세 상황 및 트레이딩 통계 분석과 관련된 상황)으로 프랙탈을 분석할 수 있습니다. 다시 한번 말씀드리지만 이 글에서는 "p = 1 - p = q = 0.5"인 경우만 고려했다는 점을 참고하시기 바랍니다. 즉 모든 계산은 무작위 걷기를 설명하는 상황에만 적용 가능합니다. 따라서 훨씬 더 많은 잠재적 가능성이 있습니다.
아래는 프랙탈을 연구한 후 얻은 공식입니다. 다시 한번 간략하게 설명해 드리겠습니다:
- S = K^2 - 한 스텝이 다른 스텝과 같다는 사실에 기반한 새로운 복도의 평균 스텝 수입니다.
- T = S * T0 = T0 * K^2 알 수 없는 복도의 평균 수명
- T0 - 알려진 복도의 평균 수명
- P = K * P0 --> K = P/P0 - 알려진 복도가 알려지지 않은 복도 보다 몇 배 더 큰지 알 수 있습니다.
- P - 수명을 알 수 없는 복도의 폭입니다.
- P0 - 알려진 복도의 폭
4를 1에 대입하면 우리는 알려진 값을 통해 미지의 복도에 있을 평균 스텝 수를 표현할 수 있고 1을 2로 대입하면 알려진 값을 기반으로 계산된 이 복도의 평균 수명을 구할 수 있습니다:
- T0, P0, P
또한 이 글의 시작 부분에서 독자들이 궁금해할 수 있었던 질문에 대한 답변도 추가하겠습니다:
- MetaTrader 5 전략 테스터에서 트레이딩 통계를 수집할 수 있는데 왜 공식이 필요할까요?
응답:
- 모든 금융 종목에 대해 이러한 평가에 필요한 충분한 거래 내역이 있는 것은 아니므로 통계를 수집하는 것이 항상 가능한 것은 아닙니다. 대형 복도의 경우 경계를 넘어 본 적이 없는 복도를 선택할 수 있기 때문에 불가능합니다. 폭이 작은 복도와 공식을 사용하면 우리는 통계에서 얻을 수 없는 데이터를 얻을 수 있습니다. 또한 이러한 종류의 수학은 타의 추종을 불허하는 정확성과 유연성을 가집니다. 이 외에도 훨씬 더 많은 이점이 있습니다.
결론
이 글에서 저는 가격 책정 프로세스에 관한 추가적인 연구를 수행하는 데 사용할 수 있는 계산 로직을 설명하려고 했습니다. 아직까지는 실용적으로 적용할 수 있는 부분이 많지 않습니다. 그러나 저는 우리가 범용 프랙탈의 모든 종류를 연구하고 비대칭 한 경계 가격 복도를 설명하는 가능한 공식을 얻을 수 있다고 확신합니다. 다음 기사에서 저는 범용 프랙탈에 대해 계속 연구하고 모든 결과를 간단한 공식으로 제시하려고 노력할 것입니다. 또한 가격 책정 프로세스뿐만 아니라 백 테스트 및 거래 신호를 설명하는 데에도 우리가 얻은 공식을 사용할 수 있는 새롭고 매우 흥미로운 수학에 대해서도 알아볼 것입니다. 이를 통해 우리는 트레이딩에서 궁극적으로 가장 중요한 요소인 시간과 확률 측면에서 모든 전략을 절대적으로 정확하게 분석할 수 있습니다.
참조
MetaQuotes 소프트웨어 사를 통해 러시아어가 번역됨.
원본 기고글: https://www.mql5.com/ru/articles/9511