English Русский 中文 Español Deutsch 日本語 Português Français Italiano Türkçe
매매 전략 다목적 엑스퍼트 어드바이저

매매 전략 다목적 엑스퍼트 어드바이저

MetaTrader 5트레이딩 | 5 7월 2021, 11:40
121 0
Dmitry Fedoseev
Dmitry Fedoseev

 

개요

모든 매매 전략의 기초는 가격 및 기술적 지표의 분석입니다. 이는 포지션을 오픈하는 데에 기반이 되죠. 이것을 시장 분석라고 부르는데요. 시장에서 일어나는 모든 행위와 우리가 통제하지 못하는 모든 것이 여기에 포함됩니다.

이 밖에 또 다른 분석이 필요한 경우도 있습니다. 현재 거래 상황 분석라는 건데요. 거래 포지션 형태에 대한 분석과 대기 주문이 있는 경우 모든 대기 주문에 대한 분석을 포함합니다. 이런 분석을 통해 포지션 및 주문 관련 결정을 내리는 것이죠. 예를 들어 포지션 청산이라든지, 손절매 이동, 대기 주문 설정 및 삭제 등 말입니다. 다시 말해 분석은 시장 활동, 즉 우리가 (혹은 엑스퍼트 어드바이저가) 만들어 낸 상황에 따른 액션 및 사용되는 전략의 규칙에 대해 연구하는 것입니다.

많이들 알고 계시는 추적 손절매도 어떻게 보면 아래의 두 번째 요소에 속한다고 볼 수 있죠. 다음을 생각해 볼까요? 설정 값보다 높은 수익을 창출하는 포지션이 오픈되어 있으나 손절매가 설정되어있지 않거나 현재 가격에서 설정된 거리보다 먼 곳에 위치하는 경우, 손절매 주문이 취소됩니다.

이때 추적 손절매는 눈길이 갈만한 동시에 꽤 간단한 기능이죠. 게다가 포지션 관리 기능이므로 완전히 다른 매매 전략 카테고리로 분류됩니다. 따라서 매매 전략은 다음의 세 가지 요소로 구성됩니다:

  1. 시장 분석 및 시장 분석 결과를 기반으로 하는 투자 행위.

  2. 시장 상황 분석 및 시장 상황 분석 결과를 기반으로 하는 투자 행위.

  3. 포지션 관리.

이 글은 대기 주문을 활용하는 전략(이하 매매 전략) 및 해당 전략 개발에 사용되는 Metalanguage, 그리고 그 Metalanguage를 기반으로 작동하는 다목적 도구(엑스퍼트 어드바이저)에 관한 글입니다.

 

매매 전략 예시

보통 초기 포지션 오픈이 매매의 시작점이 됩니다. 여기에는 다음과 같은 여러 방법이 있는데요.

  1. 시장에 포지션 오픈하기

    • 인디케이터가 나타내는 방향을 따라 오픈.

    • 엑스퍼트 어드바이저에서 사용자가 선택한 방향을 따라 오픈.

    • 마지막 포지션 청산 결과에 따라 오픈. 초기 포지션이 아닌 중간 운용 단계에 해당.

  2. 서로 다른 방향의 두 가지 스탑오더 설정. 둘 중 한 오더가 체결되는 경우 나머지 하나는 취소됨.

  3. 서로 다른 방향의 두 가지 리미트오더 설정. 둘 중 한 오더가 체결되는 경우 나머지 하나는 취소됨.

  4. 리미트오더와 스탑오더가 동일한 방향으로 설정된 경우. 1의 경우처럼 방향 설정이 필요.

한번 포지션을 오픈하고 나면 다양한 매매 전략을 사용해 볼 수 있습니다.

리미트오더를 이용한 스케일링(그림 1.)

초기 포지션 오픈 후 랏 크기가 증가된 동일한 방향의 리미트오더를 하나 이상 설정합니다. 리미트오더가 발동하면, 이익실현 설정 가격에서 포지션이 청산될 때까지 계속해서 새로운 리미트오더가 설정됩니다. 이익실현 설정 가격에서 포지션이 청산될 경우 남은 대기 주문은 취소됩니다.

그림 1.  리미트오더를 이용한 스케일링
그림 1. 리미트오더를 이용한 스케일링

SAR(그림 2.)

초기 포지션 오픈 후 손절가에서 랏 크기가 증가하는 스탑오더를 설정합니다. 손절가에서 포지션이 청산되면 대기 주문이 실행되며 새로운 스탑오더가 손절가에서 설정되어 포지션이 청산될 때까지 반복됩니다. 이익실현 설정 가격에서 포지션이 청산될 경우 남은 대기 주문은 취소됩니다.

그림 2. SAR
그림 2. SAR

피라미딩(그림 3.)

초기 포지션 오픈 후 수익 발생 시 비중을 확대하고 스탑오더 가격을 최초 진입가로 설정합니다. 이익실현 설정 가격에서 포지션이 청산될 경우 포지션 사이즈와 그에 따른 수익이 상당할 수 있습니다. 그러나중간 단계에서 스탑오더 발생 시 수익은 없습니다.

그림 3. 피라미딩
그림 3. 피라미딩

리오프닝(그림 4.)

포지션을 오픈합니다. 스탑오더로 포지션 청산 후 랏 크기가 증가된 포지션을 오픈하고 이를 이익실현 시까지 반복합니다. 리미트오더를 이용한 스케일링과 비슷하죠.

그림 4. 리오프닝
그림 4. 리오프닝

언급된 모든 전략을 결합시킬 수도 있습니다. 수익이 창출되는 포지션의 경우 피라미딩이 편리하게 쓰입니다. 반대로, 손실이 있는 경우 리미트오더를 이용한 스케일링이 보다 효과적일 수 있습니다. 하지만 리미트오더를 이용한 스케일링을 계속 사용할 필요는 없죠. 예를 들어, 처음 세 번은 스케일링을 사용하고, SAR도 몇 번 사용하다가, 다시 리미트오더를 이용한 스케일링을 사용할 수도 있습니다.

실제로 매매 전략 개발 시 코딩 과정 뿐만 아니라 케이스에 따른 창의적 전략 구상에 많은 시간이 소요됩니다. 어떤 매매 전략이라도 실행할 수 있게 해주는 다목적 엑스퍼트 어드바이저를 만들어서 전략 수립에 소모되는 시간을 줄여 보도록 할게요.

 

기본 원칙

매매 기술 개발의 기본 원칙은 현재 사용 중인 기술의 운용 단계를 확인하고 그에 따른 작전을 수행하는 것이죠.

다음의 예를 볼까요? 포지션을 오픈해야 하는데, 매매 포지션이 다음과 같다고 가정해 볼게요. 일단 포지션을 오픈하고 나면 두 가지 대기 주문을 설정해야 합니다. 스탑오더와 리미트오더죠. 포지션을 오픈하거나 주문을 실행한 적이 없는 상태이니 포지션 오픈이 필요한 초기 운용 단계라고 볼 수 있습니다. 이미 시장에 오픈된 포지션이 있다면 그 다음 운용 단계가 되는 것이죠. 따라서 운용 단계는 다음과 같이 나눌 수 있습니다.

  1. 포지션 또는 주문이 설정되지 않은 경우. 포지션 오픈 필요.

  2. 포지션은 오픈했으나 설정된 주문이 없는 경우. 스탑오더가 필요.

  3. 포지션이 오픈되었으며 스탑오더도 설정된 경우. 리미트오더가 필요.

위의 규칙을 따르면 신뢰할 수 있는 결과가 나올 겁니다. 다만 세 가지 틱이 필요한데요. 첫 번째는 포지션이 없는 경우 포지션 오픈을 위해, 두 번째는 포지션은 있으나 주문이 없는 경우를 위해, 그리고 세 번째는 이미 존재하는 포지션과 주문을 확인하기 위함입니다. 이 세 가지는 동시에 수행되어야 합니다.

한번 동시에 실행시켜 볼게요: 포지션 또는 주문이 설정되지 않은 경우, 포지션을 오픈해야 합니다. 성공적으로 포지션이 오픈되었다면, 스탑오더와 리미트오더를 각각 요청해야 합니다. 대기 주문 설정 요청이 승낙되지 않을 수도 있습니다만(연결 문제, 가격 정보 부족 등) 일단 포지션이 오픈된 새로운 단계로 넘어가게 됐습니다. 그렇다면 이번에는 모든 중간 과정 시나리오를 살펴보아야 겠죠:

  1. 포지션이 없는 경우. 포지션 오픈 필요. 성공적으로 포지션이 오픈된 경우 스탑오더와 리미트오더를 각각 요청할 것.

  2. 포지션은 있으나 설정된 대기 주문이 없는 경우. 스탑오더와 리미트오더를 각각 요청할 것.

  3. 포지션이 오픈되고 스톱오더가 설정되었으나 리미트오더가 없는 경우. 리미트오더를 요청할 것.

  4. 포지션이 오픈되고 리미트오더가 설정되었으나 스톱오더가 없는 경우. 스톱오더를 요청할 것.

