English Русский 中文 Español Deutsch 日本語 Português Français Italiano Türkçe
거래 내역을 기반으로 한 거래 플레이어

거래 내역을 기반으로 한 거래 플레이어

MetaTrader 5트레이딩 | 4 8월 2021, 17:01
87 0
Mykola Demko
Mykola Demko


한 번 보는 것이 두 번 듣는 것보다 낫다

거래 내역의 시각적 분석은 거래자의 분석 작업에서 중요한 부분입니다. 그렇지 않았다면 숫자의 세계를 그림의 세계로 바꾸는 기술적 분석은 없었을 것입니다. 글쎄요, 인간 지각의 80%가 눈으로 이루어지기 때문인 건 분명한 것 같습니다. 정보를 일반화하는 통계는 많은 뉘앙스를 말할 수 없습니다. 그리고 숫자의 세계에 대한 직관적인 인식을 가진 시각화만이 t를 넘을 수 있습니다. 한 번 보는 것이 두 번 듣는 것보다 낫다고 합니다.

이 글에서는 거래 내역의 시각적 표시를 자동화하기 위한 Expert Advisor를 작성하는 방법을 고려하지 않을 것입니다. 우리는 객체 간의 정보 전달, 거대한 응용 프로그램 계획, 차트 관리, 다른 기호의 정보 동기화 등의 문제에 대해 논의할 것입니다.

전통적으로 먼저 플레이어 애플리케이션 및 관련 스크립트의 이점에 대해 설명한 다음 코드 분석으로 이동합니다.


MetaTrader 5 전략 테스터에서 거래 실행

플레이어의 작동은 MetaTrader 5 HTML 보고서를 기반으로 합니다. 따라서 Automated Trading Championship 2010의 이력은 ATC-2010에 필요한 계정에 로그인하여 HTML 보고서로 거래 이력을 저장하면 얻을 수 있습니다.

Automated Trading Championship 2008의 서버가 중지되어 같은 방법으로 만들 수 없습니다. 이 사이트에는 단일 zip 아카이브로 포장된 모든 참가자의 일반 보고서가 포함되어 있습니다. Automated_Trading_Championship_2008_All_Trades.zip

"Automated Trading Championship 2008 All Trades.zip" 아카이브는 MetaTrader 5 설치 디렉토리의 \Files 폴더에 압축을 풀어야 합니다.

Automated Trading Championship 2008의 기록을 분석하려면 기록을 구문 분석하고 지정된 로그인에 대해 선택하고 바이너리 파일에 저장할 Report Parser MT4 스크립트를 실행해야 합니다. 이 바이너리 파일은 플레이어 보고서 Expert Advisor이 읽습니다.

플레이어 보고서 EA는 필요한 로그인이 지정된 전략 테스터에서 실행되어야 합니다. 테스트가 끝나면 보고서를 HTML 형식으로 저장합니다. 지정된 로그인은 테스트 결과에 영향을 미치지 않지만 보고서에 입력 매개변수 "login"으로 표시됩니다. 보고서를 더 잘 식별할 수 있습니다. 보고서는 동일한 Expert Advisor에 의해 생성되므로 기본 이름과 다른 이름을 지정하는 것이 좋습니다.

Report Parser MT4 스크립트에는 기록을 보고 싶은 참가자의 로그인을 지정해야 하는 "login" 입력 매개변수도 있습니다. 참가자의 로그인은 모르지만 닉네임은 알고 있는 경우 로그인 값이 0(기본값)인 스크립트를 시작합니다. 이 경우 스크립트는 로그인으로 선택하지 않습니다. 모든 로그인이 알파벳순으로 나열되는 csv 파일을 생성합니다. 파일 이름은 "Automated Trading Championship 2008 All Trades_plus"입니다. 이 파일에서 필요한 참여자를 찾으면 지정된 로그인으로 스크립트를 다시 한 번 실행하십시오.

따라서 Report Parser MT4 스크립트와 Player Report EA는 MetaTrader 4 형식의 거래 내역을 기반으로 MetaTrader 5 Strategy Tester의 표준 html 보고서를 생성합니다.

플레이어 리포트 Expert Advisor는 실제 실행된 거래를 정확히 실행하지 않고 대략적으로 처리합니다. 그 이유는 다른 인용문, 보고서의 시간을 분 단위로 반올림 및 실행 중 슬리피지입니다. 대부분의 경우 그 차이는 거래의 10%에서 발생한다는 점에서 몇 가지 점입니다. 그러나 예를 들어 전략 테스터의 이익을 ~170,000에서 ~160,000으로 줄이는 것으로 충분합니다. 모든 것은 미끄러짐이 있는 거래의 양에 달려 있습니다.


플레이어의 작동

앞서 언급했듯이 플레이어는 추가 애플리케이션을 사용하여 Automated Trading Championship 2008의 거래 내역을 볼 수 있으며 Automated Trading Championship 2010을 직접 볼 수 있습니다.

또한 플레이어는 모든 MetaTrader 5 보고서를 지원하므로 전략 테스터에서 실행되는 모든 Expert Advisor의 거래 내역 또는 테스터가 형식화하지 않았지만 "도구 상자" 창의 "History" 탭에서 보고서로 저장된 수동 거래 내역을 볼 수 있습니다.

Player History Trades exp v5 Expert Advisor의 매개변수:

MetaTrader 5 전략 테스터의 보고서는 거래 내역 플레이어의 입력 파일로 사용됩니다. Player History Trades exp v5 EA "전략 테스터 보고서의 html 파일 이름"의 입력 매개변수로 지정해야 하는 보고서 파일의 이름입니다. 플레이어를 시작할 때 사용자는 "기록 시작" 및 "기록 끝" 입력 변수에서 재생 기간을 지정할 수 있습니다.

이러한 변수가 설정되지 않은 경우 플레이어는 첫 번째 거래에서 시작하여 마지막 거래로 끝나는 거래 내역에서 변수를 가져옵니다. 거래에 사용되는 기호의 수는 차이가 없습니다. 계정의 첫 번째 및 마지막 거래 시간만 고려됩니다.

