MQL5 언어를 처음부터 자가 학습 - 페이지 52

 

위치 루프에서 기호와 마술로 필터에 주의하십시오. 필터가 없지만 모든 기호의 모든 열린 위치 를 추적하는 경우 이는 좋지 않습니다.

글쎄, 언뜻보기에 모든 것이 순서대로 보입니다.

Совершение сделок - Торговые операции - Справка по MetaTrader 5
Совершение сделок - Торговые операции - Справка по MetaTrader 5
  • www.metatrader5.com
Торговая деятельность в платформе связана с формированием и отсылкой рыночных и отложенных ордеров для исполнения брокером, а также с управлением текущими позициями путем их модификации или закрытия. Платформа позволяет удобно просматривать торговую историю на счете, настраивать оповещения о событиях на рынке и многое другое. Открытие позиций...
 
Andrei Novichkov :

위치 루프에서 기호와 마술로 필터에 주의하십시오. 필터가 없지만 모든 기호의 모든 열린 위치 를 추적하는 경우 이는 좋지 않습니다.

글쎄, 언뜻보기에는 모든 것이 정상인 것처럼 보입니다.

정말 감사합니다, 안드레이! 하나의 기호에서 실제로 여러 위치를 한 번에 열 수 있기 때문에 Magic에 대한 모든 것이 명확하지만 반론이 제기되었습니다. 현재 기호를 명시적으로 가리키지 않는 경우 EA가 모든 기호에 대해 열린 위치를 한 번에 처리합니까? 그리고 이것은 EURUSD와 같은 특정 통화 쌍으로 설정되어 있음에도 불구하고 그렇습니다. 솔직히 지금 이 순간이 잘 이해가 되지 않는다.

안부 인사를 전합니다. 블라디미르.

 
MrBrooklin :

정말 감사합니다, 안드레이! 하나의 기호에서 실제로 여러 위치를 한 번에 열 수 있기 때문에 Magic에 대한 모든 것이 명확하지만 반론이 제기되었습니다. 현재 기호를 명시적으로 가리키지 않는 경우 EA가 모든 기호에 대해 열린 위치를 한 번에 처리합니까? 그리고 이것은 EURUSD와 같은 특정 통화 쌍으로 설정되어 있음에도 불구하고 그렇습니다. 솔직히 지금 이 순간이 잘 이해가 되지 않는다.

안부 인사를 전합니다. 블라디미르.


네. 모든 기호에 대한 모든 열린 포즈에 대해...
지속적으로 포지션을 엽니다.
여기에 이미 교과서에 있는 간단한 트롤이 있습니다.

https://book.mql4.com/ru/build/trading
 
MrBrooklin :

