![MetaTrader 5에서 MetaTrader 4로 거래를 복제하는 방법](https://c.mql5.com/i/articles/overlay.png)
MetaTrader 5에서 MetaTrader 4로 거래를 복제하는 방법
소개
얼마 전까지만 해도 많은 거래자들은 MetaTrader 5가 실제 거래에 적합하지 않은 조잡한 플랫폼이라고 믿었습니다. 하지만 이제 얼마 지나지 않아 실제 거래가 언제 가능할지 여론이 들끓고 있죠. 많은 거래자들은 이미 MetaTrader 5에 구현된 이점을 높이 평가했습니다. 또한 MetaQuotes Software Corp.에서 주관하는 챔피언십 MQL5 언어에 대한 개발자의 관심 증가. 그리고 이제 이 흥미로운 바램이 거래에서 이익을 얻는 형태로 실현되기를 바랍니다. 바로 그 질문, "실제 거래가 언제 가능합니까?"라는 질문은 사실 주소를 잘못 찾은 것으로 보입니다. 솔루션은 특정 브로커에 따라 달라집니다. 새로운 플랫폼으로 전환할 때 최종 결정을 내리는 것이 바로 그들이거든요.
이 상황에서 거래자는 홀로 무엇을 할 수 있습니까? 답은 분명합니다. MetaTrader 5의 환승 수단으로 MetaTrader 4가 제공하는 실제 거래의 기회를 사용해야 합니다. 즉. 카피스트(복제 담당자)를 쓰는 것이죠. 두 MetaTrader 4 간의 바인딩은 웹 (Web)에서 전혀 혁신적인 게 아닙니다. 이제 MetaTrader 5로 이러한 바인딩을 구현할 때입니다.
프롤로그
주제에 명시된 아이디어를 구현하려면 "이익은 어디에서 나오나요?"라는 질문을 명확히 해야 합니다. 및 "트레이더가 이익 성장을 어떻게 제어할 수 있습니까?" 언뜻 보기에 답은 분명합니다. 싸게 사서 비싸게 판다. 그러나 이익의 구성 요소를 생각해 봅시다. 이익은 매수와 매도의 차액에 베팅액을 곱한 것입니다. 즉, 이익에는 시세와 거래 포지션의 거래량이라는 두 가지 구성 요소가 있습니다.
거래자는 무엇을 관리할 수 있습니까? 이 두 가지 구성 요소 중 거래를 좌우 (조종)하는 것은 무엇입니까? 물론 거래 포지션의 양입니다. 호가은 브로커로부터 수신되며 트레이더는 변경할 수 없습니다. 첫 번째 결론은 다음과 같습니다. 거래 사본을 만들기 위해서는 거래 포지션의 양을 동기적으로 유지해야 합니다.
1. 두 플랫폼의 비교
1.1 회계 시스템의 차이점
비교되는 플랫폼은 서로 다른 거래 회계 시스템을 가지고 있으며 이는 복제 문제를 복잡하게 만들 수 있습니다. 그러나 우리는 이 바인딩의 선두가 MetaTrader 5라는 것을 잊어서는 안됩니다. 이는 MetaTrader 4에서 동일한 회계 시스템을 가상으로 반복해야 함을 의미합니다.
MetaTrader 5의 거래 포지션은 MetaTrader 4에서 채택된 주문 회계와 모순되지 않는 개별 거래 주문의 결과입니다. 포지션에 대한 일반적인 손절매와 이익실현은 모든 미결 주문에 대해 동일한 손절매와 이익실현을 통해 구현할 수 있습니다. 플랫폼 간의 중요한 차이점은 MetaTrader 4에서 어떤 순서로 마감해야 하는지에 대한 질문에만 나타납니다. MetaTrader 5는 트레이드 포지션의 주문에 대한 별도의 회계처리가 없기 때문에 이 문제가 걸림돌이 될 수 있습니다.
1.2 거래 포지션의 양
어떤 주문을 마감할지에 차이가 있는지 자세히 살펴보겠습니다. 이익에 영향을 미칠까요? 예를 들어, 서로 다른 시간에 개설된 두 개의 주문이 있고 다른 시간에 같은 방식으로 마감되었지만 한동안 함께 존재해 왔습니다. 즉, 우리는 주문 회계 시스템에서 거래 포지션을 에뮬레이션하려고 합니다.
주문 마감 수준의 수준을 변경하면 이익을 얻을 수 있는 다양한 변형들을 계산해 보겠습니다.
유형 | 용량 | 단계 시작 | 단계 종료 |
---|---|---|---|
매도 | 0.1 | 1.39388 | 1.38438 |
매도 | 0.1 | 1.38868 | 1.38149 |
계산기 코드를 작성해 보겠습니다.
void OnStart() { double open1=1.39388,close1=1.38438, open2=1.38868,close2=1.38149; Print("total ",n1(profit((open1-close1),0.1)+profit((open2-close2),0.1))); Print("order2 pp=",ns(open2-close2)," profit=",n1(profit((open2-close2),0.1))); Print("order1 pp=",ns(open1-close1)," profit=",n1(profit((open1-close1),0.1))); } string ns(double v){return(DoubleToString(v,_Digits));} string n1(double v){return(DoubleToString(v,1));} double profit(double v,double lot){return(v/_Point*lot);}계산은 다음과 같습니다.
order1 pp=0.00950 profit=95.0 order2 pp=0.00719 profit=71.9 total 166.9
이제 close1과 close2의 값을 바꿉니다.
order1 pp=0.01239 profit=123.9 order2 pp=0.00430 profit=43.0 total 166.9
그림 1. 주문 마감의 변형
그림 1은 두 버전에서 AB와 CD 영역의 거래량이 0.1이고 BC의 거래량이 0.2이며 주문이 마감된 거래량에 의존하지 않음을 보여줍니다.
개별 주문의 이익에는 차이가 있지만 포지션의 총 이익은 동일합니다. 이 예가 동일한 주문량에 대해 계산되었다는 사실에 주의를 기울이고 싶습니다. 즉, 동일한 수준에서 주문이 아닌 동일한 볼륨의 마감을 구현했습니다. 그리고 거래량 마감의 원칙만 철저히 지키면 주문량은 얼마든지 상관없습니다. 마감 물량이 주문 물량보다 많을 경우 부분 마감됩니다.
따라서 주요 결론은 다음과 같습니다. 전체 포지션의 경우 어떤 주문이 마감되었는지는 중요하지 않습니다. 중요한 것은 마감된 볼륨이 주어진 수준에서 동일해야 한다는 것입니다.
1.3 거래 복제
위의 예에서 동일한 이익을 얻기 위해 MQL5로 작성된 Expert Advisor에서 생성된 신호를 전송할 필요가 없음을 알 수 있습니다. 거래 포지션의 양만 반복하면 됩니다. 나중에 논의될 몇 가지 이유로 인해 완전히 동일한 거래는 아닐 것입니다. 그러나 이러한 이유는 MQL5로 작성된 수익성 있는 EA를 사용하여 실제 이익을 얻는 데 장애가 될 수 없습니다.
이익 감소의 첫 번째 이유는 호가의 차이입니다. 일부 브로커의 경우 스프레드를 초과할 수 있습니다. 사실은 호가가 실시간으로 바뀐다는 것입니다. 그리고 MetaTrader 5에서 EA가 포지션을 열기로 결정하면 MetaTrader 4가 연결된 브로커가 단순히 다른 가격을 가질 수 있게 됩니다. 그리고 이 경우 가격은 더 나쁠 수도 있고 더 나을 수도 있습니다.
이익 감소의 두 번째 이유는 시간 요인입니다. 포지션은 MetaTrader 5에 이미 나타난 후에 복제되므로 지연이 불가피합니다.
이 두 가지 이유는 모든 스캘핑 전략을 압도해버립니다. 따라서 MetaTrader 5에서 실제 거래가 가능해질 때까지 이러한 전략은 적용되지 않습니다.
스프레드를 훨씬 초과하고 특정 브로커의 호가에 둔감한 (거래에서) 이익을 암시하는 시스템은 포지션 카피스트 사용하여 실제 돈을 버는 데 사용할 수 있습니다.
2. 문제 설정
- MetaTrader 5와 MetaTrader 4 간에 신호를 전달하기 위한 바인딩
- MetaTrader 5의 포지션 변경
- MetaTrader 4에서 신호 수신
- MetaTrader 4에서 거래 포지션의 반복
2.1. MetaTrader 5와 MetaTrader 4 간에 신호를 전달하기 위한 바인딩
첫 번째 변형은 공유 파일을 통해 신호를 전송하는 것입니다. 질문은 다음과 같습니다. 파일에 자주 기록하면 하드웨어가 손상되지 않습니까? 포지션이 변경된 경우에만 새 데이터를 작성하면 이러한 레코드가 자주 발생하지 않습니다. Windows 개발자보다 더 자주 페이징 파일을 변경하지 않습니다. 이것은 차례로 하드웨어에 해를 입히지 않는 입증된 절차입니다. 공유 파일에 쓰는 것은 자주 요청하지 않는 경우 수용 가능합니다. 이것은 이전 제한보다 중요하지는 않지만 스캘핑 전략의 또 다른 제한이라 볼 수 있습니다.
바인딩의 경우 하위 디렉토리를 작성하는 MetaTrader 5 기능을 사용할 수 있습니다. 저는 "모두 (any)"를 체크하지 않았는데도 최대 10 개의 하위 디렉토리가 작성된 걸 볼 수 있었습니다. 확실히말이죠. 그리고 우리는 이를 더 필요로 하지 않습니다. DLL을 사용하여 액세스를 제공할 수는 있지만 DLL 없이 문제를 해결할 수 있는 경우 이를 사용하지 않는 것이 저의 원칙입니다. DLL 없이 이 문제를 해결하려면 MetaTrader 4를 MetaTrader 5 터미널의 \Files\ 디렉토리에 설치하기만 하면 됩니다(파일 작업 참조).
따라서 공유 파일의 경로는 다음과 같습니다.
C:\Program Files\MetaTrader 5\MQL5\Files\MetaTrader 4\experts\files\xxx //where xxx is the name of the shared file.
이 포지션에서 파일은 MetaTrader 4와 MetaTrader 5에서 모두 사용할 수 있으며 파일 공유 가능성은 MQL5의 기능에 의해 제공됩니다.
2.2. MetaTrader 5의 포지션 변경
포지션을 변경하고 자원을 경제적으로 사용하려면 모든 상품에 대한 거래 포지션의 출현/수정/폐쇄를 모니터링하는 기능이 필요합니다. 위에서 거래를 양도하려면 거래 포지션의 양만 알면 되는 것으로 나타났습니다. 볼륨에 기기 기호와 SL 및 TP 레벨을 추가합니다.
변경 사항을 추적하려면 포지션의 이전 상태를 알아야 합니다. 그리고 이전 상태와 현재 상태가 같지 않으면(따라서 포지션이 변경된 경우) 파일에 표시해야 합니다. 이 정보를 파일에 기록하는 함수도 필요합니다. 여러 프로그램에서 동시에 사용할 수 있도록 파일을 열어야 합니다.
포지션 수정의 순간을 놓치지 않으려면 OnTimer() 함수에서 추적 시스템을 구현해야 합니다. 한 번에 모든 인스트루먼트를 추적해야 하고 다른 기호에 대해 틱이 다른 시간에 오기 때문입니다. 또한 파일 내용의 변경에 대한 신호를 보내야 합니다.
2.3. MetaTrader 4에서 신호 수신
파일 업데이트 신호를 추적해야 합니다. 이는 포지션 변경 영역으로의 진입을 위해 상태를 모니터링하는 변수를 통해 정리할 수 있습니다. 포지션 상태가 있는 파일을 읽는 함수가 필요합니다. 표준 기능일 뿐입니다.
계산을 위해 파일 내용을 배열로 전달합니다. 여기서 우리는 파서가 필요합니다. 숫자뿐만 아니라 기호까지 전달되기 때문에 MetaTrader 5에서 전송할 때 모든 것을 문자열로 다시 코딩하는 것이 편리합니다. 또한, 하나의 기호에 대한 모든 데이터를 하나의 텍스트 문자열에 작성하여 데이터 혼동을 제거합니다.
2.4. MetaTrader 4에서 거래 포지션의 반복
가장 큰 기능 집합입니다. 여러 하위 클래스로 나누어야 합니다.
- 가상 포지션 비교;
- 주문 선택 기능;
- 주문 개시 기능;
- 주문 마감 기능;
- 주문 수정 기능.
2.4.1. 가상 포지션 비교
포지션이 일치하는지 확인하려면 가상 포지션의 비교가 필요합니다. 이 기능은 각 기호의 포지션을 별도로 계산해야 하며 거래가 금지된 포지션(있는 경우)을 필터링할 수도 있습니다.
실제로 브로커에 MetaTrader 5에서 전달되는 신호인 기호가 없는 상황이 있을 수 있습니다. 그러나 경고가 제공되어야 하기는 하나 일반적으로 거래를 차단하는 요인이 되서는 안됩니다. 사용자는 그러한 상황에 대해 알 권리가 있습니다.
2.4.2. 주문 선택 기능
이 기능은 추가 작업을 위해 기호에 따라 주문을 선택해야 합니다. 이 경우 열린 포지션만 방송하기 때문에 미결 주문이 없도록 주문도 필터링해야 합니다.
2.4.3. 주문 개시 기능
최대 계산 수를 포함해야 합니다. 따라서 볼륨과 유형을 통과하면 충분합니다.
2.4.4. 주문 마감 기능
이전과 마찬가지로 닫기 주문을 내리기 전에 모든 것을 계산해야 합니다.
2.4.5. 주문 수정 기능
함수에는 시장에 대한 근접성에 대한 검사가 포함되어야 합니다. 또한 모든 브로커가 개설 중 스탑 레벨을 두는 것은 허용되지 않기 때문에 시간이 지남에 따라 주문 및 스탑 레벨을 배치하는 것이 바람직합니다. 또한 공동 주문 개시 및 정지 수준 설정은 재호가 가능성을 높입니다.
따라서 포지션이 빠르게 반복됩니다. 그리고 스톱 레벨을 배치하는 것은 사소한 일이지만 중요하지 않은 건 아닙니다.
3. 구현
코드는 거의 한 줄씩 자세히 설명되어 있습니다. 따라서 코드를 설명할 때 가장 어려운 순간에 대해서만 설명하겠습니다.
MetaTrader 5와 MetaTrader 4 간에 신호를 전달하기 위한 바인딩
바인딩은 MetaTrader 5에서 다음 기능에 의해 구현됩니다.
void WriteFile(string folder="Translator positions") // by default it is the name of the shared file
오프닝 플래그는 다음을 의미합니다.
FILE_WRITE|FILE_SHARE_READ|FILE_ANSI
파일이 쓰기 위해 열려 있습니다 | 읽기를 위해 다른 프로그램에서 공유 사용이 허용됨 | ANSI 인코딩
MetaTrader 4에서 바인딩은 다음 기능에 의해 구현됩니다.
int READS(string files,string &s[],bool resize)
resize 매개변수는 수신된 데이터 배열의 메모리를 재배포하는 것을 금지합니다. 코드에서 이 배열의 메모리는 개발자가 줄 수를 예측할 수 없기 때문에 각 반복마다 할당됩니다. MetaTrader 5에서 선택한 기호의 수에 따라 다릅니다. 따라서 MetaTrader에서 미리 계산할 수 없습니다.
따라서 배열은 각 단계에서 하나씩 증가해야 합니다. 그러나 이 작업은 두 번째 함수 호출에서 차단되어야 합니다. 배열의 길이가 이미 정의되어 있고 변경되지 않기 때문입니다. 이를 위해 bool 크기 조정 변수를 사용합니다.
MetaTrader 5의 포지션 변경
1초의 빈도로 OnTimer 기능에서 변경을 구성합니다. 모든 포지션에 대한 데이터는 함수에서 수신됩니다.
void get_positions()
그런 다음 포지션의 이전 값을 함수의 현재 값과 비교합니다.
bool compare_positions()
그리고 하나 이상의 셀이 일치하지 않는 경우 return(true)이 있는 종료가 발생합니다. return(true)으로 종료하면 포지션이 같지 않고 파일을 다시 작성해야 함을 의미합니다. 파일을 다시 쓸 때 cnt_command 카운터가 1씩 증가합니다.
MetaTrader 4에서 신호 수신
READS() 함수를 사용하여 파일을 읽은 후 문자열 s[]의 채워진 배열이 있습니다.
이 문자열이 유용한 정보로 바뀌려면 파서가 필요합니다.
함수:
int parser(int Size)
라인 식별 함수 호출을 위한 래퍼일 뿐입니다.
void parser_string(int x)
함수는 기호를 제외한 모든 셀을 인식합니다.
기호는 다음 기능을 사용하는 알고리즘 시작 시 한 주기로 인식됩니다.
void parser_string_Symbols(int x)
다음으로 MQL5의 코드에는 적용하지 않고 특별히 언급하지 않는 한 MQL4의 코드만 설명합니다.
가상 포지션 비교
포지션 비교는 두 부분으로 나뉩니다. 포지션의 볼륨 및 유형 비교는 다음 기능에서 구현됩니다.
bool compare_positions()
이 셸에서 포지션의 실제 상태를 가져오기 위한 호출은 함수에서 구현됩니다.
void real_pos_volum()
및 위에서 언급한 "전부 아니면 전무" 원칙에 따른 비교 기능. 즉, 적어도 하나의 셀이 동일하지 않으면 모든 포지션이 다른 것으로 간주됩니다. real_pos_volum()에는 코드에 자세히 설명되어 있고 다른 기능에서 반복적으로 사용될 여러 필터가 구현되어 있습니다.
특히, 하나의 기호에 대한 모든 주문의 볼륨을 가상 포지션으로 합산하는 데 사용됩니다. 잠금 포지션(있는 경우)가 올바르게 처리되도록 하기 위해 매수 주문에는 마이너스가 있고 매도 주문에는 플러스가 있습니다.
비교의 두 번째 부분은 정지 수준을 비교하는 것입니다(정지 수준은 손절매 및 이익 실현). 위의 것과 유사한 기능에서 구현됩니다.
bool compare_sl_tp_levels()
볼륨과 마찬가지로 셸 내부에는 함수의 정지 수준에 대한 정보를 가져오는 호출이 있습니다.void real_pos_sl_tp_levels()
주문 선택 기능
주문은 볼륨을 마감할 때만 선택해야 하므로 복잡한 특수 선택 기능은 마감용으로만 구현됩니다.
void close_market_order(string symbol,double lot)
닫혀야 하는 기호 및 볼륨의 매개변수가 있습니다. 가능한 한 적게 명령을 해제하기 위해 함수의 첫 번째 사이클에서 보증 요청 매개 변수에서 전달된 손실 순서와 볼륨이 같은 순서를 검색합니다. 그리고 이는 매개 변수에 전달된 마감 볼륨이 있는 볼륨과 동일합니다.
그러한 순서가 없는 경우(클로저 플래그 FlagLot의 상태 true에서 알려짐), 지정된 볼륨은 주기의 첫 번째 주문입니다(주문량 초과 확인은 닫기 함수 Closes()에서 구현됨).
정지 수준 수정을 위한 주문 선택은 다음 기능에서 구현됩니다.
void modification_sl_tp_levels()
한 기호 내의 모든 정지 수준이 동일하기 때문에 주문은 기호로만 필터링됩니다.
주문 개시 기능
다음 기능으로 구현됩니다.
int open_market_order(string symbol,int cmd,double volume, int stoploss=0,int takeprofit=0,int magic=0)
여기에는 지정된 데이터를 사용하여 편안하게 주문을 여는 데 필요한 모든 검사가 포함되어 있습니다.
주문 마감 기능
다음 기능으로 구현됩니다.
bool Closes(string symbol,int ticket,double lot)
코드에는 랏 매개변수가 이전에 선택한 주문의 실제 수량을 초과하는 경우에 대한 확인이 포함되어 있습니다.
주문 수정 기능
다음 기능으로 구현됩니다.
bool OrderTradeModif(int ticket,string symbol,int cmd,double price, double stoploss=0,double takeprofit=0,int magic=0)
코드에는 검사가 있으며, 중지 수준이 주문 유형과 일치하지 않는 경우 값이 교환됩니다. 또한 레벨에 이미 요청된 값이 있는지 여부도 확인합니다.
4. 논리의 기능
이전에 그린 계획은 끝났지만 코드에는 아직 설명되지 않은 기능이 있습니다. 그것들은 논리 기능이며 프로세스를 구동하는 기본 기능이라고 말할 수 있습니다.
void processing_signals() void processing_sl_tp_levels()
두 기능 모두 조건부 break로 종료되는 끝없는 순환입니다. 여기서 스크립트 자체가 무한 루프로 구현된다는 점에 유의해야 합니다. 사용자가 프로그램을 편안하게 제거할 수 있도록 주기 (사이클)의 주요 조건에는 IsStopped() 기능이 내장되어 있습니다.
코드는 다음과 같은 방식으로 Expert Advisor에서 루프 스크립트로 전송됩니다.
// Init() while(!IsStopped()) { // Start() Sleep(1000); } // Deinit()
전체 스크립트 논리 (logic)은 표준 함수 start()의 동일한 무한 루프에 설명되어 있습니다.
start()에 있는 주기의 코드는 다음과 같습니다.
If the trade flow is not busy Read the file and save data in an array (not changing the array size); if there have been changes in the file write new comments; remember the time when cycles of compliance check start (located below); if the positions whose volumes are being compared are not equal process the positions by volumes; if the positions whose stops are being compared are not equal process the positions by stops; calculate the end time of checks; If time is not exceeded make a pause for the remaining time;
가장 복잡한 논리적 구성은 processing_signals() 및 processing_sl_tp_levels() 함수에 있습니다.
우리는 "단순한 것에서 복잡한 것으로"라는 원칙에 따라 기능을 설명하기 시작합니다. 코드의 호출은 반대지만요.
//+------------------------------------------------------------------+ //| processing stop levels | //+------------------------------------------------------------------+ void processing_sl_tp_levels() { //--- remember the time of entering the cycle int start=GetTickCount(); while(!IsStopped()) { //--- if the trade flow is not busy if(Busy_and_Connected()) { //--- select the order and modify stop levels modification_sl_tp_levels(); } //--- if the delay time is over, update information from the file if(GetTickCount()-start>delay_time)READS("Translator positions",s,false); //--- if the update counter has changed in the file, exit the cycle if(cnt_command!=StrToInteger(s[0]))break; //--- micro-pause Sleep(50); //--- if real stop levels and those in the file are equal, exit the cycle if(!compare_sl_tp_levels())break; } return; }
앞서 언급했듯이 이 함수는 두 가지 조건에서 종료되는 무한 루프입니다.
루프에서 나가는 첫 번째 조건은 cnt_command 의 값이 파일의 동일한 값과 같지 않은 경우에 발생합니다. 그 전에 루프 작업 시간이 전역 변수 delay_time에 설정된 지연 시간을 초과한 경우 파일에 대한 최신 정보를 받았습니다.
모든 수정 사항이 Busy_and_Connected() 필터에 의해 보호되기 때문에 시간이 초과될 수 있습니다. 즉, 거래 흐름이 자유로운 경우에만 입력하세요.
MetaTrader 4에서는 (MetaTrader 5와 대조적으로) 재호가 없이 서버에 일련의 주문을 보내는 것이 불가능하다는 것을 여기에서 설명해야 합니다. 서버는 첫 번째 요청만 수락할 수 있으며 나머지는 손실됩니다. 따라서 서버에 주문을 내리기 전에 거래 흐름이 자유로운지 확인해야 합니다.
주기를 종료하기 위한 두 번째 검사는 위에서 설명한 정지 수준 compare_sl_tp_levels()에 의한 포지션 비교 기능입니다. 포지션이 같으면 주기를 종료합니다.
이제 복잡한 부분으로 이동하세요. processing_signals () 함수는 유사한 방식으로 구성되지만 논리적 부분은 기능면에서 매우 다릅니다.
이 부분을 자세히 분석해 보겠습니다.
//--- convert the direction of the position stored in the file to the form -1,+1 int TF=SymPosType[i]*2-1; //--- convert the direction of the real position to the form -1,+1 int TR=realSymPosType[i]*2-1; //--- save the volume of the position stored in the file double VF=SymPosVol[i]; //--- save the volume of the real position double VR=realSymPosVol[i]; double lot; //--- if the positions for the current symbol are nor equal if(NormalizeDouble(VF*TF,8)!=NormalizeDouble(VR*TR,8)) { //--- if the real volume is not equal to zero and the directions are not equal or //--- if the directions are equal and the real volume is larger than that in the file if((VR!=0 && TF!=TR) || (TF==TR && VF<VR)) { //--- if the directions are equal and the real volume is larger than that in the file if(TF==TR && VF<VR)lot=realSymPosVol[i]-SymPosVol[i]; //--- if the real volume is not equal to zero and the directions are not equal else lot=realSymPosVol[i]; //--- close the calculated volume and exit the cycle close_market_order(Symbols[i],lot); break; } else { //--- if the directions are equal and the real volume is less than that in the file if(TF==TR && VF>VR)lot=SymPosVol[i]-realSymPosVol[i]; //--- if the directions are not the same and the volume is equal to zero else lot=SymPosVol[i]; //--- open the calculated volume and exit the cycle open_market_order(Symbols[i],SymPosType[i],lot); break; } }
TF 및 TR 변수는 buy=-1,sell=1 형식으로 포지션 유형의 값을 저장합니다. 따라서 TF는 파일에 저장된 값이고 TR은 가상 포지션의 실제 값입니다. 볼륨 VF,VR도 마찬가지입니다.<부분 2026>
따라서, 불일치:if(VF*TF!=VR*TR)
볼륨 또는 포지션 유형이 같지 않은 경우 true가 됩니다.
그런 다음 논리적 연결이 옵니다.
if((VR!=0 && TF!=TR) || (TF==TR && VF<VR))
즉, 실제 거래량이 0이 아니고 유형이 같지 않으면 전체 포지션을 청산해야 합니다.
여기에는 파일의 볼륨이 0일 때의 옵션과 포지션이 방향이 반대일 때의 옵션이 포함됩니다. 변형에서 포지션이 방향이 바뀌면 먼저 열기 위한 포지션을 준비해야 합니다. 즉, 이전 볼륨을 닫습니다. 그런 다음 다음 반복에서 논리는 다른 분기, 즉 열기 (오프닝)로 이동합니다.
논리적 연결의 두 번째 복잡한 조건은 유형이 정확하지만 실제 볼륨이 파일에 저장된 것보다 많으면 실제 볼륨을 줄여야 함을 의미합니다. 이를 위해 먼저 부피를 줄이는 데 필요한 랏의 크기를 계산했습니다.
이 상황에 적합한 마감 조건이 없고 포지션(첫 번째 필터에서 발견한 대로)가 동일하지 않은 경우 새 주문을 열어야 합니다. 여기에 두 가지 변형이 있습니다. 파일에서 포지션의 전체 크기에 대한 주문을 열거나 기존 주문에 추가합니다. 여기서 저는 한계 볼륨 초과에 대한 확인이 개방 기능에서 가능하므로 알고리즘의 다음 반복에서 누락된 볼륨(확인으로 가능하지 않은 경우)이 열립니다. 먼저 Close 상황을 처리하고 나서야 Open 하기 때문에 Lock 상황은 거의 불가능합니다.
한 가지 미묘한 코드 장소를 언급하고 싶습니다. MetaTrader 4에서 막 마감된 주문을 다시 멈춘 상황입니다. 따옴표의 불일치는 종종 5 자리의 2-3 포인트 이내라고 앞서 언급했습니다. 스프레드가 15와 같으면 차이가 미미합니다. 그러나 이러한 차이로 인해 MetaTrader 5보다 먼저 MetaTrader 4에서 손절매 또는 이익실현이 트리거되면 알고리즘이 방금 마감된 포지션을 다시 만들려고 시도하는 상황이 나타났고 MetaTrader 5에서 중지가 트리거된 후속 제거와 함께 발생했습니다.
큰 손실은 없었지만 스프레드 하나가 낭비되었습니다. 따라서 알고리즘이 재설계되어 포지션이 제거된 후 MetaTrader 4는 이를 복원하지 않고 파일 상태가 변경될 때까지 대기합니다. 그리고 나서야 다시 행동을 개시할 것입니다. 이 상황에서 거래자는 잘못된 포지션을 발견하면 수동으로 포지션을 제거할 수 있습니다. 그리고 MetaTrader 5가 파일을 변경할 때까지 복원되지 않습니다.
유일한 약점은 MetaTrader 4가 정지하면 포지션이 제거되고 MetaTrader 5에서는 포지션이 마감되지 않는 드문 상황입니다. 이 경우 Copyist position 스크립트를 다시 시작하도록 조언할 수 있습니다. 그리고 마지막 절 - 코드는 주말에 작업을 확인하지 않습니다. 심각한 것은 아닙니다. 단지 로그만 무가치한 재호가들로 가득 차 있을 것입니다.
5. 실제 구현 확인
C:\Program Files\MetaTrader 5\MQL5\Files\ 디렉토리에 MetaTrader 4를 설치하세요.
MetaTrader 5의 모든 차트에서 컴파일된 Expert Advisor 트랜슬레이터 포지션을 실행합니다(Expert Advisor의 작업은 실행 중인 차트에 의존하지 않음).
그림 2. MetaTrader 5의 트랜슬레이터 포지션
카운터 상태가 첫 번째 줄에 있고 모든 포지션의 로그가 한 줄씩 있는 여러 줄 주석이 표시됩니다.
MetaTrader 4의 차트에서 컴파일된 스크립트 Copyist position을 실행합니다(루핑된 스크립트의 작업은 실행 중인 차트에 종속되지 않음).
그림 3. MetaTrader 4의 카피스트 포지션
그러면 MetaTrader 5에서 모든 Expert Advisor를 실행할 수 있습니다. 작업 결과는 MetaTrader 4에 빠르게 복제됩니다.
그림 4. MetaTrader 4(상단) 및 MetaTrader 5(하단)의 포지션 및 주문
그건 그렇고, MetaTrader 5의 계정 관리는 수동으로 수행하거나 계정은 투자자 비밀번호를 사용하여 로그인할 수 있습니다.
예를 들어, 모든 Championship 계정에서 복제기를 시작할 수 있습니다.
결론
이 글은 트레이더를 새로운 플랫폼으로 빠르게 전환하고 MQL5에 대한 연구를 장려하기 위한 것입니다.
결론적으로 이 코드는 MetaTrader 5의 실제 계정에 대한 직접 거래를 완전히 대체할 수 없다고 말하고 싶습니다. 논리를 고려하지 않고 모든 거래 시스템에 대한 보편적인 코드로 작성되었으므로 보편적인 모든 것과 마찬가지로 이상적이지 않습니다. 그러나 이를 기반으로 특정 전략에 대한 신호 변환기를 작성할 수 있습니다. 프로그래밍과 거리가 먼 많은 거래자에게 릴리스를 예상하는 전환 단계로 작용할 수 있습니다.
프로그래밍에 정통하신 분들은 매직넘버로 주문을 인식할 수 있도록 코드를 수정하고, 주문이체 및 발주를 구현하는 것을 추천합니다. 서버에 안정적으로 연결되어 있다면 대기 중인 주문을 해도 수익에 영향을 미치지 않습니다. 연결 끊김이 자주 발생하는 경우 보류 중인 주문을 포함한 모든 서버 경로를 복제해야 합니다.
새로운 언어를 배우고 이를 사용하여 강력한 시스템을 개발하세요. 거래에 행운을 빕니다.
MetaQuotes 소프트웨어 사를 통해 러시아어가 번역됨.
원본 기고글: https://www.mql5.com/ru/articles/189
![차트에서 거래 아이디어의 빠른 테스트](https://c.mql5.com/2/0/avatar__23.png)
![MetaTrader 5 터미널의 Strategy Tester 내 틱 생성 알고리즘](https://c.mql5.com/2/0/Ticks_Modelling_Algorithm_Metatrader5.png)
![MetaTrader 5의 신호 거래: PAMM 계정에 대한 더 나은 대안!](https://c.mql5.com/2/0/signal_avatar.png)
![MetaTrader 5의 주문, 포지션 및 거래](https://c.mql5.com/2/0/TradeIndo_MQL5.png)