또한 사용자는 차트를 분석해야 하는 기호의 이름을 설정할 수 있습니다. 이름은 "필수 차트 목록" 변수에 열거형으로 지정해야 합니다. 이 변수의 분석은 구분 기호의 대소문자 및 유형에 민감하지 않습니다. 변수가 설정되어 있지 않으면 계정에서 거래되는 모든 기호가 열립니다. 그리고 때때로 그것들이 많이 있습니다.

예를 들어, Manov는 거래에서 12개의 통화 쌍을 사용했습니다. 한 번에 4개 이하의 기호를 설정하는 것이 좋습니다. 첫째, 그것들을 정리하는 것이 편리합니다. 둘째, 많은 차트가 재생 속도를 늦춥니다. 각 심볼은 일반 루프에서 처리되기 때문에 심볼의 수를 늘리면 틱 생성이 느려집니다.

플레이어는 거래에 사용되지 않은 기호를 지정해도 작동합니다. 이 경우 차트에는 거래가 표시되지 않으며 다른 차트와 동일합니다. 또한 균형 지표가 부착되어 있습니다. 그러나 모든 변형에서 일반 저울의 이력만 표시합니다.

"EA 삭제 시 차트 삭제" 매개변수에 대한 설명을 의도적으로 건너뛰었습니다. 이는 관리가 아니라 Expert Advisor의 행동에 관한 것입니다. 요점은 Expert Advisor가 운영을 위해 많은 정보를 분석한다는 것입니다. EA가 가지고 있는 일부 정보가 파일 형태로 분석에 유용할 것이라고 판단했습니다. Expert Advisor는 각 기호에 대한 거래 작업이 포함된 csv 파일과 모든 기호의 동기화된 잔액이 있는 파일을 생성하므로 다중 통화 바구니에서 기호를 감지하는 데 유용할 수 있습니다.

Expert Advisor에서 자동으로 연 차트를 삭제할 때도 동일한 변수가 사용됩니다. 전통적으로 EA는 작업이 끝나면 작업장을 청소해야 합니다. 그러나 사용자가 EA 컨트롤 없이 차트를 자세히 분석하려면 "EA 삭제 시 차트 삭제" 매개변수를 'false'로 설정하여 EA를 시작해야 합니다.

다음 매개변수는 그다지 중요하지 않습니다.

생성기의 주기는 틱 생성기의 초기 매개변수를 설정합니다. 여기에서 "틱"이라는 용어는 고전적인 의미로 사용되지 않습니다. 레벨의 변화를 의미합니다. Expert Advisor에서는 바의 4점에 따라 눈금이 생성됩니다. "생성기의 기간" 매개변수는 생성기의 초기 상태를 설정합니다. 또한 작동하는 동안 플레이어에서 이 매개변수를 변경할 수 있습니다.

M1에서 시작하는 모든 기간을 생성하지 않는 이유는 무엇입니까? 발전기의 주기를 변경해야 하는 이유는 무엇입니까? 문제는 더 큰 시간대의 바에는 많은 M1 바가 포함되어 있으므로 생성 프로세스의 속도를 높여야 할 수도 있습니다. 그렇기 때문에 기간 변경 가능성이 구현됩니다. 모든 시간 프레임이 생성기에서 구현되는 것은 아니며 일부만 구현됩니다. 코드에서 변경하는 방법은 나중에 설명하겠습니다.

"거래에 대한 의견의 글꼴" 매개변수는 예를 들어 거래에 대한 의견이 거래 자체를 보는 데 방해가 될 때 유용할 수 있습니다. 크기를 1로 설정하면 비문이 가는 선으로 보이며 보기에 방해가 되지 않습니다. 툴팁에서 개체 이름을 찾을 때 "개체 목록" 탭에서 거래량과 위치를 볼 수 있습니다.

거래 내역은 별도의 거래로 그려지지만 그어진 선은 포지션 유형에 따라 다릅니다.

"구매 작업 색상""판매 작업 색상"을 사용하여 원하는 색상을 설정할 수 있습니다.

거래 내역 표시

위의 스크린샷을 보면 포지션 수준이 거래 수준과 다른 경우가 많다는 것을 알 수 있습니다.

그러나 이익은 포지션 수준을 기준으로 계산됩니다. 그래서 추세선으로 포지션을 표시하고 수직선을 사용하여 포지션과 거래의 수준을 연결하기로 결정했습니다. 위치 수준 근처의 주석에는 다음 정보가 표시됩니다.

[deal volume|position volume]

거래 유형이 위치 유형과 일치하지 않는 경우(예: 부분 청산) 거래량이 추가 기호와 함께 표시됩니다.

[<deal volume>|position volume]

우선 거래 보고서에 표시되는 거래량을 볼 수 있습니다. 포지션의 양은 이전 포지션의 상태와 거래로 인한 변경 사항을 기반으로 계산됩니다.

"숫자" 매개변수는 재생 속도를 줄이는 단계 수를 조절합니다. 플레이어가 최대 속도로 시작됩니다. 또한 "속도 수" 매개변수 값 내에서 속도를 줄이거나 늘릴 수 있습니다. 따라서 속도 버튼과 생성기의 기간은 거래 내역의 재생 속도를 관리하기 위한 전체 범위의 도구를 구성합니다.

그리고 마지막 매개변수는 "vert. 진행 버튼의 크기". 진행 표시줄의 큰 버튼을 선호하는 사용자를 위해 만들었습니다. 일반적으로 제 목표는 컨트롤 뒤에 차트를 숨기는 것을 피하는 것이었습니다. 그렇기 때문에 "vert. 진행 버튼의 크기" 매개변수가 8로 설정됩니다.

이제 플레이어의 컨트롤로 이동해 보겠습니다.

플레이어의 컨트롤

속도 는 왼쪽 및 오른쪽 화살표를 사용하여 제어됩니다. 제어 모드는 가운데(사각형) 버튼의 상태에 따라 다릅니다. 누르지 않은 상태에서 속도를 변경하고 누른 상태에서 발전기의 주기를 변경합니다.

균형 지표를 제어하는 ​​개체는 완전한 타원형으로 표시되지만 실제로는 시각적 크기의 경계를 크게 초과하는 두 개의 큰 버튼으로 구성됩니다. 왼쪽 버튼은 차트에서 균형 지표를 추가 및 삭제하기 위한 것이고 오른쪽 버튼은 데이터 내용을 제어합니다.