그래서 내가 읽은 문헌을 기반으로 후행 정지 기능이 있는 Expert Advisor를 만들기 위한 작은 알고리즘을 작성했습니다.

  1. Stop 수준 의 추적(유지 관리) 작업을 자동화하기 위해 Expert Advisor를 만듭니다. 상실 이익 실현 및 정지 수준 이 지정된 이미 열린 포지션 손실 .
  2. EA에서 "trailing level"을 설정하고 "trailing step"을 설정하는 두 개의 매개변수를 사용하여 입력 매개변수 블록을 만듭니다.
  3. 새로운 따옴표가 도착하면 OnTick() 함수로 처리합니다. 후행은 현재 기호에 대해 새 틱이 도착할 때만 작동합니다.
  4. 모든 위치의 열거 주기를 만들고 시작합시다.
  5. 갑자기 열린 위치를 찾지 못하면 주기로 돌아갑니다.
  6. 견적을 업데이트합니다.
  7. 열린 위치가 있으면 계속하십시오.
  8. 오픈 포지션 유형 결정: 매수 또는 판매.
  9. 매수 포지션이 open 이면 현재 가격이 open 포지션에 상대적인 위치를 결정합니다.
  10. 현재 가격이 포지션 개시 가격보다 높으면 어느 정도 상승했는지 확인합니다.
  11. 현재 가격이 입력 매개변수에 지정된 "후행 수준"에 도달한 경우 중지 를 이동합니다. 상실 매수 포지션 의 시가와 동일한 손실 없는 수준까지 . 그렇지 않으면 우리는 아무 것도 하지 않습니다.
  12. 현재 가격이 "후행 단계"와 동일한 양만큼 "후행 수준"을 초과한 경우 중지 매수 포지션 의 시가 수준에서 손실 이 이동합니다. 가격이 이 포지션에 대해 설정된 이익 실현 수준에 도달할 때까지 "후행 단계"와 같은 값으로 계속 진행됩니다.
  13. 가격이 반전되어 이미 이동한 Stop 수준에 도달하면 Loss , 포지션이 닫힙니다.
  14. 매도 포지션이 open 이면 현재 가격이 open 포지션에 상대적인 위치를 결정합니다.
  15. 현재 가격이 포지션 개시 가격보다 낮으면 어느 수준까지 하락했는지 확인합니다.
  16. 현재 가격이 입력 매개변수에 지정된 "후행 수준"에 도달한 경우 중지 를 이동합니다. 상실 매도 포지션 의 시가와 동일한 손실 없는 수준까지 . 그렇지 않으면 우리는 아무 것도 하지 않습니다.
  17. 현재 가격이 "후행 단계"와 동일한 양만큼 "후행 수준"을 초과한 경우 중지 손실매도 포지션의 시가 수준에서 이동합니다. 가격 이 이 포지션에 대해 설정된 이익 실현 수준에 도달할 때까지 "후행 단계"와 동일한 값으로 계속 진행됩니다.
  18. 가격이 반전되어 이미 이동한 Stop 수준에 도달하면 Loss , 포지션이 닫힙니다.

알고리즘을 보고 어떤 순간을 놓쳤는지 알려주세요.

안부 인사를 전합니다. 블라디미르.

좋은 이론, 이제 실습. 당신은 그것을 할 수 있습니다?

 
Aliaksandr Hryshyn :

좋은 이론, 이제 실습. 당신은 그것을 할 수 있습니다?

노력하겠습니다. 그러나 당신은 이것이 내가 아직 가지고 있지 않은 완전히 다른 수준의 지식이 필요하다는 것을 이해합니다.

안부 인사를 전합니다. 블라디미르.

 
Aleksey Masterov :

네. 모든 기호에 대한 모든 열린 포즈에 대해...
지속적으로 포지션을 엽니다.
여기에 이미 교과서에 있는 간단한 트롤이 있습니다.

https://book.mql4.com/ru/build/trading

예, Alexey, 저는 이미 이 코드를 보았습니다. 인클루드 파일로 만들어집니다. 솔직히 말해서, 나는 그 상징에 대해 아무 것도 찾지 못했다. 나는 그것을 여러 번 보았지만. 내가 뭔가를 놓치고 있는 것일 수도 있고, 아니면 내가 나쁘게 보고 있는 것일 수도 있습니다.

안부 인사를 전합니다. 블라디미르.

 

지금은 기능에 대해 계속하겠습니다.