해당 예시의 운용 단계 판단 시 거래 상황이 위의 규칙과 완전히 동일해야 함을 유의하세요. 한 가지 포지션이 있고 주문이 없는 경우 또는 포지션이 있고 두 가지 중 한 가지 주문만 있는 경우의 두 가지 경우만이 발생 가능합니다. 이러한 원칙을 따르는 전략 운용 단계의 설명은 매우 복잡한 데다가 가능한 경우를 하나하나 확인하다 보면 소요 시간도 늘어나기 때문에 전략 실행이 불가능할 수도 있습니다. 그래서 약간 다른 방법으로 위의 예시에 해당하는 운용 규칙을 살펴볼까 해요:

  1. 포지션이 없는 경우. 포지션 오픈 필요. 성공적으로 포지션이 오픈된 경우 스탑오더와 리미트오더를 각각 요청할 것.

  2. 포지션이 있는 경우. 이 경우, 두 가지 대기 주문이 설정된 상태여야 함. 스탑오더가 있는지 확인 후 없을 경우 설정할 것. 리미트오더가 있는지 확인 후 없을 경우 설정할 것.

이 경우에 사용될 수 있는 운용 단계 식별용 몇 가지 최소 규칙과 단계별 해당 거래 상황에 대한 완벽한 설명을 만들었습니다.

해당 원칙을 적용하기 위해서는 현재 포지션이 최초 포지션인지 혹은 이미 발동한 주문이 있는지를 확인해야 합니다. 시스템이 새로운 운용 단계에 있으므로 두 번째 주문을 설정할 필요는 없죠. 주문의 종류도 식별해야 하는데 우선은 포지션에 대해 알아보기로 하겠습니다. 매매 전략 코딩 기본 원칙을 좀 더 간략하고 이해하기 쉬운 방법으로 설명해 드릴게요:

  1. 최소한의 방법으로 현재 운용 단계를 식별할 수 있는 방법이 필요합니다.

  2. 각각의 운용 단계에 부합하는 상황에 대한 설명이 있어야 하고요.

  3. 시장의 움직임(개장, 폐장, 스케일링 등) 또는 대기 주문이 요구되는 단계는 두 가지 하위 단계로 분류합니다: 시장 움직임 전과 후 (한번에 모두 실행하고 대기 주문 실패 시 재실행 가능하도록)

  4. 시장의 움직임(개장, 폐장, 스케일링 등) 또는 대기 주문이 요구되는 단계의 경우, 대기주문은 시장 움직임 완료 후 실행됩니다.

  5. 하나의 단계는 하나의 시장 움직임 또는 복수 개의 대기 주문에 해당합니다.

 

주문 및 포지션 식별

포지션과 주문은 다음의 방법으로 식별 가능합니다: 주석, 매직 넘버 또는 전역 변수. 주석을 사용해 보겠습니다. 주석 사용의 가장 큰 문제는 글자수에 제한이 있는데 브로커가 내용을 추가할 수 있다는 점이죠. 남은 공간이 부족하면 브로커의 주석이 잘리고 맙니다.

그렇기 때문에 최소한의 주석을 남기고 브로커의 주석과 분리할 수 있는 방법을 강구해야 하는데요. 각각의 주문은 단 하나의 식별자만을 필요로 합니다. 실제 사용되는 식별자는 숫자 한 두개 또는 알파벳 하나와 숫자 한 두개가 혼합된 경우가 많습니다. 식별자 끝에는 마킹을 할 거예요. 예를 들어 '='를 넣는다고 하죠(브로커들이 거의 사용하지 않는 것 같아서 골랐어요.) 최대 4자까지인데요. 주석에서 식별자를 구하기 위해서는 다음과 같은 함수를 사용할 수 있습니다:

//+------------------------------------------------------------------+
//|   Function for obtaining the identifier from the aComment string |
//+------------------------------------------------------------------+
string GetID(string aComment)
  {
   int    p =StringFind(aComment,"=",0); // Determine the position of the separator
   string id=StringSubstr(aComment,0,p); // Get the substring located before the separator
   return(id);
  }
//+------------------------------------------------------------------+

식별자를 이용해 포지션 또는 주문을 확인해야 하는 경우 다음을 따라해 보세요:

//+------------------------------------------------------------------+
//|   Checking the comment against the set identifier                |
//+------------------------------------------------------------------+
bool FitsID(string aID,string aComment)
  {
   return(StringFind(aComment,aID+"=",0)==0);
  }
//+------------------------------------------------------------------+

 

Metalanguage를 이용한 매매 전략 작성

매매 전략 작성에 쓰이는 언어에 대해 알아 볼게요. 간결하고, 명확하며, 직관적인 동시에 MQL5 형식에 부합하여 불필요한 연산 없이 빠른 실행이 가능해야 합니다. 결과가 어떤지는 말하지 않아도 아실 거예요.

전략은 텍스트 파일에 작성한 후 엑스퍼트 어드바이저 설정창에서 지정해 엑스퍼트 어드바이저로 연결되도록 합니다.

파일 내 행 하나가 하나의 운용 단계에 해당하죠. 각 행은 두 개의 필드로 나뉘어 있는데요. 첫 번째 필드는 단계 식별 규칙을 나타냅니다. 두 번째 필드는 거래 행위에 관한 설명이죠. 두 필드는 세로줄 '|'로 나뉘어 있습니다. 식별 규칙과 거래 행위 항목은 ';'로 구분됩니다.

명령 이외에도, 각 행의 오른쪽에 '#'로 분리되는 주석을 추가할 수 있습니다. 예:

Nothing | Buy(M1,1,0,0) #If there is no position or order in the market, open a Buy position, mark it with "М1", lot 1, no Stop Loss, no Take Profit.

 

단계 식별

단계 식별에는 현재 포지션, 대기 주문 또는 지난 거래 등에 대한 정보가 필요할 수 있습니다. 포지션의 형태와 더불어 가격, 수익, 손절가 등 기타 세부 정보가 요구될 수도 있고요. 지난 거래에 대한 정보는 거래 결과를 의미할 수도 있겠죠. 대기 주문의 경우, 시초가, 손절가, 이익실현가(주로 실행 단계) 등의 구체적인 정보가 필요할 수 있습니다.

이런 정보는 거래 데이터 액세스 명령을 통해 얻을 수 있습니다. 여기에 필요한 명령은 대부분 두 가지 매개 변수를 갖는데요. 포지션 또는 주문 식별자와 매개 변수 식별자입니다. 매개 변수 식별자가 지정되지 않은 경우, 명령 및 식별자로 지정된 거래 대상의 존재만 확인 가능합니다.

예를 들어 명령어 Buy(M1)은 식별자 'M1'을 갖는 포지션이 있음을 의미하죠. Buy() 명령이 혼자 쓰이는 경우(혹은 괄호 없이 Buy만 쓰이는 경우), 불특정 식별자를 갖는 포지션이 있음을 의미합니다. 매개 변수 식별자를 특정하면 매개 변수 값을 나타낼 수 있습니다. 예: Buy(M1,StopLossInPoints) - 'M1' 식별자를 갖는 매수 포지션에 대한 손절가. 특정한 식별자가 없는 경우 - Buy(,StopLossInPoints), 불특정 식별자를 갖는 매수 포지션에 대한 손절매만으로 간주합니다(매수 포지션이 있는 경우).

획득 값은 조건 검사에 사용됩니다. 예: Buy(M1,StopLossInPoints)>=0 - 해당 포지션의 손익분기점. 포지션이 없거나 식별자가 다른 포지션이 있는 경우에는 식별되지 않습니다. 즉, 두 가지 조건을 한번에 검사할 수는 없는거죠. 그러나 해당 경우 손절매 여부를 미리 확인해야 할 필요는 있죠. - Buy(M1,StopLossExists); Buy(M1,StopLossInPoints)>=0.

입력 값 확인 시에는 모든 부등호를 사용할 수 있습니다: '>=', '<=', '==', '!=', '>', '<'. 부등호 오른쪽에 위치하는 값은 숫자 또는 Var1, Var2 등의 특수 변수로 나타낼 수 있습니다. Var20도 가능하죠. 숫자 또는 변수에 'p'가 붙게 되면 해당 값에 포인트 값이 곱해집니다(_포인트 변수).

부등호 오른쪽에는 보다 복잡한 연산이 올 수도 있습니다. 예: X1*X2+X3*X4 (물론 '+' 대신 '-'도 사용 가능), X1, X2, X3과 X4는 숫자, 변수 또는 데이터 액세스 명령. 하단의 예시는 이론적으로 옳다고 볼 수 있습니다(실용성은 없지만요).

-BuyStop(BS1,StopLossInPoints)*-SellLimit(SL1,StopLossInPoints)+-SellStop(SS1,StopLossInPoints)*-BuyLimit(SL1,StopLossInPoints)

표 1은 사용 가능한 모든 액세스 명령을 나타냅니다.

표 1. 데이터 액세스 명령