"전체" 상태에서는 계정의 총 잔액에 대한 정보가 표시됩니다. "합계" 상태는 지표가 실행되는 차트 기호에 대한 잔액 샘플링을 표시하기 위한 것입니다. 지표 제어는 비동기식이며, 이는 지표가 한 차트에서 실행되고 다른 차트에서는 실행되지 않을 수 있음을 의미합니다. 

균형의 지표

균형 지표를 제어하는 ​​대상은 차트 동기화의 유일한 예외입니다. 컨트롤의 다른 모든 개체는 동기화됩니다. 즉, 심볼에 대한 변경 사항은 자동으로 다른 심볼에 적용됩니다.

재생/중지는 누르는 즉시 수행할 작업을 표시합니다. 재생하는 동안 두 개의 작은 줄이 표시되어 누르면 작업이 일시 중지됩니다. 그리고 그 반대의 경우에도 삼각형은 일시 정지 상태로 표시됩니다. 따라서 그것을 누르면 플레이어가 작동을 시작합니다.

진행 라인은 트리거로 만들어진 100개의 제어 버튼으로 구성됩니다. 버튼을 누르면 다른 모든 버튼이 눌러지지 않습니다. 버튼이 100개라서 재생시간은 100부분으로 나뉩니다. 바의 수가 100으로 나누어지지 않으면 나머지가 마지막 부분에 추가됩니다. 이것이 설정에 "기록 시작" 및 "기록 끝" 매개변수가 포함되는 이유입니다. 이 매개변수를 변경하면 필요한 기록 기간으로 이동할 수 있습니다.

버튼을 누름으로써 사용자는 내부 틱 생성기의 날짜를 변경하고 영점 바를 탐색합니다. 누르지 않았지만 발전기의 내부 시간이 이미 활성 버튼 외부로 이동한 경우 플레이어는 자체적으로 해당 전환을 수행합니다.

따라서 "진행 라인" 개체는 진행률의 지표이자 탐색의 활성 제어입니다. 플레이어의 제어 개체는 자동으로 숨겨지고 차트 중앙으로 확장됩니다. 따라서 진행 라인의 특정 버튼을 눌러야 하는 경우 차트를 전체 화면으로 확장합니다.

이제 플레이어가 관리하는 차트의 동작에 대해 이야기해 보겠습니다. 플레이어는 모든 차트의 동기화를 수행하지만, 메인 차트에서 수행된 스케일, 차트 종류, 색 구성표, 제로 바 이동 등의 변경이 다른 차트에서도 반복된다는 것을 의미하지는 않습니다.

변경 사항에는 기간 변경이 포함됩니다. 여기서 플레이어가 주요 차트로 간주하는 차트는 파란색 활동 선이 있는 차트가 아니라 컨트롤이 표시되는 차트라는 점에 유의해야 합니다. 일반적으로 하나의 동일한 차트이지만 항상 그런 것은 아닙니다. 차트를 활성화하려면 차트 필드에서 차트를 클릭하세요.

플레이어를 사용하는 기능이 있습니다. 두 개체가 같은 필드에 있으면 버튼이 작동을 멈춥니다. 그렇기 때문에 때때로 입찰선이 플레이어 필드를 넘을 때 버튼을 누르기 위해 다른 차트로 전환하거나 차트의 수직 스케일을 변경해야 합니다.



비디오는 ATC 2010 참가자 중 한 명인 Manov의 트레이딩 재생을 보여줍니다. 그것을 만들기 위해 나는 login=630165 및 password=MetaTrader 매개변수를 사용하여 클라이언트 터미널에서 그의 계정에 연결했습니다. 트레이딩 보고서는 terminal_data_folder\MQL5\Files 폴더의 ReportHistory-630165.html 이름으로 저장되었습니다. 이 파일을 아카이브로 다운로드하고 지정된 폴더에 압축을 풉니다.


시작 준비

  1. 모든 것이 작동하도록 하려면 player_history_trades.zip을 다운로드하고 terminal_data_folder/MQL5/Indicators 폴더에 압축을 풉니다.
  2. 복사한 Player History Trades 폴더를 열고 MetaEditor의 루트 디렉토리에 있는 4개의 파일을 컴파일하십시오. 파일의 컴파일 순서는 중요하지 않습니다.
  3. 트레이딩 보고서의 모든 기호에 대해 필요한 이력 기간이 М1 기간에 제공되는지 확인하십시오. 이를 수행하려면 M1 기간으로 필요한 차트를 수동으로 열고 수직선을 배치한 다음 컨텍스트 메뉴의 Ctrl+B 키 조합을 사용하여 개체 목록을 엽니다. 그런 다음 수직선의 날짜를 거래 시작 날짜로 변경합니다.
  4. 그런 다음 "표시" 버튼을 누릅니다. 따옴표가 없으면 두 가지 이유가 있을 수 있습니다. 다운로드되지 않았거나 "차트의 최대 바" 매개변수가 너무 작습니다. 이를 보려면 도구->옵션->차트로 이동하십시오.

이제 모든 것이 작동해야 합니다.


개발의 시작

응용 프로그램을 개발하려면 계획이 있어야 합니다. 계획은 공부하면서 블록 다이어그램으로 바뀌고 코드로 바뀝니다. 그러나 프로젝트 자체는 더 일찍 시작됩니다. 모든 프로젝트의 시작점은 사용자가 요구하는 애플리케이션 속성입니다. 그렇다면 트레이드 히스토리의 플레이어는 어떤 속성을 가져야 할까요? 

  1. 다중 통화입니다.
  2. 필요한 차트의 자동 열기.
  3. 편리한 탐색 인터페이스와 양방향으로 기록을 스크롤할 수 있는 가능성.
  4. 모든 차트에 동시 표시.
  5. 재생 시작/일시 중지.
  6. 표시되는 차트의 수와 기호를 선택할 수 있습니다(및 기본 모드).
  7. 플레이어가 작업할 기간(및 기본 모드)을 선택할 수 있습니다.
  8. 차트에 거래 내역 표시.
  9. 균형 및 형평성의 내역 표시.
  10. 기호의 잔액(자본)과 계정의 총 잔액(자본)을 별도로 표시합니다.

처음 4개 항목은 일반적인 개념을 결정합니다. 다른 속성은 메소드 구현 방향을 결정합니다.