앞서 썼듯이 기능은 어디에나 있고 사랑받아야 하고 쓸 수 있어야 합니다. 기능은 글로벌 문제를 해결하는 우리의 작은 전사입니다. 우리가 군대의 장군이라면 어떤 전사를 조종하고 싶습니까? 다음은 예시 목록입니다.

  • 전투기는 명령을 분명히 따라야 합니다. 보병의 평균 지적 발달 수준은 크지 않습니다. 따라서 "벙커 가져 오기", "언어 얻기", "다리 채굴"과 같은 전투기에 대해 명확하고 간단한 목표를 설정하는 것이 좋습니다.
  • 작업이 어렵다면 그것을 구현하기 위해 슈퍼 똑똑한 전투기를 찾을 필요가 없습니다. 작업을 여러 하위 작업으로 나누고 더 멍청하지만 더 효율적인 두세 명의 전투기를 사용하는 것이 좋습니다. 모든 사람이 질문 없이 하위 문제를 풀도록 하거나 더 나은 방법으로 각자가 아이디어와 문제를 전체적으로 알지 못하게 하십시오. 그런 다음 누군가가 잡히면 무섭지 않습니다. 전체 계획은 공개되지 않습니다.
  • 전투기는 눈, 비, 파리 및 여성과 같은 주변 조건에 관계없이 명령을 수행해야 합니다. 이러한 환경이 명령 실행에 영향을 미치지 않으면 이러한 조건과 외부 환경을 무시해야 합니다.
  • 때로는 작업이 어렵습니다. 그들을 해결하려면 많은 전투기가 필요합니다. 각 전투기에 장군을 둘 수는 없습니다. 대신, 당신은 더 똑똑한 파이터를 골라 그를 여러 파이터를 책임지게 해야 합니다. 이 그룹은 차례로 군인 회사에서 동일한 그룹과 결합하여 더 높은 지도자를 할당합니다.

그러나 우리는 탈선하고 다시 기능으로 넘어 갑시다.

일반적으로 기능이 너무 많은 작업을 해결하는 경우 유추에 따라 문제가 발생하면 전체 기업을 파괴할 수 있는 매우 똑똑한 전사입니다. 그러한 기능이 무엇인지 묻는다면 대답이 길 수 있습니다. 이 함수의 결과가 갑자기 정확하지 않으면 그 안에 오류의 원인을 파악하기가 매우 어려울 것입니다(많은 작업, 많은 코드, 많은 하위 프로시저 호출 및 오류가 어디에 있는지 정확히 이해하기 어렵습니다.)

함수가 월요일, 수요일, 일요일에 정확한 결과를 계산하고 "기분"에 따라 다른 날에 계산한다면 - 우리는 그러한 함수에 의존할 수 있습니까? OrderSend 시스템 기능이 목요일에만 포지션을 오픈하고 값이 13인 특정 매직 매개변수가 정의된 경우 위의 내용이 전혀 넌센스나 환상이 아니라고 가정해 보겠습니다. 이러한 동작은 손가락 클릭으로 정렬할 수 있으며 외부 환경의 특정 매개변수에 따라 기능을 만드는 것으로 충분합니다.

다음과 같은 기능을 가정해 보겠습니다.

 double sum( double a, double b)
{
   return a+b;
}

외부 환경에 관계없이 항상 두 값의 합계를 반환합니다. 즉, 이 기능을 다른 스크립트나 Expert Advisor에 복사하여 붙여넣어도 잘 작동합니다. 이러한 함수는 한 번 작성되고 단순히 어리석게 복사하여 많은 프로그램에서 사용할 수 있습니다. 우리는 그녀의 작업이 아무것도 의존하지 않는다는 것을 알기 때문에 항상 그녀의 결과에 의존할 수 있습니다. 결과가 환경에 의존하지 않는 이러한 함수 를 부작용이 없는 함수 또는 순수 함수 라고 합니다. 순수한 함수를 작성하려고 노력한다면 머지 않아 많은 함수가 생성될 것입니다. 이는 파일로 결합되어 새 프로젝트에 포함될 수 있음을 의미합니다. 이것을 코드 재사용 이라고 합니다 . 우리는 일을 두 번 하지 않습니다. 그 대신, 우리는 이미 두 번 이상 테스트를 거쳐 신뢰성을 알고 있는 이미 작성된 기능을 사용합니다.

이제 반대 예를 살펴보겠습니다.

 double c = 0.0 ;
double sum( double a, double b)
{
   return a+b+c;
}