인덱스 명령 설정 가능 매개 변수 목적
0 Nothing 매개 변수 없음 포지션 또는 대기 주문 없음
1 NoPos 매개 변수 없음 포지션 없음
2 Pending 객체 식별자, 주문 매개 변수 식별자 해당 객체 식별자를 포함하는 모든 대기 주문 식별. 특정한 객체 식별자가 없는 경우 객체 식별자와 관계 없이 모든 대기 주문 식별
3 Buy 객체 식별자, 포지션 매개 변수 식별자 해당 객체 식별자를 포함하는 매수 포지션 식별. 특정한 객체 식별자가 없는 경우 존재하는 매수 포지션 식별
4 Sell 객체 식별자, 포지션 매개 변수 식별자 해당 객체 식별자를 포함하는 매도 포지션 식별. 특정한 객체 식별자가 없는 경우 존재하는 매도 포지션 식별
5 BuyStop 객체 식별자, 주문 매개 변수 식별자 해당 객체 식별자를 포함하는 역지정가 매수 주문 식별. 특정한 객체 식별자가 없는 경우 존재하는 역지정가 매수 주문 식별
6 SellStop 객체 식별자, 주문 매개 변수 식별자 해당 객체 식별자를 포함하는 역지정가 매도 주문 식별. 특정한 객체 식별자가 없는 경우 존재하는 역지정가 매도 주문 식별
7 BuyLimit 객체 식별자, 주문 매개 변수 식별자 해당 객체 식별자를 포함하는 지정가 매수 주문 식별. 특정한 객체 식별자가 없는 경우 존재하는 지정가 매수 주문 식별
8 SelLimit 객체 식별자, 주문 매개 변수 식별자 해당 객체 식별자를 포함하는 지정가 매도 주문 식별. 특정한 객체 식별자가 없는 경우 존재하는 지정가 매도 주문 식별
9 BuyStopLimit 객체 식별자, 주문 매개 변수 식별자 해당 객체 식별자를 포함하는 스탑-리밋 매수 주문 식별. 특정한 객체 식별자가 없는 경우 존재하는 스탑-리밋 매수 주문 식별
10 SellStopLimit 객체 식별자, 주문 매개 변수 식별자 해당 객체 식별자를 포함하는 스탑-리밋 매도 주문 식별. 특정한 객체 식별자가 없는 경우 존재하는 스탑-리밋 매도 주문 식별
11 LastDeal 빈 값, 거래 매개 변수 식별자 직전 매매
12 LastDealBuy 빈 값, 거래 매개 변수 식별자 직전 매매가 매수 거래인 경우
13 LastDealSell 빈 값, 거래 매개 변수 식별자 직전 매매가 매도 거래인 경우
14 NoLastDeal 매개 변수 없음 매매 기록 없음; 엑스퍼트 어드바이저를 처음 실행하는 경우 필요
15 SignalOpenBuy 매개 변수 없음 매수 포지션 오픈 인디케이터 시그널
16 SignalOpenSell 매개 변수 없음 매도 포지션 오픈 인디케이터 시그널
17 SignalCloseBuy 매개 변수 없음 매수 포지션 청산 인디케이터 시그널
18 SignalCloseSell 매개 변수 없음 매도 포지션 청산 인디케이터 시그널
19 UserBuy 매개 변수 없음 사용자 매수 명령
20 UserSell 매개 변수 없음 사용자 매도 명령
21 Bid 매개 변수 없음 매수호가
22 Ask 매개 변수 없음 매도호가
23 ThisOpenPrice 매개 변수 없음 매개 변수가 계산된 주문의 시초가. 스탑-리밋 주문을 제외한 모든 대기 주문 관련 액션 명령에 사용
24 ThisOpenPrice1 매개 변수 없음 매개 변수가 계산된 주문의 시초가-1. 스탑-리밋 대기 주문 관련 액션 명령에 사용
25 ThisOpenPrice2 매개 변수 없음 매개 변수가 계산된 주문의 시초가-2. 스탑-리밋 대기 주문 관련 액션 명령에 사용
26 LastEADeal 객체 식별자, 거래 매개 변수 식별자 엑스퍼트 어드바이저에서 실행된 직전 거래. 코멘트에 '='를 포함하는 직전 거래는 기록에서 검색 후 객체 식별자가 검사됨
27 LastEADealBuy 객체 식별자, 거래 매개 변수 식별자 엑스퍼트 어드바이저에서 실행된 직전 거래가 매수 거래인 경우. 코멘트에 '='를 포함하는 직전 거래는 기록에서 검색 후 객체 식별자가 검사됨
28 LastEADealSell 객체 식별자, 거래 매개 변수 식별자 엑스퍼트 어드바이저에서 실행된 직전 거래가 매도 거래인 경우. 코멘트에 '='를 포함하는 직전 거래는 기록에서 검색 후 객체 식별자가 검사됨
29 NoTradeOnBar 매개 변수 없음 마지막 바에 거래가 없는 경우

 

표1의 명령어를 활용하면 다음 매매 객체에 대한 액세스가 가능해 집니다: 포지션, 매매, 거래 및 작성 예정 주문. 객체가 다르면 매개 변수도 달라지죠.

표 2는 모든 매개 변수 식별자 및 적용 가능한 객체 타입에 대한 설명입니다.

표 2. 데이터 액세스 식별자.

인덱스 식별자 목적 거래 객체 타입
0 ProfitInPoints 포인트 수익 포지션
1 ProfitInValute 예금 통화 수익 포지션, 거래
2 OpenPrice 시초가 포지션, 대기 주문(스탑-리밋 주문 제외)
3 LastPrice 가격 거래
4 OpenPrice1 스탑-리밋 지정가 전환 가격 스탑-리밋 대기 주문. 해당 주문이 지정가 주문으로 전환되는 경우
5 OpenPrice2 스탑-리밋 포지션 전환 가격 스탑-리밋 대기 주문. 해당 주문이 지정가 주문으로 전환되는 경우
6 StopLossValue 손절가 포지션, 대기 주문
7 TakeProfitValue 손익분기점 포지션, 대기 주문
8 StopLossInPoints 포인트 손절가 포지션, 대기 주문
9 TakeProfitInPoints 포인트 손익분기점 포지션, 대기 주문
10 StopLossExists 손절가 존재 여부 포지션, 대기 주문
11 TakeProfitExists 손익분기점 존재 여부 포지션, 대기 주문
12 Direction 방향 1 - 매수, -1 - 매도 포지션, 대기 주문, 거래

 

액션

액션은 개장 및 폐장, 대기 주문의 설정, 정정 및 취소, 이 밖에 추적 손절매, 손익분기점, 대기 주문 추적 손절매 등의 관리 도구 실행을 포함합니다.

포지션 오픈과 매매 주문 설정 시 필요한 매개 변수가 사용되는데요. 매개 변수는 명령어 다음에 오는 괄호 안에 표시됩니다. 일반적인 함수가 호출되는 방식으로요. 모든 명령의 첫 번째 매개 변수는 식별자입니다. 매개 변수 지정 시에는 숫자 값, 변수, 기존 포지션 또는 주문에서 사용된 매개 변수를 이용할 수 있습니다. 단계 식별 섹션에서 언급된 X1*X2+X3*X4와 같은 연산도 매개 변수로 쓸 수 있고요.

표 3에 모든 액션 명령이 설명되어 있습니다.

표 3. 액션 명령

인덱스 명령 목적
0 Buy(ID,Lot,StopLoss,TakeProfit) 매수 포지션 오픈
1 Sell(ID,Lot,StopLoss,TakeProfit) 매도 포지션 오픈
2 Close(ID) 포지션 청산
3 BuyStop(ID,Lot,Price,StopLoss,TakeProfit) 역지정가 매수 주문 설정
4 SellStop(ID,Lot,Price,StopLoss,TakeProfit) 역지정가 매도 주문 설정
5 BuyLimit(ID,Lot,Price,StopLoss,TakeProfit) 지정가 매수 주문 설정
6 SellLimit(ID,Lot,Price,StopLoss,TakeProfit) 지정가 매도 주문 설정
7 BuyStopLimit(ID,Lot,Price1,Price2,StopLoss,TakeProfit) 스탑-리밋 매수 주문 설정
8 SellStopLimit(ID,Lot,Price1,Price2,StopLoss,TakeProfit) 스탑-리밋 매도 주문 설정
9 Delete(ID) 대기 주문 취소
10 DeleteAll(ID,BuyStop,SellStop,BuyLimit,SellLimit,BuyStopLimit,SellStopLimit) 특정 형식의 대기 주문 취소
11 Modify(ID,Price1,Price2,StopLoss,TakeProfit) 포지션 또는 주문 수정
12 TrailingStop 추적손절매 기능 설정. 엑스퍼트 어드바이저 설정창에서 매개 변수 설정
13 BreakEven 수익분기점 기능 설정. 엑스퍼트 어드바이저 설정창에서 매개 변수 설정

 

액션 명령 매개 변수는 표4 참조

표 4. 액션 명령 매개 변수

매개 변수 목적
ID 거래 객체(포지션, 주문) 식별자
유닛별 랏 사이즈 엑스퍼트 어드바이저 설정 창에서 유닛 변수를 나타내는 랏 변수 설정 가능
StopLoss 손절가
TakeProfit 손익분기점
가격 대기 주문 가격(스탑-리밋 주문 제외)
Price1 스탑-리밋 지정가 전환 가격
Price2 스탑-리밋 포지션 전환 가격

 

이제 Metalanguage를 사용하여 매매 전략을 직접 작성해 볼게요.

 

Metalanguage를 이용한 매매 전략 예시