플레이어의 일반적인 작동 계획:

  1. HTML 보고서를 로드합니다.
  2. 거래를 분석하고 위치 기록을 복원하십시오.
  3. 개설/마감을 위한 주문 대기열로 거래를 준비합니다.
  4. 사용자 명령에서 지표(자기자본 차트, 손실액 등)의 형태로 필요한 비율을 계산하여 거래 내역의 역학을 표시하기 시작합니다.
  5. 다른 요금과 함께 차트에 정보 패널 표시를 구성합니다.

또한 MetaTrader 4 보고서에 따르면 전략 테스터에서 거래하려면 특별 Expert Advisor이 필요합니다.

  1. 구문 분석된 거래는 Expert Advisor의 바이너리 데이터 파일로 작성되어야 합니다.
  2. MetaTrader 5 전략 테스터의 보고서를 작성하십시오.

이것은 개발을 시작하기 위한 일반적인 계획이며 요구 사항의 사양입니다. 가지고 있다면 개념에서 기능 구현에 이르기까지 위에서 아래로 코드 작성을 계획할 수 있습니다.

글을 확장하는 것이 아니라 코드의 가장 중요한 부분만 설명하겠습니다. 주석이 잘 되어 있으므로 코드를 읽을 때 문제가 발생하지 않아야 합니다.


주문 및 거래

현재 두 가지 트레이딩 개념이 있습니다. MetaTrader 4에서 사용되는 기존 개념과 실제 입찰에 사용되는 MetaTrader 5에서 사용되는 개념으로 "netting" 개념이라고 합니다. 이들 간의 차이점에 대한 자세한 설명은 MetaTrader 5의 주문, 위치 및 거래 문서에 나와 있습니다.

한 가지 중요한 차이점만 설명하겠습니다. MetaTrader 4에서 주문은 개장 시간, 시가 및 거래량에 대한 정보를 저장하는 컨테이너로 나타낼 수 있습니다. 그리고 컨테이너의 문이 열려 있는 동안에는 활성 트레이딩 상태입니다. 컨테이너를 닫는 즉시 컨테이너의 모든 정보가 기록으로 이동됩니다.

MetaTrader 5에서는 위치가 이러한 컨테이너로 사용됩니다. 그러나 중요한 차이점은 포지션의 이력이 없다는 것입니다. 주문과 거래의 공통된 이력만 있을 뿐입니다. 그리고 이력에는 포지션의 이력을 복원하는 데 필요한 모든 정보가 포함되어 있지만 생각의 재구성에 시간을 할애해야 합니다.

ORDER_POSITION_IDDEAL_POSITION_ID 식별자를 각각 사용하여 선택한 주문 또는 거래가 속한 위치를 찾을 수 있습니다. 따라서 MetaTrader 5에 적합한 형식으로 히스토리를 변환하기 위해 MetaTrader 4 히스토리의 주문을 두 개의 개별 거래(개설 및 마감 거래)로 나눕니다.


HTML 파서

컴퓨터 속어에 대해 잘 모르시는 분들을 위해 parse라는 단어가 무엇을 의미하는지 설명하겠습니다. 구문 분석은 입력 텍스트와 지정된 문법의 일치를 확인하고 이에 따라 구문 분석 트리를 구성하는 텍스트 또는 어휘 시퀀스(기호, 단어, 바이트 등)의 구문적(문법적 또는 어휘적) 분석을 의미합니다. 그렇게 되면 추가 계산 또는 변환을 수행할 수 있게 됩니다.

두 개의 큰 클래스 CTable과 CHTML이 파서에서 사용됩니다. CTable 클래스의 사용법은 Electronic Tables in MQL5 문서에 자세히 설명되어 있으므로 다시 설명하지 않겠습니다.

HTML 구문 분석을 위해 CHTML 클래스를 개발했습니다. 제 기본 생각에 따르면, 그 설명은 글이 되어야 합니다. 하지만 글을 쓰기에는 수업이 너무 간단해서 간략하게 설명하겠습니다.

클래스의 일반적인 개념은 '태그'라는 용어로 설명할 수 있습니다. 태그는 인클로저가 있는 기능으로 나타낼 수 있습니다. 예를 들어, Tag(header,casket), 여기서 'header'는 태그 제목(페이지 모양을 제어하는 ​​태그 변수는 일반적으로 여기에 지정됨)이고 'casket'은 태그 컨테이너의 내용입니다. 이러한 태그는 전체 HTML 언어로 구성됩니다.

클래스의 일반적인 구조는 객체의 3단계 호출로 나타낼 수 있습니다. CHTML 클래스의 인스턴스는 해당 본문에 가능한 모든 태그의 개체를 만듭니다. 태그의 기능은 템플릿에 의해 생성되며, 두 플래그의 이름과 설정만 서로 다릅니다.

하나의 플래그는 헤더의 존재를 결정하고 다른 하나는 관의 존재를 결정합니다. 이러한 플래그를 사용하면 모든 태그를 공통 구조로 표시할 수 있습니다. 각 태그 인스턴스는 본문에 CTeg 클래스의 인스턴스를 만듭니다. 이 클래스는 모든 태그에 대한 공통 메소드를 포함하며 문서 본문에서 필요한 태그를 검색하는 주요 작업을 수행합니다.

3단계 호출은 다음과 같습니다.

h.td.base.casket

이 비문은 'h' 객체가 중첩 객체 'base'( CTegs 클래스의 객체임).

이 클래스에는 태그를 검색하는 메소드도 포함되어 있으며 공개 메소드에 결합되어 있습니다.

h.td.Search(text,start);

태그 끝의 검색 지점을 반환하고 태그의 '헤더' 및 '상자' 변수를 채웁니다.

수업에서 준비한 다른 기능은 사용하지 않으므로 설명하지 않겠습니다. 다른 흥미로운 내용이 많이 있습니다.

HTML 문서 작업에 대한 설명 끝에서 이 글에서는 두 가지 유형의 파서가 사용된다는 점을 언급하고 싶습니다. 파일에서 얻은 정보의 저장 유형만 다릅니다. 첫 번째 유형은 전체 문서를 '문자열' 유형의 단일 변수에 저장하는 방식으로 플레이어에서 사용됩니다. 두 번째 유형은 보고서의 라인별 구문 분석을 사용합니다. 챔피언십 2008의 내역을 준비하기 위한 스크립트에서 사용됩니다.