c 는 항상 0과 같기 때문에 결과는 동일한 것으로 보입니다. 아니면 항상 그렇지는 않습니까? 그러나 누군가 어딘가에서 c 를 변경하면 어떻게 될까요? 그럼? 그리고 누군가 어딘가에서 외부 변수 c를 사용하지만 자신의 목적을 위해 다른 유형의 변수 c가 있는 경우 문자열이라고 가정해 보겠습니다. 더 이상 이 두 함수를 모두 결합할 수 없습니다(컴파일러는 동일한 이름의 두 변수를 선언할 수 없습니다). 공통 종속성을 처리하는 것도 어렵습니다. 그것으로 무엇을 해야할지 전혀 명확하지 않습니다. 예를 들어, 나는 여전히 그러한 기능을 함께 작동시키는 안정적이고 간단한 방법을 모릅니다.

다른 기능이 없고 하나의 기능만 외부 변수를 읽어온다 해도 다른 곳에 복사하기가 쉽지 않다. 이 함수 와 종속성 을 모두 복사해야 합니다. 이러한 기능을 공유 파일에 복사하면 어떻게 될까요? 여기에 이러한 기능이 50, 100개 입력됩니다. 그리고 각각은 그 자체와 함께 많은 종속 변수를 복사합니다. 관련 변수가 얽힌 것으로 밝혀졌으며 어떤 기능이 있는지 명확하지 않습니다. 그리고 왜 이 모든 것입니까? 어떤 문제를 해결합니까? 대부분의 경우에 불필요한 종속성을 만들 수 있는데 왜 불필요한 종속성을 생성합니까?

함수에는 또 다른 놀라운 속성이 있습니다. 기능은 자체 설명입니다. 저것들. 다이어그램을 그릴 필요 없이 좋은 이름을 선택하고 일반 알고리즘을 기능으로 나누기만 하면 됩니다. 예를 들어 보겠습니다.

 void OnTick ()
{
   if (SelectFirstPendingOrder( ORDER_TYPE_BUY ))
       CancelSelectPendingOrder();
}

함수가 작성되지 않았기 때문에 이 코드가 무엇을 하는지 모르겠습니다. 하지만 읽어보면 ORDER_TYPE_BUY 방향으로 첫 번째 <gotcha> 보류 주문이 성공적으로 선택되면 취소된다는 의미일 가능성이 큽니다(첫 번째 기능이 선택되고 두 번째 기능이 취소됨). 코드는 보류 중인 주문의 수에 관계없이 매 틱마다 실행되기 때문에 조만간 각 주문이 취소될 것입니다. 또한 보류 중인 구매 주문 시도가 중지되고 주문이 즉시 제거됩니다. 이 경우 매도 주문은 문제 없이 이루어집니다.

두 줄의 코드와 두 개의 기능만 있으면 됩니다. 그리고 알고리즘은 사소하지 않고 가장 중요하게는 신뢰할 수 있는 것으로 판명되었습니다.

MCL에 적용할 때 순수 함수에 대해 조금 더 말해야 합니다. 응용 언어이기 때문에 단말에서 제공하는 데이터에 의존하지 않고는 아무 것도 작성하기 어렵습니다. 결국 이것은 거래 환경과 적절하게 상호 작용하는 주요 작업입니다. 공식적으로 모든 거래 환경은 변동성이 있습니다. 가격 변동, 주문 수, 잔액 등입니다. 따라서 이러한 변동성 거래 환경과 상호 작용하는 기능은 순수하지 않습니다. 외부 거래 환경도 끊임없이 변화하는 일종의 글로벌 변수로 간주될 수 있기 때문입니다. 그러나 OrdersTotal()을 작성할 때 이 함수가 항상 동일한 값을 반환할 것으로 기대하지는 않습니다. 대신에 자연히 달라지는 보류 중인 주문 수를 반환할 것으로 예상합니다. 따라서 MQL과 관련하여 우리는 함수가 OrdersTotal()과 같은 외부 API 함수를 호출하더라도 깨끗하고 재사용 가능한 함수를 고려할 것입니다. 이것은 우리의 합리적인 방종입니다.

 
Vasiliy Sokolov :

우리가 기능에 대해 계속하는 동안 ...