여러분의 간편한 이해를 위해 각 단계와 액션 명령, 코멘트란의 설명이 포함된 프로그래밍 방법을 표로 만들었습니다. 첨부파일은 엑스퍼트 어드바이저에서 사용 가능한 프로그래밍별 텍스트 파일입니다.

주의사항: 식별자는 '+', '-' 또는 '*'를 포함할 수 없습니다. 숫자를 쓰는 게 더 간단하기도 하고요.

 

리미트오더를 이용한 스케일링

최초 포지션은 사용자가 설정한 속성에 따라 오픈됩니다. 스케일링은 최대 5회 가능합니다(리미트오더). 동시에 세 개의 주문만이 존재할 수 있고요.

표 5. 리미트오더를 이용한 스케일링을 위한 Metaprogram

단계 번호 단계 식별 액션 코멘트
1 Nothing;
UserBuy
Buy(1,1,0,Ask+Var1p);
BuyLimit(2,2,Buy(1,OpenPrice)-Var2p,0,ThisOpenPrice+Var3p);
BuyLimit(3,4,BuyLimit(2,OpenPrice)-Var2p,0,ThisOpenPrice+Var3p);
BuyLimit(4,8,BuyLimit(3,OpenPrice)-Var2p,0,ThisOpenPrice+Var3p)
포지션 또는 주문이 없는 경우 엑스퍼트 어드바이저 속성에서 매수 주문이 설정되며 초기 랏이 적용된 포지션을 오픈합니다. 포지션이 성공적으로 오픈된 경우, 세 가지 리미트오더 설정을 시도합니다. 주문 가격이 이전 주문 가격을 기반으로 하므로 이전 주문이 성공적으로 체결된 경우 다음 주문 또한 성공적으로 체결됩니다.
2 Buy(1) BuyLimit(2,2,Buy(1,OpenPrice)-Var2p,0,ThisOpenPrice+Var3p);
BuyLimit(3,4,BuyLimit(2,OpenPrice)-Var2p,0,ThisOpenPrice+Var3p);
BuyLimit(4,8,BuyLimit(3,OpenPrice)-Var2p,0,ThisOpenPrice+Var3p)
1단계에서 포지션이 성공적으로 오픈되었으나 전체 대기 주문이 설정되지 않은 경우 계속해서 남은 대기 주문을 설정합니다.
3 Buy(2) BuyLimit(3,4,Buy(2,OpenPrice)-Var2p,0,ThisOpenPrice+Var3p);
BuyLimit(4,8,BuyLimit(3,OpenPrice)-Var2p,0,ThisOpenPrice+Var3p);
BuyLimit(5,16,BuyLimit(4,OpenPrice)-Var2p,0,ThisOpenPrice+Var3p)
첫 번째 리미트오더(식별자 2)가 실행된 경우 나머지 두 리미트오더 또한 지난 단계에서 실행되었어야 합니다. 그러나 실패하였으므로 계속해서 실행 시도를 하며 항상 세 가지 리미트오더가 존재하도록 새 오더를 설정합니다.
4 Buy(3) BuyLimit(4,8,Buy(3,OpenPrice)-Var2p,0,ThisOpenPrice+Var3p);
BuyLimit(5,16,BuyLimit(4,OpenPrice)-Var2p,0,ThisOpenPrice+Var3p);
BuyLimit(6,32,BuyLimit(4,OpenPrice)-Var2p,0,ThisOpenPrice+Var3p)
새로운 리미트오더가 발동되었으며 이전 단계에서와 같이 세 가지 리미트오더가 모두 존재함을 확인합니다.
5 Buy(4) BuyLimit(5,16,Buy(4,OpenPrice)-Var2p,0,ThisOpenPrice+Var3p);
BuyLimit(6,32,BuyLimit(5,OpenPrice)-Var2p,0,ThisOpenPrice+Var3p)
해당 단계는 총 주문의 수가 최대 주문 가능 건수에 근접한 경우 두 대기 주문의 존재를 확인합니다.
6 Buy(5) BuyLimit(6,32,Buy(5,OpenPrice)-Var2p,0,ThisOpenPrice+Var3p) 해당 단계는 한 건의 마지막 주문만을 갖습니다.
7 Buy(6) Modify(6,,,Buy(6,OpenPrice)-Var4p,) 마지막 주문이 실행된 경우 손절매가 설정됩니다.
8 Nothing;
UserSell
Sell(1,1,0,Var1p); SellLimit(2,2,Sell(1,OpenPrice)+Var2p,0,ThisOpenPrice-Var3p);
SellLimit(3,4,SellLimit(2,OpenPrice)+Var2p,0,ThisOpenPrice-Var3p);
SellLimit(4,8,SellLimit(3,OpenPrice)+Var2p,0,ThisOpenPrice-Var3p)
1단계와 유사하나 매도 주문의 경우입니다.
9 Sell(1) SellLimit(2,2,Sell(1,OpenPrice)+Var2p,0,ThisOpenPrice-Var3p);
SellLimit(3,4,SellLimit(2,OpenPrice)+Var2p,0,ThisOpenPrice-Var3p);
SellLimit(4,8,SellLimit(3,OpenPrice)+Var2p,0,ThisOpenPrice-Var3p)
2단계와 유사하나 매도 주문의 경우입니다.
10 Sell(2) SellLimit(3,4,Sell(2,OpenPrice)+Var2p,0,Var3);
SellLimit(4,8,SellLimit(3,OpenPrice)+Var2p,0,ThisOpenPrice-Var3p);
SellLimit(5,16,SellLimit(4,OpenPrice)+Var2p,0,ThisOpenPrice-Var3p)
3단계와 유사하나 매도 주문의 경우입니다.
11 Sell(3) SellLimit(4,8,Sell(3,OpenPrice)+Var2p,0,Var3);
SellLimit(5,16,SellLimit(4,OpenPrice)+Var2p,0,ThisOpenPrice-Var3p);
SellLimit(6,32,SellLimit(4,OpenPrice)+Var2p,0,ThisOpenPrice-Var3p)
4단계와 유사하나 매도 주문의 경우입니다.
12 Sell(4) SellLimit(5,16,Sell(4,OpenPrice)+Var2p,0,Var3);
SellLimit(6,32,SellLimit(5,OpenPrice)+Var2p,0,ThisOpenPrice-Var3p)
5단계와 유사하나 매도 주문의 경우입니다.
13 Sell(5) SellLimit(6,32,Sell(5,OpenPrice)+Var2p,0,ThisOpenPrice-Var3p) 6단계와 유사하나 매도 주문의 경우입니다.
14 Sell(6) Modify(6,,,Sell(6,OpenPrice)+Var4p,) 7단계와 유사하나 매도 주문의 경우입니다.
15 NoPos;
Pending
DeleteAll(,0,0,1,1,0,0) 대기 주문은 있으나 포지션이 없는 경우입니다. 이익실현이 발동된 경우 발생합니다. 이 경우 모든 주문은 삭제되어야 합니다. 주문이 삭제되면 시스템이 1단계 또는 9단계로 전환됩니다. 사용자가 초기 방향 설정을 해제한 경우에는 아무 액션이 발생하지 않습니다.

 

변수의 사용: Var1 - 최초 주문 이익실현, Var2 - 이전 주문의 시초가에 비례해 설정된 리미트오더 값, Var3 - 직전 주문 손절매

그림 5는 해당 Metaprogram이 실행된 차트입니다.

그림 5. 리미트오더를 이용한 스케일링을 위한 Metaprogram 실행
그림 5. 리미트오더를 이용한 스케일링을 위한 Metaprogram 실행

주의사항: 매수와 매도 관련 규칙은 각각 설명되어 있습니다. 모든 대기 주문의 주문 가격은 직전 주문을 기준으로 설정됩니다. 따라서 주문 설정 시도가 실패하는 경우 매개 변수 값 부족으로 다음 주문은 설정되지 않습니다. 포지션을 기준으로 가격을 설정하면 안되니까요. 그렇게 되면 놓치는 주문도 생기거든요.

 

SAR

우선 두 개의 스탑오더가 대기 중이어야 합니다. 반전은 5개까지 가능합니다.

표 6. SAR을 위한 Metaprogram