두 가지 접근 방식을 사용하는 이유는 무엇입니까? 문제는 CTegs 클래스의 올바른 기능 작동을 위해 전체 태그가 분석된 문자열에 배치되어야 한다는 것입니다. 그리고 항상 가능한 것은 아닙니다. 예를 들어, table, html, body와 같은 태그의 경우(여러 줄임). 문자열 유형의 변수를 사용하면 표 기호 없이 32750개의 기호를 저장할 수 있습니다(내 계산에 따르면). 그리고 '\r'(각 32748번째 기호 뒤에)을 사용하여 최대 2,000,000개의 기호를 저장할 수 있었습니다만 이 값에 도달한 후 시도를 중단했습니다. 아마도 더 많은 기호를 저장할 수 있을 것 같습니다.

그렇다면 두 가지 접근 방식을 사용하는 이유는 무엇입니까? 요점은 적절한 테이블을 찾는 데 필요한 플레이어의 범용 파서를 위한 것입니다. 테스터 보고서 및 거래 내역 보고서에 필요한 테이블은 서로 다른 위치에 있습니다. 다양성을 유지하기 위해(파서가 두 보고서를 모두 이해할 수 있도록) "deals"가 포함된 'td' 태그로 테이블을 검색하는 방식을 사용합니다.

챔피언십 2008 보고서의 구조는 알려져 있으며 필요한 테이블을 검색할 필요가 없습니다. 그러나 보고서 문서는 방대하고(35MB) 전체 보고서를 단일 변수에 배치하는 데 많은 시간이 걸립니다. 이 상황은 구문 분석에 대한 두 번째 접근 방식을 규정합니다.


플레이어

플레이어에 대한 10가지 요구 사항은 "개발 시작" 섹션에 설명되어 있습니다. 멀티 화폐가 우선이기 때문에 Expert Advisor가 차트를 관리해야 합니다. 각 차트가 플레이어가 작동하는 데 필요한 모든 기능을 가진 별도의 개체에 의해 처리된다면 논리적일 것입니다.

우리는 히스토리를 가지고 작업하기 때문에 우리가 원할 때 언제든지 얻을 수 있기를 바라는 대신에 중단 없는 작동을 위해 별도의 히스토리 예제가 필요합니다. 또한 동일한 이력을 반복적으로 가져오는 것은 플레이어에 보관하는 것보다 낭비입니다. 결국 다음과 같은 계획이 나옵니다.

트레이딩 이력 선수의 일반적인 계획

객체 지향 프로그래밍(OOP)을 사용하면 블록 시스템을 사용하여 매우 큰 응용 프로그램을 작성할 수 있습니다. Expert Advisor 코드의 개발된 부분은 이전에 스크립트로 작성하고 디버깅한 다음 최소한의 조정으로 Expert Advisor에 연결할 수 있습니다.

이러한 개발 계획은 연결된 코드에 오류가 포함되어 있지 않고(오류 없이 스크립트에서 작동하기 때문에) 발견된 버그가 적응 오류임을 확신하기 때문에 편리합니다. 코드가 상향식으로 작성되면 한 곳에서 모든 것을 프로시저로 설명할 때 이러한 이점이 없습니다. 그리고 응용 프로그램의 모든 위치에 새로운 버그가 나타날 수 있습니다.

따라서 위에서 아래로 프로그래밍하는 것은 애플리케이션 작성의 단순성과 속도 면에서 이점이 있습니다. "여기서 간단한 것이 무엇입니까?"라고 물을 수 있습니다. 저는 비유로 대답하겠습니다. 자전거 타기를 배우는 것은 어렵지만 일단 배우면 그 과정을 눈치 채지 못할 것입니다. 빠른 라이딩을 즐길 수 있습니다. OOP 구문을 배우면 큰 이점을 얻을 수 있습니다.


내레이션을 계속하려면 OOP의 세 가지 용어인 연관, 집계 및 구성을 설명해야 합니다.

  • 연관은 개체 간의 연결을 의미합니다. 집계 및 구성은 협회의 특정 사례입니다.
  • 집계는 개체가 "일부" 관계와 연결되어 있음을 의미합니다. 집계는 여러 개일 수 있습니다. 즉, 하나의 개체가 여러 클래스 또는 개체에서 집계될 수 있습니다.
  • 구성은 보다 엄격한 집계 변형입니다. "일부" 요구사항 외에도 이 "일부"는 다른 "소유자"에 동시에 속할 수 없으며 소유자가 삭제되면 삭제됩니다.

연관(association)에는 집합(aggregation)과 구성(composition)이 포함되기 때문에 세부 분석에서는 집합(aggregation)이나 구성(composition)으로 설명할 수 없는 모든 경우를 연관(association)이라고 합니다. 일반적으로 세 가지 관용구를 모두 연관이라고 합니다.

class Base
  {
public:
                     Base(void){};
                    ~Base(void){};
   int               a;
  };
//+------------------------------------------------------------------+

class A_Association
  {
public:
                     A_Association(void){};
                    ~A_Association(void){};
   void              Association(Base *a_){};
   // At association, data of the bound object 
   // will be available through the object pointer only in the method, 
   // where the pointer is passed.
  };
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
class A_Aggregation
  {
   Base             *a;
public:
                     A_Aggregation(void){};
                    ~A_Aggregation(void){};
   void              Aggregation(Base *a_){a=a_;};
   // At aggregation, data of the bound object 
   // will be available through the object pointer in any method of the class.
  };
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
class A_Composition
  {
   Base             *a;
public:
                     A_Composition(void){ a=new Base;};
                    ~A_Composition(void){delete a;};
   // At composition, the object becomes the class member.
  };

MQL5에는 매개변수를 통해 포인터를 전달하는 함수가 있습니다. 

GetPointer(pointer)

매개변수는 객체 포인터입니다.

예:

void OnStart()
  {
   Base a; 
   A_Association b;
   b.Association(GetPointer(a));
  }


내 코드의 OnInit()에서 호출되는 함수는 종종 연관을 사용합니다. 컴포지션은 CHTML 클래스에 적용됩니다. 그리고 CPlayer 클래스 내에서 개체를 바인딩하기 위해 집계와 구성을 함께 사용합니다. 예를 들어 집계를 사용하여 CChartData 및 SBase 클래스의 개체는 플레이어에서 구성을 사용하여 만든 모든 개체에 대한 공통 데이터 필드를 만듭니다.