Vasily, 저뿐만 아니라 이 주제를 읽거나 읽게 될 초보 프로그래머 들과도 귀중한 지식을 공유해 주셔서 감사합니다!

같은 존경을 표합니다, 블라디미르.

 

계속해서 MQL5 프로그래밍 언어를 공부하고 있습니다. 지금까지 Trailing_Stop 어드바이저의 코드를 작성하기 위한 알고리즘에 대한 주제 참가자의 진지한 의견은 없었습니다(기호와 Magic에 대해 기억합니다. 나중에 알고리즘에 추가하겠습니다!), 입력을 만들었습니다. 어드바이저의 매개변수를 수정하고 열린 위치에서 반복을 시작하는 루프에 대한 코드를 작성했습니다.

고문을 시작할 때 문제가 발견되었습니다. 거래 터미널의 "전문가" 탭에서 각 틱마다 거래 터미널에 차트 가 하나만 있음에도 불구하고 "사이클 시작됨"이라는 동일한 메시지 2 개가 한 번에 표시됩니다. EURUSD 통화 쌍 및 하나의 위치만 열려 있습니다. 또한 이러한 메시지의 출력 시간은 정확히 동일합니다.

그는 자정까지 싸웠지만 이길 수 없었습니다. 문제가 무엇인지 알 수 없습니다.


EA 코드는 영어로 작성되었으며 코드에 대한 주석은 자료의 동화를 용이하게 하기 위해 러시아어로 작성되었습니다. 이 Expert Advisor에서는 앞서 약속한 대로 프로그래밍 학교 1학년 학생이 볼 수 있는 프레젠테이션에서 모든 것을 설명하려고 했습니다.

안부 인사를 전합니다. 블라디미르.

 //+------------------------------------------------------------------+
//|                                                Trailing_Stop.mq5 |
//|                        Copyright 2020, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2020, MetaQuotes Software Corp."
#property link        "https://www.mql5.com"
#property version    "1.00"

input ushort TrailingLevel= 100 ; //Уровень трейлинга (для включения)
input ushort TrailingStep= 10 ;   //Шаг трейлинга (для перемещения)
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit ()
  {
//---

   return ( INIT_SUCCEEDED );
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit ( const int reason)
  {
//---

  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick ()
  {
//---
   /* Для цикла for создаем локальную переменную i и присваиваем ей значение "торговая функция PositionsTotal",
      которая возвращает нам количество открытых позиций*/
   int i= PositionsTotal ();
   /* Разберемся, что такое оператор for.
      Оператор for состоит из трех Выражений и выполняемого Оператора:
      for(Выражение_1; Выражение_2; Выражение_3)
         Оператор;
      Выражение_1 описывает инициализацию цикла. За инициализацию цикла будет отвечать "Торговая функция PositionsTotal".
      Выражение_2 проверяет условия завершения цикла. Если оно истинно, то выполняется Оператор в теле цикла for.
      Все повторяется до тех пор, пока Выражение_2 не станет ложным. Если оно ложно, цикл заканчивается
      и управление передается следующему оператору.
      Выражение_З вычисляется после каждой итерации (т.е. после каждого повторения действия).
   */
   for (i; i>= 0 ; i--) //запускаем цикл перебора открытых позиций (i) от максимума до нуля (i>=0) с шагом минус 1 (i--)
       Print ( "Запущен цикл" );
  }
//+------------------------------------------------------------------+
//| Timer function                                                   |
//+------------------------------------------------------------------+
void OnTimer ()
  {
//---

  }
//+------------------------------------------------------------------+
 
MrBrooklin :


i는 열린 위치 의 수와 같으므로 많은 주기가 인쇄됩니다.

 Print ( "Запущен цикл" );
"=" 로그인을 제거해야 합니다.
   for (i; i>= 0 ; i--)
열린 위치의 수가 0일 때 주기를 거쳐야 하는 이유는 무엇입니까? 이 제로 호출은 두 번째 인쇄였습니다.