단계 번호 단계 식별 액션 코멘트
1 Nothing BuyStop(1,1,Ask+Var1p,ThisOpenPrice-Var2p,ThisOpenPrice+Var3p);
SellStop(1,1,Bid-Var1p,ThisOpenPrice+Var2p,ThisOpenPrice-Var3p)
포지션이나 주문이 없습니다; 식별자 1을 사용해 두 개의 스탑오더 설정을 시도합니다.
2 NoPos;
BuyStop(1)
SellStop(1,1,Bid-Var1p,ThisOpenPrice+Var2p,ThisOpenPrice-Var3p) 포지션은 없으나 식별자 1을 포함하는 역지정가 매수 주문이 있으므로 식별자 1을 포함하는 역지정가 매도 주문 또한 있어야 합니다.
3 NoPos;
SellStop(1)
BuyStop(1,1,Ask+Var1p,ThisOpenPrice-Var2p,ThisOpenPrice+Var3p) 포지션은 없으나 식별자 1을 포함하는 역지정가 매도 주문이 있으므로 식별자 1을 포함하는 역지정가 매수 주문 또한 있어야 합니다.
4 Buy(1) Delete(1);
SellStop(2,2,Buy(1,StopLossValue),ThisOpenPrice+Var2p,ThisOpenPrice-Var3p)
식별자 1을 포함하는 매수 포지션이 설정되어 있습니다. 이 경우 식별자 1을 포함하는 다른 주문은 없어야 하며 식별자 2를 포함하는 역지정가 매도 주문이 있어야 합니다.
5 Sell(1) Delete(1);
BuyStop(2,2,Sell(1,StopLossValue),ThisOpenPrice-Var2p,ThisOpenPrice+Var3p)
4단계와 유사하나 역지정가 매도 주문이 발동한 경우입니다.
6 Buy(2) SellStop(3,4,Buy(2,StopLossValue),ThisOpenPrice+Var2p,ThisOpenPrice-Var3p) 두 번째 역지정가 매수 주문이 발동했으므로 세 번째 역지정가 매도 주문이 설정되어야 합니다.
7 Sell(2) BuyStop(3,4,Sell(2,StopLossValue),ThisOpenPrice-Var2p,ThisOpenPrice+Var3p) 두 번째 역지정가 매도 주문이 발동했으므로 세 번째 역지정가 매수 주문이 설정되어야 합니다.
8 Buy(3) SellStop(4,8,Buy(3,StopLossValue),ThisOpenPrice+Var2p,ThisOpenPrice-Var3p) 세 번째 역지정가 매도 주문이 실행되었으므로 네 번째 역지정가 매수 주문이 설정되어야 합니다.
9 Sell(3) BuyStop(4,8,Sell(3,StopLossValue),ThisOpenPrice-Var2p,ThisOpenPrice+Var3p) 세 번째 역지정가 매수 주문이 실행되었으므로 네 번째 역지정가 매도 주문이 설정되어야 합니다.
10 Buy(4) SellStop(5,16,Buy(4,StopLossValue),ThisOpenPrice+Var2p,ThisOpenPrice-Var3p) 네 번째 역지정가 매수 주문이 실행되었으므로 다섯 번째 역지정가 매도 주문이 설정되어야 합니다.
11 Sell(4) BuyStop(5,16,Sell(4,StopLossValue),ThisOpenPrice-Var2p,ThisOpenPrice+Var3p) 네 번째 역지정가 매도 주문이 실행되었으므로 다섯 번째 역지정가 매수 주문이 설정되어야 합니다.
12 Buy(5) SellStop(6,32,Buy(5,StopLossValue),ThisOpenPrice+Var2p,ThisOpenPrice-Var3p) 다섯 번째 역지정가 매수 주문이 실행되었으므로 여섯 번째 역지정가 매도 주문이 설정되어야 합니다.
13 Sell(5) BuyStop(6,32,Sell(5,StopLossValue),ThisOpenPrice-Var2p,ThisOpenPrice+Var3p) 다섯 번째 역지정가 매도 주문이 실행되었으므로 여섯 번째 역지정가 매수 주문이 설정되어야 합니다.
14 NoPos;
BuyStop(2)
Delete(2) 포지션은 없으나 역지정가 매수 주문이 있는 경우입니다. 포지션이 이익실현 설정 가격에서 청산된 경우 발생할 수 있습니다. 해당 경우 남은 주문은 삭제되며 시스템은 1단계로 돌아갑니다.
15 NoPos;
SellStop(2)
Delete(2) 14단계와 유사합니다.
16 NoPos;
BuyStop(3)
Delete(3) 14단계와 유사합니다.
17 NoPos;
SellStop(3)
Delete(3) 14단계와 유사합니다.
18 NoPos;
BuyStop(4)
Delete(4) 14단계와 유사합니다.
19 NoPos;
SellStop(4)
Delete(4) 14단계와 유사합니다.
20 NoPos;
BuyStop(5)
Delete(5) 14단계와 유사합니다.
21 NoPos;
SellStop(5)
Delete(5) 14단계와 유사합니다.
22 NoPos;
BuyStop(6)
Delete(6) 14단계와 유사합니다.
23 NoPos;
SellStop(6) |
Delete(6) 14단계와 유사합니다.

 

변수의 사용: Var1 - 현재 시장 가격으로 최초 주문 가격이 설정된 경우, Var2 - 손절매, Var3 - 이익실현.

그림 6은 해당 Metaprogram이 실행된 차트입니다.

그림 6. SAR을 위한 Metaprogram 실행
그림 6. SAR을 위한 Metaprogram 실행

 

피라미딩

최초 포지션은 인디케이터 시그널을 기반으로 오픈됩니다. 최대 5회의 스케일링이 가능합니다.

표 7. 피라미딩을 위한 Metaprogram

단계 번호 단계 식별 액션 코멘트
1 Nothing;
SignalOpenBuy
Buy(1,1,Ask-Var1p,Ask+Var2p*6) 포지션이나 주문이 없습니다. 인디케이터 시그널을 따라 매수 포지션을 오픈합니다. 손익분기점이 Var2p*6 만큼 떨어진 곳에 설정됩니다. 다음에는 Var2p*5에 설정될 것입니다. 이는 손익분기점이 비슷한 가격대에 형성되도록 하기 위함입니다.
2 Buy(1);
Buy(1,ProfitInPoints)>=Var3
Buy(2,1,Ask-Var1p,Ask+Var2p*5) 가격이 상승세인 매수 포지션이 있으므로 매수 스케일 오더를 실행합니다.
3 Buy(2) Modify(2,,,Buy(2,OpenPrice),) 포지션의 인덱스 2는 해당 포지션이 초기 포지션이 아니며 매수 스케일 오더가 실행되었음을 의미합니다. 손절매가 수익분기점에서 일어납니다.
4 Buy(2);
Buy(2,ProfitInPoints)>=Var3
Buy(3,1,Ask-Var1p,Ask+Var2p*4) 다시 상승세이므로 매수 스케일 오더를 실행합니다.
5 Buy(3) Modify(3,,,Buy(3,OpenPrice),) 매수 스케일 오더가 실행될 때마다 손절매가 수익분기점으로 설정됩니다.
6 Buy(3);
Buy(3,ProfitInPoints)>=Var3
Buy(4,1,Ask-Var1p,Ask+Var2p*3) 4단계와 유사합니다.
7 Buy(4) Modify(4,,,Buy(4,OpenPrice),) 5단계와 유사합니다.
8 Buy(4);
Buy(4,ProfitInPoints)>=Var3
Buy(5,1,Ask-Var1p,Ask+Var2p*2) 4단계와 유사합니다.
9 Buy(5) Modify(5,,,Buy(5,OpenPrice),) 5단계와 유사합니다.
10 Buy(5);
Buy(5,ProfitInPoints)>=Var3
Buy(6,1,Ask-Var1p,Ask+Var2p) 4단계와 유사합니다.
11 Buy(6) Modify(6,,,Buy(6,OpenPrice),) 5단계와 유사합니다.
12 Nothing;
SignalOpenSell
Sell(1,1,Bid+Var1p,Bid-Var2p*6) 1단계와 유사하나 매도 포지션의 경우입니다.
13 Sell(1);
Sell(1,ProfitInPoints)>=Var3
Sell(2,1,Bid+Var1p,Bid-Var2p*5) 2단계와 유사하나 매도 포지션의 경우입니다.
14 Sell(2) Modify(2,,,Sell(2,OpenPrice),) 3단계와 유사하나 매도 포지션의 경우입니다.
15 Sell(2);
Sell(2,ProfitInPoints)>=Var3
Sell(3,1,Bid+Var1p,Bid-Var2p*4) 4단계와 유사하나 매도 포지션의 경우입니다.
16 Sell(3); Modify(3,,,Sell(3,OpenPrice),) 5단계와 유사하나 매도 포지션의 경우입니다.
17 Sell(3);
Sell(3,ProfitInPoints)>=Var3
Sell(4,1,Bid+Var1p,Bid-Var2p*3) 6단계와 유사하나 매도 포지션의 경우입니다.
18 Sell(4); Modify(4,,,Sell(4,OpenPrice),) 7단계와 유사하나 매도 포지션의 경우입니다.
19 Sell(4);
Sell(4,ProfitInPoints)>=Var3
Sell(5,1,Bid+Var1p,Bid-Var2p*2) 8단계와 유사하나 매도 포지션의 경우입니다.
20 Sell(5); Modify(5,,,Sell(5,OpenPrice),) 9단계와 유사하나 매도 포지션의 경우입니다.
21 Sell(5);
Sell(5,ProfitInPoints)>=Var3
Sell(6,1,Bid+Var1p,Bid-Var2p) 10단계와 유사하나 매도 포지션의 경우입니다.
22 Sell(6); Modify(6,,,Sell(6,OpenPrice),) 11단계와 유사하나 매도 포지션의 경우입니다.

 

변수의 사용: Var1 - 초기 손절매, Var2 - 마지막 주문 이익실현, Var3 - 매도 스케일 주문 실행 및 손절매의 수익분기점으로 이동 시 포인트 수익.

그림 7은 해당 Metaprogram이 실행된 차트입니다.

그림 7. 피라미딩을 위한 Metaprogram 실행
그림 7. 피라미딩을 위한 Metaprogram 실행

 

리오프닝