시각적으로 다음과 같이 나타낼 수 있습니다.

데이터 바인딩

CPlayer 클래스에서 객체가 복합적으로 생성되는 클래스는 기능이 더욱 확장된 템플릿 구조를 갖습니다. 템플릿 사용법은 C++ 템플릿의 대안으로 가짜 템플릿 사용 문서에 설명되어 있으므로 여기서는 자세한 설명을 생략하겠습니다.

클래스의 템플릿은 다음과 같습니다.

//this_is_the_start_point
//+******************************************************************+
class _XXX_
  {
private:
   long              chart_id;
   string            name;
   SBase            *s;
   CChartData       *d;
public:
   bool              state;
                     _XXX_(){state=0;};
                    ~_XXX_(){};
   void              Create(long Chart_id, SBase *base, CChartData *data);
   void              Update();
  };
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void _XXX_::Create(long Chart_id, SBase *base, CChartData *data)
  {
   chart_id=Chart_id;
   s=base; // binding data to the player structure
   d=data; // binding data to the chart structure
   name=" "+ChartSymbol(chart_id);

   if(ObjectFind(chart_id,name)<0)// if there is no object yet
     {//--- try to create the object         
      if(ObjectCreate(chart_id,name,OBJ_TREND,0,0,0,0,0))
        {//---
        }
      else
        {//--- failed to create the object, tell about it
         Print("Failed to create the object"+name+". Error code ",GetLastError());
         ResetLastError();
        }
     }       
  };
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void _XXX_::Update()
  {
  };
//+******************************************************************+
//this_is_the_end_point

그래서 템플릿으로 빈 클래스를 만들고 연결하고 모든 요청을 올바르게 처리하는지 확인하고 나서야 필요한 기능으로 복합 클래스를 채우기 시작했습니다. 이것을 하향식 프로그래밍이라고 합니다. 실패할 경우 그 이유를 어디에서 찾아야 하는지 알고 있습니다.

이제 건물의 일반적인 개념이 명확해졌으므로 세부적으로 진행할 수 있습니다.

먼저 Player History Trades exp v5 Expert Advisor에서 선언한 함수의 동작을 살펴봅시다.

OnInit() 함수는 일반적으로 정보를 준비합니다. 전략 테스터의 보고서를 구문 분석하고, 거래된 모든 금융 상품 목록을 가져오고, 거래를 처리하고, 포지션의 볼륨과 수준을 계산한 다음 차트에 기록을 그리는 CParser_Tester 클래스의 개체를 만듭니다. 마지막 항목은 데이터가 전달된 직후 객체가 삭제되지 않는 이유를 설명합니다. 문제는 차트가 열리기 전에 정보가 준비된다는 것입니다. 그리고 그래픽 개체를 그리기 위해서는 차트 ID가 필요합니다. 그래서 CParser_Tester 클래스의 객체는 나중에 삭제됩니다.

또한 거래에 사용되는 기호의 이름이 있으므로 Balance_Process() 함수를 호출하여 M1 이력을 기반으로 전체 잔액 및 자본뿐만 아니라 전달된 모든 기호의 잔액과 자산을 계산합니다.

이 부분에서; 응용 프로그램은 정보 부족에 특히 민감합니다. 그래서 심볼 중 하나에 대한 정보가 다운로드되지 않는 경우 EA 실행 중단을 구현했습니다. 응용 프로그램 실행이 중지되면 다운로드해야 하는 기호 정보가 포함된 경고가 표시됩니다.

Balance_Process() 함수의 작업 결과는 잔액 지표에 의해 필요한 기간으로 추가로 절단된 M1의 잔액 및 자본 이력의 이진 파일입니다. 글쎄요, 제가 앞서 나가고 있는 것 같네요. 균형 지표의 작동은 나중에 설명하겠습니다.

Expert Advisor를 시작하는 다음 단계는 기호 선택입니다. 여기에서 입력 매개변수 "필수 차트 목록"을 분석합니다. 필요한 기호가 "시세" 목록에 있는 경우 기호 배열에 추가합니다. 이러한 방식으로 사용자가 기호 이름 대신 abracadabra를 지정하거나 잘못 인쇄할 수 있으므로 "바보"로부터 자신을 보호합니다.

사용자가 열기 위해 요청한 확인된 기호 목록이 있으므로 차트를 열 수 있습니다. 다음 기능을 사용하여 수행됩니다.

ChartOpen(symbol,period)

이 함수는 매개변수에서 기호와 마침표가 전달된 차트를 엽니다. 이론상 이 함수는 열린 차트의 ID를 반환하지만 항상 발생하는 것은 아닙니다.

ID 분실로 인해 애플리케이션이 오작동합니다. 이를 피하기 위해 두 가지 기능을 만들었습니다.

ChartTotal(arrayID);   // get the list of charts before opening additional charts
CurrentChart(arrayID); // get the list of chart for operation

하나의 함수는 차트를 열기 전에 실행되고 다른 하나는 차트를 연 후에 실행됩니다. ChartTotal() 함수는 EA가 시작되기 전에 열린 차트 목록(EA가 실행되는 차트 포함)을 가져와서 해당 ID를 입력 배열에 저장합니다.

CurrentChart() 함수는 해당 정보를 얻고 이미 열려 있는 차트를 고려하여 새 목록을 만듭니다. 그런 다음 목록의 차이에 따라 EA에서 생성한 차트의 ID를 매개변수 배열로 전달합니다. 이 계획은 차트 열기 사실에 따라 작동하기 때문에 신뢰할 수 있습니다.

이제 필요한 차트의 ID가 있으므로 이를 제어할 수 있습니다. 이를 수행하려면 루프의 모든 차트를 살펴보고 CParser_Tester의 개체를 사용하여(이전에 내가 필요하다고 말한 것처럼) 거래 내역을 그리고 차트를 관리하기 위한 개체를 만듭니다.

OnInit()의 마지막 작업 - 타이머를 만들고 작동하도록 호출합니다. 다른 모든 작업은 OnTimer()에서 수행됩니다.