우선 두 가지 리미트 오더를 설정합니다. 하나가 발동하면 다른 하나는 삭제됩니다. 손절매가 실행되면 새로운 포지션이 오픈되고 이익실현 설정 가격에서 청산되거나 최대 포지션 개수인 5개에 도달할 때까지 유지됩니다.

표 8. 리오프닝을 위한 Metaprogram

단계 번호 단계 식별 액션 코멘트
1 Nothing;
NoLastDeal
BuyLimit(1,1,Ask-Var1p,ThisOpenPrice-Var2p,ThisOpenPrice+Var3p);
SellLimit(1,1,Bid+Var1p,ThisOpenPrice+Var2p,ThisOpenPrice-Var3p)
포지션 또는 주문이 없으며 계정에 해당 심볼 거래 기록이 없습니다. 시스템 운용의 첫 단계인 것이죠. 최초 액션으로 두 개의 리미트오더가 설정됩니다.
2 Nothing;
LastDeal(,ProfitInValute)>0
BuyLimit(1,1,Ask-Var1p,ThisOpenPrice-Var2p,ThisOpenPrice+Var3p);
SellLimit(1,1,Bid+Var1p,ThisOpenPrice+Var2p,ThisOpenPrice-Var3p)
포지션 또는 주문이 없으나 이익을 창출한 거래 기록이 있습니다. 전 단계가 완료된 것이므로 1단계부터 다시 시작해 두 개의 리미트오더를 설정합니다.
3 Nothing;
LastEADeal(5)
BuyLimit(1,1,Ask-Var1p,ThisOpenPrice-Var2p,ThisOpenPrice+Var3p);
SellLimit(1,1,Bid+Var1p,ThisOpenPrice+Var2p,ThisOpenPrice-Var3p)
포지션 또는 주문이 없으나 마지막 식별자가 포함된 거래 기록이 있습니다. 전 단계가 완료된 것으로 간주되므로 창출된 이익은 중요하지 않으며 1단계부터 다시 시작해 두 개의 리미트오더를 설정합니다.
4 NoPos;
BuyLimit(1)
SellLimit(1,1,Bid+Var1p,ThisOpenPrice-Var2p,ThisOpenPrice+Var3p) 포지션 또는 주문이 없으나 하나의 리미트오더가 있으며 이는 리미트오더가 총 두 개임을 의미합니다.
5 NoPos;
SellLimit(1)
BuyLimit(1,1,Ask-Var1p,ThisOpenPrice+Var2p,ThisOpenPrice-Var3p) 4단계와 유사합니다.
6 Buy(1);
SellLimit(1)
Delete(1) 식별자 1을 포함하는 포지션이 있습니다. 리미트오더 중 하나가 실행되었다는 의미이며 나머지 리미트 오더는 삭제되어야 합니다.
7 Sell(1);
BuyLimit(1)
Delete(1) 6단계와 유사합니다.
8 Nothing;
LastDeal(1,ProfitInValute)<=0;
LastEADeal(1,Direction)==1
Buy(2,2,Ask-Var2p,Ask+Var3p) 포지션이 없으며 마지막 거래에서 수익이 창출되지 않았습니다. 엑스퍼트 어드바이저에서 실행된 마지막 거래의 방향을 확인합니다. 매수 거래였을 경우 다음으로 오픈하는 포지션은 매수 포지션이 됩니다.
9 Nothing;
LastDeal(1,ProfitInValute)<=0;
LastEADeal(1,Direction)==-1
Sell(2,2,Bid+Var2p,Bid-Var3p) 포지션이 없으며 마지막 거래에서 수익이 창출되지 않았습니다. 엑스퍼트 어드바이저에서 실행된 마지막 거래의 방향을 확인합니다. 매도 거래였을 경우 다음으로 오픈하는 포지션은 매도 포지션이 됩니다.
10 Nothing;
LastDeal(2,ProfitInValute)<=0;
LastEADeal(2,Direction)==1
Buy(3,4,Ask-Var2p,Ask+Var3p) 8단계와 유사합니다.
11 Nothing;
LastDeal(2,ProfitInValute)<=0;
LastEADeal(2,Direction)==-1
Sell(3,4,Bid+Var2p,Bid-Var3p) 9단계와 유사합니다.
12 Nothing;
LastDeal(3,ProfitInValute)<=0;
LastEADeal(3,Direction)==1
Buy(4,8,Ask-Var2p,Ask+Var3p) 8단계와 유사합니다.
13 Nothing;
LastDeal(3,ProfitInValute)<=0;
LastEADeal(3,Direction)==-1
Sell(4,8,Bid+Var2p,Bid-Var3p) 9단계와 유사합니다.
14 Nothing;
LastDeal(4,ProfitInValute)<=0;
LastEADeal(4,Direction)==1
Buy(5,16,Ask-Var2p,Ask+Var3p) 8단계와 유사합니다.
15 Nothing;
LastDeal(4,ProfitInValute)<=0;
LastEADeal(4,Direction)==-1
Sell(5,16,Bid+Var2p,Bid-Var3p) 9단계와 유사합니다.

 

변수의 사용: Var1 - 리미트오더가 설정된 시장 가격, Var2 - 손절매, Var3 - 이익실현.

그림 8은 해당 Metaprogram이 실행된 차트입니다.

그림 8. 리오프닝을 위한 Metaprogram 실행
그림 8. 리오프닝을 위한 Metaprogram 실행

아래는 거래 시그널, 추적 손절매 및 손익분기점 등의 기능을 실행시키는 간단한 프로그래밍 방법입니다.

 

거래 시그널

진입과 청산은 거래 시그널을 기반으로 합니다.

표 9. 트레이딩 시그널을 위한 Metaprogram

단계 번호 단계 식별 액션 코멘트
1 Nothing;
SignalOpenBuy;
NoTradeOnBar
Buy(1,1,0,0) 포지션 또는 주문이 없으나 매수 포지션 오픈을 알리는 시그널이 있습니다. 현재 바에 거래가 없으며 매수 포지션을 오픈합니다.
2 Nothing;
SignalOpenSell;
NoTradeOnBar
Sell(1,1,0,0) 포지션 또는 주문이 없으나 매도 포지션 오픈을 알리는 시그널이 있습니다. 현재 바에 거래가 없으며 매도 포지션을 오픈합니다.
3 SignalCloseBuy;
Buy(1)
Close(1); 매수 포지션이 있으며 포지션 청산을 알리는 시그널이 있습니다. 매수 포지션을 청산합니다.
4 SignalCloseSell;
Sell(1)
Close(1); 매도 포지션이 있으며 포지션 청산을 알리는 시그널이 있습니다. 매도 포지션을 청산합니다.

 

그림 9는 해당 Metaprogram이 실행된 차트입니다.

그림 9. 트레이딩 시그널을 위한 Metaprogram 실행
그림 9. 트레이딩 시그널을 위한 Metaprogram 실행

 

추적 손절매가 있는 트레이딩 시그널

표 10. 추적 손절매가 있는 트레이딩 시그널을 위한 Metaprogram

단계 번호 단계 식별 액션 코멘트
1 Nothing;
SignalOpenBuy;
NoTradeOnBar
Buy(1,1,0,0) 포지션 또는 주문이 없으나 매수 포지션 오픈을 알리는 시그널이 있습니다. 현재 바에 거래가 없으며 매수 포지션을 오픈합니다.
2 Nothing;
SignalOpenSell;
NoTradeOnBar
Sell(1,1,0,0) 포지션 또는 주문이 없으나 매도 포지션 오픈을 알리는 시그널이 있습니다. 현재 바에 거래가 없으며 매도 포지션을 오픈합니다.
3 SignalCloseBuy;
Buy(1)
Close(1); 매수 포지션이 있으며 포지션 청산을 알리는 시그널이 있습니다. 매수 포지션을 청산합니다.
4 SignalCloseSell;
Sell(1)
Close(1); 매도 포지션이 있으며 포지션 청산을 알리는 시그널이 있습니다. 매도 포지션을 청산합니다.
5 Buy(1) TrailingStop 매수 포지션이 있습니다. 추적 손절매 기능이 활성화되어야 합니다.
6 Sell(1) TrailingStop 매도 포지션이 있습니다. 추적 손절매 기능이 활성화되어야 합니다.

 

그림 10은 해당 Metaprogram이 실행된 차트입니다.

그림 10. 추적 손절매가 있는 트레이딩 시그널을 위한 Metaprogram
그림 10. 추적 손절매가 있는 트레이딩 시그널을 위한 Metaprogram

 

이익실현 기능을 동반한 트레이딩 시그널

표 11. 이익실현 기능을 동반한 트레이딩 시그널을 위한 Metaprogram

단계 번호 단계 식별 액션 코멘트
1 Nothing;
SignalOpenBuy;
NoTradeOnBar
Buy(1,1,0,0) 포지션 또는 주문이 없으나 매수 포지션 오픈을 알리는 시그널이 있습니다. 현재 바에 거래가 없으므로 매수 포지션을 오픈합니다.
2 Nothing;
SignalOpenSell;
NoTradeOnBar
Sell(1,1,0,0) 포지션 또는 주문이 없으나 매도 포지션 오픈을 알리는 시그널이 있습니다. 현재 바에 거래가 없으므로 매도 포지션을 오픈합니다.
3 SignalCloseBuy;
Buy(1)
Close(1); 매수 포지션이 있으며 포지션 청산을 알리는 시그널이 있습니다. 매수 포지션을 청산합니다.
4 SignalCloseSell;
Sell(1)
Close(1); 매도 포지션이 있으며 포지션 청산을 알리는 시그널이 있습니다. 매도 포지션을 청산합니다.
5 Buy(1) BreakEven 매수 포지션이 있습니다. 이익실현 기능이 활성화되어야 합니다.
6 Sell(1) BreakEven 매도 포지션이 있습니다. 이익실현 기능이 활성화되어야 합니다.

 

그림 11은 해당 Metaprogram이 실행된 차트입니다.

그림 11. 이익실현 기능을 동반한 트레이딩 시그널을 위한 Metaprogram 실행

그림 11. 이익실현 기능을 동반한 트레이딩 시그널을 위한 Metaprogram 실행

 

명령어 인터프리터

매매 전략을 정형화하는 위의 접근법은 전략에 대한 이해도를 높여줄 뿐 아니라 알고리즘을 작성해 엑스퍼트 어드바이저에서 적용할 수 있도록 해 줍니다. 또한 정교하게 고안된 규칙을 쉽게 해석하고 따를 수 있게도 해 주죠. 엑스퍼트 어드바이저의 인터프리터는 이를 염두에 두고 개발되었습니다(첨부 파일 참조). 엑스퍼트 어드바이저의 매개 변수 및 각각에 대한 설명은 표 12에서 찾아볼 수 있습니다.

표 12. 엑스퍼트 어드바이저 인터프리터 매개 변수

매개 변수 목적
Lots 랏 계수가 1일 때 주문량
UserTradeDir 사용자가 특정한 거래 방향(단계 식별 시 UserBuy 및 UserSell 명령 실행을 통해 확인).
ProgramFileName Metaprogram 파일명(계정 로그인 시). 테스팅 또는 최적화 시 Metaprogram은 TesterMetaProgram.txt 파일에 저장할 것.
DeInterpritate 명령 해석 반전. 실행 시 파일명 앞에 'De_'가 붙은 파일이 생성되며 ProgramFileName 파일에서 어떻게 적용되었는지 확인 가능.
사용자 변수
Var1 - Var20 사용자 변수.
추적 손절매
TR_ON 추적 손절매 기능 활성화
TR_Start 추적 손절매 기능이 활성화되는 포인트 수익.
TR_Level 추적 손절매 가격. 현재 시장 가격에서 손절매까지의 포인트 거리.
TR_Step 손절매 수정을 위한 포인트 스텝.
이익실현
BE_ON 이익실현 기능 활성화.
BE_Start 이익실현 기능이 활성화되는 포인트 수익.
BE_Level 이익실현 발동 시 손절매 이동 위치. BE_Start와 BE_Level 사이의 포인트 수익 고정.
오픈 시그널
OS_ON 오픈 시그널 활성화.
OS_Shift 인디케이터 확인 바: 0 - 새 인디케이터, 1 - 완료.
OS_TimeFrame 인디케이터 타임프레임.
OS_MA2FastPeriod 빠른 이동평균 기간.
OS_MA2FastShift 빠른 이동평균 시프트.
OS_MA2FastMethod 빠른 이동평균법.
OS_MA2FastPrice 빠른 이동평균가.
OS_MA2SlowPeriod 느린 이동평균 기간.
OS_MA2SlowShift 느린 이동평균 시프트.
OS_MA2SlowMethod 느린 이동평균법.
OS_MA2SlowPrice 느린 이동평균가.
청산 시그널
CS_ON 청산 시그널 활성화.
CS_Shift 인디케이터 확인 바: 0 - 새 인디케이터, 1 - 완료.
CS_TimeFrame 인디케이터 타임프레임.
CS_CCIPeriod CCI 기간.
CS_CCIPrice CCI 가격.
CS_CCILevel 상위 CCI 레벨(매수 포지션 청산). 매수 포지션 청산 시그널은 레벨의 하향 교차점에서 발생합니다. 매도 포지션과는 완전히 반대죠.

 

엑스퍼트 어드바이저 작동법

엑스퍼트 어드바이저는 우선 파일에서 Metaprogram을 열어 검토하고 분석합니다. 중대한 오차 발생 시, 경고창이 나타납니다. Metaprogram 분석을 진행하면서 엑스퍼트 어드바이저가 데이터 구조에 텍스트 명령어에 상응하는 수치 값을 채웁니다. 이는 엑스퍼트 어드바이저의 최대 성능을 끌어내는 데 도움이 됩니다. 분석이 성공적으로 완료되면 다음 메세지가 로그에 나타납니다: '인터프리터 초기화 완료'.

Deinterpritate 변수가 포함된 경우, 엑스퍼트 어드바이저는 반전 해석 테스트를 진행합니다(차트와의 연결이 끊기며 전략 테스터의 모든 테스트가 강제 종료됩니다). 반전 해석 시, 엑스퍼트 어드바이저는 수치 값을 텍스트 명령어로 전환합니다. 명령어 입력 값이 다르기는 하지만, 반전 해석된 Metaprogram은 엑스퍼트 어드바이저의 명령 분석 과정을 이해하는 데에 도움이 됩니다.

다음 문자열을 한번 볼게요:

Buy(6) | Modify(6,,,ThisOpenPrice-Var4p,)

반전 해석이 끝나고 나면 문자열이 다음과 같이 바뀝니다:

Buy(6)==1*1+0*0; | Modify(6,,,ThisOpenPrice()*1-0.0025*1,)

간단한 Buy(6) 명령어가 오른쪽에 결과가 1이 되는 X1*X2+X3*X4 연산이 위치하는 등식으로 전환된 걸 볼 수 있네요. 액션 필드의 경우, 사용자 변수는 수치 값으로 대체됩니다.

 

엑스퍼트 어드바이저 커스터마이징 팁

아마 엑스퍼트 어드바이저 커스터마이징을 원하는 분들도 계실 겁니다. 분석 단계와 명령 실행 단계에 자신만의 명령어를 더하거나 다른 포지션 관리 기능을 추가할 수 있겠죠. 엑스퍼트 어드바이저의 구조 덕분에 커스터마이징은 매우 쉽습니다. 그렇지 않으면 엑스퍼트 어드바이저는 실용성이 없겠죠.

데이터 명령어 추가

InfoCommand 배열에서 데이터 명령어를 찾을 수 있습니다. 각 열에 5가지 명령어가 배열되어 있어 개수를 세거나 새로운 인덱스 값을 찾기가 용이합니다.

InfoCommand 배열에 명령어가 추가되면 새로운 인덱스에 해당하는 케이스문을 추가하여 SetValue() 함수의 구조를 바꿉니다. 해당 값을 구하려면 우선 값이 구해질 개체를 선택해야 합니다. 그렇지 않으면 해당 값을 구할 수 없습니다. 데이터가 얻어지는 개체의 형태에 따라 개체 선택에 사용되는 함수가 달라집니다. 해당 함수들은 표 13에서 확인할 수 있습니다.

표 13. 객체 선택을 위한 엑스퍼트 어드바이저 함수

함수 목적 및 매개 변수
Pos.Select(_Symbol) 포지션 선택. PositionSelect() 함수와 비슷한 표준 방식.
SelectOrder(long aType,string aID,bool & aSelected) 엑스퍼트 어드바이저 심볼, 형태(aType) 및 식별자(aID)에 따른 주문 선택 함수. 객체가 선택된 경우 aSelected 참조 형식 매개 변수가 트루를 반환합니다.
bool SelectLastDeal(int aType,bool & aSelected) 엑스퍼트 어드바이저 심볼 및 형태(aType)에 따른 직전 거래 선택 함수. 객체가 선택된 경우 aSelected 참조 형식 매개 변수가 트루를 반환합니다.
SelectLastEADeal(int aType,string aID,bool & aSelected) 엑스퍼트 어드바이저 심볼 및 형태(aType)에 따른 직전 실행 거래 선택 함수. 객체가 선택된 경우 aSelected 참조 형식 매개 변수가 트루를 반환합니다.

 

직전 거래와 직전 실행 거래의 차이는 직전 거래에서는 손절매매와 이익실현 주문이 이루어진다는 점입니다. 직전 거래 데이터는 직전 포지션 청산 결과를 얻기 위해 필요할 수 있습니다. 직전 실행 거래 결과는 거래의 마지막 방향이나 엑스퍼트 어드바이저 운용 단계를 알기 위해 사용되죠.

거래 개체 데이터 외에도, 가격 등의 시장 데이터에 대한 액세스도 가능합니다. 다만 데이터를 실제로 획득할 수 있도록 하는 게 중요하죠. 객체 선택 시도 후에는 aSelected 값을 이용해 객체가 선택되었음을 반드시 확인해야 하며, 필요한 매개 변수 값을 획득하여 Val.Value 변수에 적용해 트루가 반환되는지 검사합니다.

표 14는 다양한 객체로부터 매개 변수를 구하는 데에 사용되는 함수를 나타냅니다.

표 14. 선택된 객체로부터 매개 변수 획득을 위한 엑스퍼트 어드바이저 함수