플레이어 생성의 첫 번째 문제는 개발 초기 단계에서 나타납니다. 타이머 생성 문제입니다. EventSetTimer(timer) 함수를 사용하면 1초 이상의 빈도로 타이머를 만들 수 있습니다. 이 변형을 사용하면 틱이 초당 한 번 생성됩니다. 인간의 시각의 한계에도 불구하고 1초는 너무 깁니다. 최소 100밀리초가 필요합니다.

그래서 타이머 내부에 루프를 구현했습니다. 새로운 Timer 이벤트가 발생하기 몇 밀리초 전에 종료됩니다. 그러나 이 구현으로 인해 많은 기술 솔루션이 불가능했습니다. 예를 들어, 이벤트 수신 가능성은 타이머가 주기에서 종료될 때까지 계속 기다리기 때문에 사라집니다. 그리고 이벤트 수신 불가능은 플레이어의 개체를 지표에 배치하고 모든 차트의 병렬 계산을 동시에 수행할 가능성을 녹여버립니다. 그러나 결과적으로 차트를 처리하더라도 Expert Advisor는 매우 빠르게 작동합니다.

차트 활성화 이벤트는 Click(n) 함수의 주기에서 처리 중인 활성 차트의 변경 신호를 생성하는 객체가 복합 클래스 CClick으로 대체됩니다. Click() 함수는 차트 활성화 버튼의 변경 사항을 추적하는 트리거입니다. 버튼이 눌린 것을 감지하면 다른 모든 개체를 수동 상태로 전환합니다. 차트 활성화 버튼은 항상 사용자 가까이에 있지만 전체 차트의 크기를 가지고 있기 때문에 배경으로 착색되어 배경에 있기 때문에 보이지 않습니다. 차트가 활성화되면 버튼이 차트의 보이는 테두리 뒤로 이동하여 수동 모드에서 차트 활성화 버튼으로 숨겨진 플레이어 컨트롤의 그래픽 개체를 볼 수 있습니다.

또한 Click() 함수를 사용하여 메인 차트를 감지했으므로 시간 움직임 계산으로 이동하여 활성 플레이어의 Progress(Time) 함수를 호출합니다. 이 함수는 다음 계산을 수행합니다. 사용자가 탐색 작업을 수행하는지 확인합니다. - 그렇지 않으면 다음 바로 이동할 시간인지 확인합니다. 시간이 되면 진행 상황을 다음 섹션으로 옮겨야 하는지 여부를 확인합니다.

결국 Progress(Time) 함수를 종료하면 주기에 추가 계산에 사용되는 현재 시간에 대한 정보가 있습니다. 그러면 활성 차트의 설정이 슬레이브 차트에 복사됩니다. CopyPlayer(n) 함수의 루프를 사용하여 수행됩니다. 그 후, Play(Time) 함수에서 차트에 이루어져야 하는 모든 변경 사항의 실행으로 이동하여 사용자가 시간이 이동하고 호가가 오고 거래가 수행된다고 생각하게 합니다.


플레이어의 합성 클래스.

  1. CArrayRuler* - 현재 시간대의 바 사이를 빠르게 이동할 수 있도록 정보를 저장하고 검색합니다.
  2. CRuler*         -  틱 생성을 위한 M1 이력 정보를 저장하고 검색합니다.
  3. CSpeed          -  틱 생성기의 속도 설정과 기간을 제어합니다.
  4. CProgress      -  모든 진행률 버튼을 단일 개체로 결합하고, 버튼 하나만 눌러지는 것을 감시하고, 버튼의 색상을 변경합니다.
  5. CPlay             -  플레이어의 시작 및 중지를 담당하며 잔액 지표를 제어합니다.
  6. CClick            -  차트 활성화 신호를 담당합니다.
  7. CBackGround  - 개체는 사용자에게 0 바를 숨기고 오른쪽 경계 상태에서 차트 이동이 활성화된 경우 미래 ​​바를 숨깁니다.
  8. CBarDraw      -  차트의 규모와 유형(바, 촛대 또는 선)에 따라 0 바를 그립니다.
  9. CHistoryDraw -  마지막 거래가 실시간으로 변경되는 것처럼 사용자에게 환상을 줍니다.

* - 클래스에 그래픽 개체가 포함되지 않습니다.

이미 언급했듯이 CChartData 및 SBase 클래스의 개체는 집계를 사용하여 플레이어 내부의 모든 개체에 대한 공통 데이터 필드를 만듭니다. CChartData 클래스의 개체는 차트에 대한 정보를 저장 및 업데이트하고 관리하는 데 사용됩니다. 차트 관리에서 기본 차트의 설정을 복사하여 설정을 변경하는 것을 의미합니다. 이것이 차트 동기화가 수행되는 방식입니다. 사용자는 활성 차트의 설정을 변경하여 초기 신호를 보내고 나머지는 플레이어의 여러 기능이 동기화 작업을 수행합니다.

이것이 수행되는 방법입니다.

Expert Advisor에 설명된 CopyPlayer(n) 함수는 활성 차트의 플레이어에 포인터를 연결하여 전달하는 루프에서 CPlayer::Copy(CPlayer *base) 함수를 호출합니다. 플레이어 포인터의 CPlayer::Copy(CPlayer *base) 내부에서 활성 플레이어의 CChartData 개체 포인터가 연관적으로 전달됩니다. 따라서 활성 차트의 상태에 대한 정보는 복사를 위해 슬레이브 차트의 CChartData 클래스의 개체에 배치됩니다. 그 후 CPlayer::Update() 함수에서 정보가 업데이트됩니다. 여기서 필요한 모든 검사가 수행되고 모든 개체가 필요한 상태로 전환됩니다.

이전에는 생성기의 사용 가능한 기간 목록에 기간을 추가하는 방법을 알려 드리기로 약속했습니다. 그렇게 하려면 "Player5_1.mqh" 포함 파일을 엽니다. 정적 배열 TFarray[]는 파일의 시작 부분에 선언됩니다. 배열을 채우는 열거형의 해당 위치에 필요한 마침표를 추가해야 하며 배열의 크기와 CountTF 변수를 변경하는 것을 잊지 마십시오. 그런 다음 Player History Trades exp v5 Expert Advisor를 컴파일합니다.


잔액 및 인출 차트

잔액 지표는 CPlay 클래스의 개체에서 관리됩니다. 여기에는 제어 방법과 버튼이 포함되어 있습니다.