함수 목적 및 매개 변수
double SelPosParam(int aIndex) aIndex 인덱스를 활용하여 포지션 매개 변수 구하기.
double SelOrdParam(int aIndex) aIndex 인덱스를 활용하여 주문 매개 변수 구하기.
double SelDealParam(int aIndex) aIndex 인덱스를 활용하여 거래 매개 변수 구하기.

 

가져올 데이터의 식별자 인덱스는 함수로 전달됩니다. 인덱스 값은 Val.InfoIdentifierIndex 변수에 포함됩니다.

새로운 액세스 명령어 추가 시, 가지고 나갈 데이터의 식별자만 필요한 경우가 있으며 가져올 데이터의 식별자도 필요한 경우도 있습니다.

 

데이터 식별자 추가

InfoIdentifier 배열에서 식별자를 찾을 수 있습니다. 새로운 식별자를 추가하고 나면, 인덱스를 찾아 SelPosParam(), SelOrdParam() 및 SelDealParam() 함수를 업데이트해야 합니다. 모든 개체에 대한 새로운 식별자의 적용 여부에 따라 업데이트는 일부 또는 전체의 함수를 대상으로 할 수 있습니다. 함수가 업데이트되면 새로운 인덱스에 해당하는 케이스문을 추가하여 구조를 바꿉니다.

 

액션 명령어 추가

ActCommand 배열에 액션 명령어를 추가합니다. 명령어는 문자열로 배열되어 있어 필요한 인덱스를 찾는 것이 조금 어렵습니다. 명령어를 추가한 후에 매개 변수 개수와 유형을 지정해야 하므로 문자열이 나타납니다. 매개 변수 개수는 ActCmndPrmCnt 배열에 지정되며 유형은 ActCmndType 배열에 나타납니다. 유형의 예: 0 - 시장 움직임, 1 - 대기 주문 액션, 2 - 포지션 관리.

명령어를 배열에 추가한 후 DoAction() 함수에 새로운 케이스문을 추가해 스위치를 요청합니다. 새로운 함수는 불리언 자료형이어야 하며 성공적으로 실행된 경우 트루를, 에러가 발생한 경우 폴스를 리턴해야 합니다. 추적 손절매 함수와 같이 성능 측정이 필요하지 않은 경우에는 트루를 리턴합니다.

대기 주문과 관련된 함수의 경우 실행 이전에 주문 존재 여부에 대한 확인이 우선되어야 한다는 것을 꼭 기억하세요.

 

트레이딩 시그널 함수 변화

엑스퍼트 어드바이저에서 트레이딩 시그널을 구하는 데에 쓰이는 함수는 두 가지(오픈, 청산 두 개씩) 뿐입니다.

CloseSignalsInit() 함수(청산 시그널 초기화) 및 OpenSignalsInit() 함수(오픈 시그널 초기화)는 엑스퍼트 어드바이저의 OnInit()에 요청됩니다. 인디케이터를 불러오는 함수들인데요. CloseSignalsMain() (청산 시그널 식별)과 OpenSignalsMain() (오픈 시그널 식별)은 각 틱의 OnTick() 함수에 요청됩니다.

함수 실행 초기에 GlobalCloseBuySignal, GlobalCloseSellSignal(청산 시그널) 및 GlobalOpenBuySignal, GlobalOpenSellSignal(오픈 시그널)은 폴스를 반환해야 하며 해당하는 인디케이터를 읽어들인 후에 트루를 반환해야 합니다.

또한, 엑스퍼트 어드바이저의 OnDeinit() 함수를 사용할 때에는 IndicatorRelease()를 실행해야 합니다.

 

첨부파일

  • eInterpretator.mq5 - 터미널 데이터 디렉토리 내 MQL5/Experts에 배치되어야 하는 엑스퍼트 어드바이저.

  • LimitAdd.txt - 리미트오더를 이용한 스케일링을 위한 Metaprogram.

  • StopRev.txt - SAR을 위한 Metaprogram.

  • Piramiding.txt - 피라미딩을 위한 Metaprogram.

  • ReOpen.txt.txt - 리오프닝을 위한 Metaprogram.

  • TradeSignals.txt - 트레이딩 시그널을 위한 Metaprogram.

  • TradeSignalsTR.txt - 추적 손절매가 있는 트레이딩 시그널을 위한 Metaprogram.

  • TradeSignalsBE.txt - 이익실현 기능을 동반한 트레이딩 시그널을 위한 Metaprogram.

  • limitadd.set -리미트오더를 이용한 스케일링을 위한 매개 변수 파일.

  • stoprev.set - SAR을 위한 매개 변수 파일.

  • piramiding.set - 피라미딩을 위한 매개 변수 파일.

  • reopen.set - 리오프닝을 위한 매개 변수 파일.

  • tradesignals.set - 트레이딩 시그널을 위한 매개 변수 파일.

  • tradesignalstr.set - 추적 손절매가 있는 트레이딩 시그널을 위한 매개 변수 파일.

  • tradesignalsbe.set - 이익실현 기능을 동반한 트레이딩 시그널을 위한 매개 변수 파일.

유의사항 트레이딩 시그널, 추적 손절매 및 이익실현이 포함된 프로그램을 사용하는 경우 엑스퍼트 어드바이저 속성창에서 해당 함수를 활성화 시키는 것을 잊지 마세요. 전략 테스터 사용 시 Metaprogram 파일을 TesterMetaProgram.txt file로 복사하세요(원격 테스트 에이전트 사용을 위해 필요). 해당 파일은 터미널 데이터 디렉토리 내 MQL5/Files에 저장되어야 합니다(터미널: 파일 -> 데이터 폴더 열기).

Metalanguage를 이용한 매매 전략 예시 섹션 내 차트에서 실행된 프로그램은 매개 변수 파일에 포함된 매개 변수를 기반으로 한 것입니다. 지난 몇 개월간 M1의 OHLC 모델 EURUSD H1에 대해 테스팅이 이루어졌습니다(2012년 8월 29일 기준).

 

결론

매매 전략 개발을 처음 시작하면 헷갈리는 부분이 많을 거예요. 어디에서 시작하고, 뭐가 중요하고, 실제 환경에서 엑스퍼트 어드바이저의 안정성은 어떻게 유지하며, 거래 전략 알고리즘의 실행과 신뢰도 등 신경 쓰이는 부분이 많죠.

이번 글은 전략 정형화를 통해 EA 개발을 도와주는 개발자와 투자자 모두가 전략 개발 과정 및 관련 고려 사항을 이해하도록 돕는 것이 목표로 했습니다. 엑스퍼트 어드바이저의 eInterpretator 인터프리터와 함께라면 최소한의 시간과 노력으로 다양한 매매 전략을 테스트해 볼 수 있는 기회가 열린답니다.

마지막으로, 제가 MetaTrader5에 얼마나 감탄했는지 꼭 알리고 싶어요. 엑스퍼트 어드바이저 인터프리터의 작동 속도는 정말 기대 이상이더라고요!

MetaQuotes 소프트웨어 사를 통해 러시아어가 번역됨.
원본 기고글: https://www.mql5.com/ru/articles/495

파일 첨부됨 |
files__4.zip (23.39 KB)
초보자를 위한 간편 스타트 가이드 초보자를 위한 간편 스타트 가이드
여러분, 안녕하세요! 엑스퍼트 어드바이저 생성 방식이나 인디케이터 활용법을 쉽고 빠르게 이해할 수 있도록 돕고자 이번 글을 씁니다. 이 글은 초보자를 대상으로 하며 복잡하거나 난해한 예제는 포함하지 않습니다.
MQL5로 하는 트레이드 오퍼레이션 - 어렵지 않아요! MQL5로 하는 트레이드 오퍼레이션 - 어렵지 않아요!
대부분의 투자자들이 수익 창출을 목적으로 하지만 투자 과정 자체를 즐기는 투자자들도 있습니다. 하지만 반드시 수동 매매여야만 그 과정이 즐거울 수 있는 건 아니예요. 자동 거래 시스템 개발 또한 꽤 흥미진진하답니다. 트레이딩 로봇 개발은 좋은 추리 소설을 읽는 것 만큼이나 재밌을 수 있어요.
가격 히스토그램 (시장 프로필) 및 MQL5에서 구현 가격 히스토그램 (시장 프로필) 및 MQL5에서 구현
시장 프로필은 정말 뛰어난 사상가인 Peter Steidlmayer가 개발했습니다. 그는 완전히 다른 모델 세트로 이어지는 "수평" 및 "수직"시장 이동에 대한 정보의 대체 표현을 사용할 것을 제안했습니다. 그는 시장의 근본적인 맥박이나 균형과 불균형의 순환이라는 근본적인 패턴이 있다고 가정했습니다. 이 기사에서는 시장 프로필의 단순화된 모델인 가격 히스토그램을 고려하고 MQL5에서의 구현에 대해 설명합니다.
MQL5 간단하게 알아보기 MQL5 간단하게 알아보기
매매 전략 프로그래밍 언어인 MQL5를 배우기로 결심은 했는데 아무 것도 모르겠다고요? 초보 투자자의 입장에서 MQL5와 MetaTrader5를 이용해 보고 간단한 소개글을 남깁니다. 이 글은 MQL5를 이용해 할 수 있는 것들에 대한 설명 그리고 MetaEditor5와 MetaTrader5를 사용하는 데에 유용한 팁들을 포함하고 있습니다.