지표 제어 방법은 다음과 같습니다.

   Ind_Balance_Create();                 // add the indicator
   IndicatorDelete(int ind_total);     // delete the indicator
   EventIndicators(bool &prev_state);   // send an event to the indicator
   StateIndicators();                  // state of the indicator, state checks

name_on_balance 버튼의 상태에 따라 추가/삭제 방법이 다릅니다. 표준 MQL5 함수 IndicatorCreate() 및 ChartIndicatorDelete()를 사용합니다.

지표는 이벤트를 수신하고 이벤트 코드에 따라 지표의 OnChartEvent() 함수에 있는 계산을 수행합니다. 이벤트는 세 가지 유형으로 나뉩니다. 

"지표 업데이트", "총 잔액 계산" 및 "심볼에 대한 잔액 계산"이 있습니다. 따라서 이벤트를 보낼 때 name_all_balance 버튼의 상태에 따라 사용자가 계산 유형을 제어합니다. 그러나 지표 코드 자체에는 거래 내역의 구문 분석, 위치 계산 또는 이익 재계산이 포함되어 있지 않습니다. 지표는 필요하지 않습니다.

잔액 지표는 이력 데이터를 표시하기 위한 것이므로 유형을 변경하거나 지표를 추가/제거할 때마다 모든 것을 다시 실행할 필요가 없습니다. 표시기는 M1 기간에 대해 계산된 데이터의 바이너리 파일을 읽고 차트의 현재 기간에 따라 데이터를 나눕니다.

이 바이너리 파일은 OnInit()에서 호출되는 Balance_Process() 함수에 의해 준비됩니다. 사용자가 거래에 사용되지 않은 기호를 추가하고 해당 바이너리 파일이 없는 경우 지표는 두 변형의 총 잔액 내역을 표시합니다.

이제 지표에 전달된 데이터 형식에 대해 이야기해 보겠습니다. 정보를 올바르게 나누기 위해서는 바의 4가지 포인트(시가, 고가, 저가, 종가)를 아는 것만으로는 충분하지 않습니다.

그 외에도 첫 번째가 무엇인지 알아야 합니다 - 높거나 낮음. 정보 복원을 위해 Balance_Process() 함수는 전략 테스터의 "1분 OHLC" 모드와 동일한 원리를 사용합니다. 바의 종가가 시가보다 낮으면 두 번째 포인트가 최대값이고, 그렇지 않은 경우 그것은 최소입니다.

세 번째 점에 대해 동일한 계획이 사용됩니다. 결과적으로 우리는 모든 것이 일관되고 명확한 데이터 형식(오픈, 2차 포인트, 3차 포인트, 닫기)을 얻습니다. 이 형식은 따옴표의 M1 기록을 나누는 데 사용됩니다. 그리고 그 결과는 파싱된 거래 내역(동일한 형식)에 따라 균형 및 자본 내역 계산에 사용됩니다.


결론

결론적으로 이 개발은 비록 우리가 이런 식으로 사용할 수 있다 하더라도 테스터 비주얼라이저인 척 하지 않는다는 것을 말씀드리고 싶습니다. 그러나 거기에 구현된 아이디어가 실제 시각화 도구에서 유용하게 보인다면 전 기쁘게 생각할 것입니다. 플레이어의 개발은 트레이더와 EA 작가가 다가오는 챔피언십을 준비하고 트레이드 전략을 분석하는 힘든 작업을 돕는 것을 목표로 합니다.

또한 MQL5 언어는 상당히 거대한 프로젝트를 구현할 수 있는 강력한 프로그래밍 도구라고 말하고 싶습니다. 이 글을 계속 읽고 있다면 "플레이어" 프로젝트가 거의 8000줄의 코드로 구성되어 있다는 것을 눈치채셨을 것입니다. 나는 MQL4에서 그러한 코드를 작성하는 것을 상상할 수 없으며 문제는 절차로 모든 것을 설명하는 것이 아닙니다. 준비된 개발이 있으면 절차 스타일로 다시 만들 수 있습니다. 그러나 그러한 프로젝트를 처음부터 개발하는 것은 정말 어렵습니다.

행운을 빕니다!


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

HTML의 차트 및 다이어그램 HTML의 차트 및 다이어그램
오늘날에는 웹 브라우저가 설치되어 있지 않은 컴퓨터를 찾기가 어렵습니다. 오랫동안 브라우저는 진화하고 개선되어 왔습니다. 이 문서에서는 브라우저에 표시하기 위해 MetaTrader 5 클라이언트 터미널에서 얻은 정보를 기반으로 차트와 다이어그램을 만드는 간단하고 안전한 방법에 대해 설명합니다.
움직이는 Mini-Max: MQL5의 기술적 분석 및 구현을 위한 새로운 지표 움직이는 Mini-Max: MQL5의 기술적 분석 및 구현을 위한 새로운 지표
다음 글에서는 Z.G.Silagadze의 논문 'Moving Mini-max: 기술 분석을 위한 새로운 지표'를 기반으로 Moving Mini-Max 지표를 구현하는 과정을 설명합니다. 지표의 아이디어는 알파 붕괴 이론에서 G. Gamov가 제안한 양자 터널링 현상의 시뮬레이션을 기반으로 합니다.
지그재그 및 ATR의 예에 의한 지표의 클래스 구현 지그재그 및 ATR의 예에 의한 지표의 클래스 구현
지표를 계산하는 최적의 방법에 대한 논쟁은 끝이 없습니다. 지표 자체에서 지표 값을 계산하거나 이를 사용하는 Expert Advisor에 전체 논리를 포함시켜야 하는 곳은 어디입니까? 이 글에서는 계산을 최적화하고 prev_calculated 값을 모델링하여 Expert Advisor 또는 스크립트의 코드에서 사용자 지정 지표 iCustom의 소스 코드를 바로 이동하는 변형 중 하나를 설명합니다.
NeuroSolutions Neuronet 연결 NeuroSolutions Neuronet 연결
Neuronet 생성 외에도 NeuroSolutions 소프트웨어 제품군을 사용하면 이를 DLL로 내보낼 수 있습니다. 이 글은 뉴로넷 (Neuronet) 생성, DLL 생성 및 MetaTrader 5 거래를 위해 Expert Advisor에 연결하는 과정을 설명합니다.