적은 코드, 더 많이 사용합니다. Expert Advisor 작성

 

나는 조언자들을 위한 기반을 만들기 위해 노력할 것입니다. 간단한 일에 가장 적합하며 응용 프로그래머의 상당한 지식이 필요하지 않습니다.

현지에서 허용되는 관행과 달리 디자인은 하향식입니다. 터미널의 엔지니어링 기반이 아닌 사용자가 원하는 사용 사례에서. 즉, 먼저 최종 사용자를 위한 기본(유일한) 어드바이저 파일을 작성하고 거기에서 분명히 불필요한 모든 것을 제거한 다음 IT가 작동하도록 라이브러리를 작성합니다. 그런 다음 새 사용 사례를 추가하고 라이브러리를 업그레이드합니다.

https://www.mql5.com/ru/articles/5654 및 Karputov 씨의 고문과의 반대 논제 및 논쟁

물론 진행하기 전에 "당 노선"과 "목표 공산주의"를 설정해야 합니다.

- 사용자가 전략을 구현하기에 100줄이면 충분합니다. (주석, 입력 및 기타 #속성 외에).

- 동시에 새로운 "엔티티"(함수/클래스/메소드/상수)의 수는 최소로 줄여야 합니다.

- 라이브러리는 셀 수 있는 파일 수를 포함해야 합니다.

- GUI에 잠재적으로 적합

- 플러그인으로 확장 가능

목표를 달성할 수 있습니까? 어렵지만 기본적으로 예. 어떤 면에서는 발전과 아이디어가 있습니다. 그러나 아직 준비된 솔루션이 없습니다 :-)

현재 단계는 전문가의 데이터 수신을 구성하는 것입니다. 사용자가 설명하기 쉽도록 메타데이터 및 추가 확장에 대한 "후크"가 유지됩니다. (앞으로 내다보기 - 추가 코드에 따르면 GUI의 일부를 이미 구현하고 적어도 디버깅 중 하나)


개시자로서 저는 가장 간단한 사용 사례를 스케치했습니다. 우리는 두 MA의 교차점을 거래합니다.

각각의 입력 부분은 다음과 같습니다.

 /** ------- ПАРАМЕТРЫ СОВЕТНИКА ------
**/
input ENUM_APPLIED_PRICE FAST_MA_PRICE= PRICE_CLOSE ;
input ENUM_MA_METHOD FAST_MA_METHOD= MODE_EMA ;
input int FAST_MA_PERIOD= 14 ;
input int FAST_MA_SHIFT= 0 ;

input ENUM_APPLIED_PRICE SLOW_MA_PRICE= PRICE_CLOSE ;
input ENUM_MA_METHOD SLOW_MA_METHOD= MODE_SMA ;
input int SLOW_MA_PERIOD= 54 ;
input int SLOW_MA_SHIFT= 0 ;

계획한 대로 사용자가 다음으로 해야 할 일은 입력에서 수신하는 데이터를 설명하는 것입니다. 그래도 나열하려면:

 // просто перечисляем идентификаторы данных
// всех которые нужны для принятия решений
enum ENUM_SERIES {
   FAST_MA,       // id. значений FAST_MA
   SLOW_MA,       // id. значений SLOW_MA
   TOTAL_SERIES   // последний элемент перечисления = кол-во элементов
};

그리고 그가 이 데이터를 어떻게 계산/수신하는지 설명하십시오(긴 것으로 판명되었지만 즉시 두 터미널 모두에)

 /// вычисление данных
/// эксперт будет обращаться к функции каждый раз когда ему необходимы данные
/// управление кешированием и очерёдность(взаимозависимость) вычислений лежит на верхнем уровне
/// @arg ea - эксперт
/// @arg id - ид.серии данных
/// @arg shift - сдвиг в серии
/// @arg data[] - кешированные результаты
/// @return double - конкретное значение для [id][shift] или EMPTY_VALUE если не может быть вычилено
/// если данные могут быть кешированы, они должны быть сохраненны в массиве data
double GetData(EA *ea, int id, int shift, double &data[])
{
#ifdef __MQL4__
   // для 4-ки всё просто - по идентификаторам серии и бара получить данные
   switch ((ENUM_SERIES)id) {
       case FAST_MA:
         return data[shift]= iMA (ea. Symbol ,ea. Period ,FAST_MA_PERIOD, 0 ,FAST_MA_METHOD,FAST_MA_PRICE,shift);
       case SLOW_MA:
         return data[shift]= iMA (ea. Symbol ,ea. Period ,SLOW_MA_PERIOD, 0 ,SLOW_MA_METHOD,SLOW_MA_PRICE,shift);
   }
   return EMPTY_VALUE ;
#else
   // для 5-ки несколко сложнее (и кстати не проверено) - надо ещё заводить хендлы стандартных индикаторов
   // и проводить (возможно)лишнее копирование
   static d_fast_ma= 0 ;
   static d_slow_ma= 0 ;
   if (d_fast_ma== 0 ) d_fast_ma= iMA (ea. Symbol ,ea. Period ,FAST_MA_PERIOD, 0 ,FAST_MA_METHOD,FAST_MA_PRICE,shift);
   if (d_slow_ma== 0 ) d_slow_ma= iMA (ea. Symbol ,ea. Period ,SLOW_MA_PERIOD, 0 ,SLOW_MA_METHOD,SLOW_MA_PRICE,shift);  
   double tmp[ 1 ];
   switch ((ENUM_SERIES)id) {
       case FAST_MA: CopyBuffer (d_fast_ma, 0 ,shift, 1 ,tmp); return data[shift]=tmp[ 0 ];
       case SLOW_MA: CopyBuffer (d_slow_ma, 0 ,shift, 1 ,tmp); return data[shift]=tmp[ 0 ];
   }
   return EMPTY_VALUE ;
#endif
}

마지막으로 거래 신호를 설명합니다.

 /// генерация(вычисление) сигнала при открытии бара
/// @arg ea - эксперт
/// @arg shift - номер бара в таймсерии. Типично будет 0
/// @return int - сигнал OP_BUY или OP_SELL или -1 если сигнала нет 
int SignalOfCross(EA *ea, int shift)
{
   if (FAST_MA_PRICE!= PRICE_OPEN || SLOW_MA_PRICE!= PRICE_OPEN ) shift++;
   if (ea.CrossedUp(FAST_MA,SLOW_MA,shift)) {
       return OP_BUY ;
   }
   if (ea.CrossedDn(FAST_MA,SLOW_MA,shift)) {
       return OP_SELL ;
   }
   return - 1 ;
}

원칙적으로. 이것은 Expert Advisor를 구현하기에 충분하며 사용자가 수많은 문서를 읽을 필요가 없습니다. 그는 기본 수준의 MQL 능력이 필요합니다. 그리고 다른 모든 것은 라이브러리에서 수행해야 합니다(또는 유행하는 단어는 엔진입니다). 사용자가 다른 다중 볼륨 API를 배우기 위한 것이 아니라 사용자를 위해 빌드해야 합니다.

그건 그렇고 OnInit는 다음과 같습니다.

 int OnInit ()
{
   ea = new EA();
   // настраиваем таймфрейм "по умолчанию"
   //   символ и период - текущие
   //   TOTAL_SERIES наборов данных и кешируем по 30 в каждом
   //   для получения данных служит GetData
   ea.SetupTimeframe( _Symbol , _Period ,TOTAL_SERIES, 30 ,GetData);
   // настраиваем сигнал "по умолчанию"
   ea.SetupSignal(SignalOfCross);
   // ------ настройки завершены ------
   // остальная часть одинакова для всех советников
   int ret;
   if ((ret=ea. OnInit())!=INIT_SUCCEEDED ) {
       return ret;
   }
   EventSetTimer ( 60 );

   return ( INIT_SUCCEEDED );
}
  

..

Библиотека для простого и быстрого создания программ для MetaTrader (Часть I). Концепция, организация данных, первые результаты
Библиотека для простого и быстрого создания программ для MetaTrader (Часть I). Концепция, организация данных, первые результаты
  • www.mql5.com
Разбирая огромное количество торговых стратегий, множество заказов на изготовление программ для терминалов MT5 и MT4, просматривая огромное разнообразие различных сайтов по тематике скриптов, индикаторов и роботов для MetaTrader, я пришёл к выводу, что всё это многообразие в подавляющем своём большинстве строится на фактически одних и тех же...
 
모든 코드를 올바르게 삽입하십시오. 이 회색의 낙담을 보는 것은 불가능합니다. 명확한 실행 계획이 있습니다. 편집기에서 버튼을 클릭 하고 코드를 결과 필드에 붙여넣습니다 . 고집스럽게 텍스트 캔버스를 삽입한 다음 이 캔버스에 "코드" 스타일을 적용하려고 합니다.
 
Vladimir Karputov :
모든 코드를 올바르게 삽입하십시오. 이 회색의 낙담을 보는 것은 불가능합니다. 명확한 실행 계획이 있습니다. 편집기에서 버튼을 클릭 하고 코드를 결과 필드에 붙여넣습니다 . 고집스럽게 텍스트 캔버스를 삽입한 다음 이 캔버스에 "코드" 스타일을 적용하려고 합니다.

거기에 코드(코드)가 삐뚤게 삽입되어 있습니다. 한 조각은 여전히 어떻게 든 싸울 수 있고 조금 더는 이미 밀가루 ..

즉, "회색 낙담"에 대해 이것은 나를 위한 것이 아닙니다. 이것은 웹마스터를 위한 것입니다. 2019년에 어떻게 많은 자금으로 이것을 달성했는지는 미스테리입니다 :-)

하지만 앞으로 좀 더 재미있게 하기 위해 우선 위키에 좀 더 큰 글을 작성하고 복사-붙여넣기로 여기로 옮기고 퍼블리싱 코드의 양을 줄이겠습니다.

 
Maxim Kuznetsov :

거기에 코드(코드)가 삐뚤게 삽입되어 있습니다. 한 조각은 여전히 어떻게 든 싸울 수 있고 조금 더는 이미 밀가루 ..

즉, "회색 낙담"에 대해 이것은 나를 위한 것이 아닙니다. 이것은 웹마스터를 위한 것입니다. 2019년에 어떻게 많은 자금으로 이것을 달성했는지는 미스테리입니다 :-)

하지만 앞으로 더 재미있게 하기 위해 우선 위키에 다소 큰 글을 작성하고 복사-붙여넣기로 여기에 옮기고 퍼블리싱 코드의 양을 줄이겠습니다.

분명히 이제 코드와 함께 블록을 복사하여 메모장에 붙여넣어야 합니다.

그런 다음 메모장에서 복사하여 다시 붙여넣지만 그 전에 "새" 코드에 대한 새 블록을 만듭니다.

 

어드바이저를 위한 기본 템플릿을 만들고 별도로 전략 파일을 만들었습니다.

사용자가 쉽게 생각합니까?

최소한의 프로그래밍 지식은 여전히 필요합니다!

그리고 "도움말" 지침, 비디오, 아무것도 저장하지 않습니다.

그런 다음 사용자는 무료 전략을 위해 페달을 밟아야 합니다.

그리고 그들은 인증서를 읽지 않을 것입니다.

 
Vitaly Muzichenko :

분명히 이제 코드와 함께 블록을 복사하여 메모장에 붙여넣어야 합니다.

그런 다음 메모장에서 복사하여 다시 붙여넣지만 그 전에 "새" 코드에 대한 새 블록을 만듭니다.

조금 괴로웠지만 "꽃이 피었다" :-)

언급된 웹마스터를 위한 정원의 조약돌(더 정확하게는 조약돌): 내장 편집기에 복사하여 붙여넣을 때 또는 오히려 분명히 첫 번째 "색칠"에서 편집기가 임의로 코드의 일부를 물어뜯습니다. 그는 좋아하지 않는다. 특히 "if ( (ret=ea.OnInit())!=INIT_SECEEDED) {..}" 를 임의로 수정했습니다. 분명히 놀라운 하이라이트 알고리즘은 OnInit가 하나만 있고 클래스에서 오버로드될 수 없다고 간주합니다.

 
이 의사 코드 또는 이미 사용 중입니까? GetData 함수에서 표시기( d_fast_ma, d_slow_ma )의 "핸들"에 대해 "정적"을 사용할 수 없습니다. 사용자가 필터링을 위해 몇 가지 더 "마스크"를 사용하거나 다른 매개변수(예: 다른 기호에서 다른 매개변수)를 사용하기 때문입니다. ). 일부 개체에서 "핸들"을 캐시하거나 (효율성을 고려하지 않는 경우) 매번 새로 "핸들"을 가져와야 합니다. 터미널 자체에서 동일한 매개변수를 사용하여 캐시해야 합니다.
 
Maxim Kuznetsov :

물론 진행하기 전에 "당 노선"과 "목표 공산주의"를 설정해야 합니다.

1) 사용자가 전략을 구현하기에 100줄이면 충분합니다. (주석, 입력 및 기타 #속성 외에).

2) 동시에 새로운 "엔티티"의 수(함수/클래스/메소드/상수)는 최소로 줄여야 합니다.

3) 라이브러리는 셀 수 있는 파일 수를 포함해야 합니다.

4) GUI에 잠재적으로 적합

5) 플러그인으로 확장 가능


3) 라이브러리에 포함된 파일 수의 차이는 무엇입니까? 1, 10, 100, 1000? 이 라이브러리를 개발하는 사람의 편의를 위해 모든 것이 이루어져야 합니다. 그가 모든 것을 작은 파일에 두는 것이 편리하다면 - 제발. 모든 것을 하나로 코딩하는 데 익숙하다면 - 제발. 대체로 다양한 자동 수단에서 메가파일을 모으는 것은 어렵지 않습니다. 그래서 이 점 때문에 나는 버티지 않을 것입니다.

4) GUI에 적합 - 그것이 어떤 것인지 완전히 명확하지 않습니다. 라이브러리는 성인 방식으로 비즈니스 로직의 격리된 계층입니다. 이 계층은 외부 GUI에 전혀 의존하지 않아야 합니다. 이 GUI는 이 계층에 의존해야 합니다.

 
Maxim Kuznetsov :
 if (d_fast_ma== 0 ) d_fast_ma= iMA (ea. Symbol ,ea. Period ,FAST_MA_PERIOD, 0 ,FAST_MA_METHOD,FAST_MA_PRICE,shift);
if (d_slow_ma== 0 ) d_slow_ma= iMA (ea. Symbol ,ea. Period ,SLOW_MA_PERIOD, 0 ,SLOW_MA_METHOD,SLOW_MA_PRICE,shift);  


처음에 당신의 접근 방식은 순전히 절차적입니다. 내가 보는 것을 노래합니다. 그리고 평균이 가격이 아니라 거래량이나 다른 지표에 대해 계산해야 한다면? 사용자를 다시 강제로 다시 쓰시겠습니까? 평균 계산은 알고리즘입니다. 알고리즘을 적용하려는 것은 데이터입니다. 알고리즘을 즉시 구분하는 대신 데이터와 혼합하고 있습니다(이 의사 코드의 경우).

 int period_ma = 12 ;
int shift = 3 ;
double fast_ma = SMA( Close , period, shift);

죄송합니다. 시리즈 색인을 잊어버렸습니다. - 사실, 그러면 안됩니다. 알고리즘을 파이프라인으로 결합 하여 링 버퍼의 모든 것을 계산해야 합니다.

 
Maxim Kuznetsov :

https://www.mql5.com/ru/articles/5654 및 Karputov 씨의 고문과의 반대 논제 및 논쟁

내 마땅히 잊혀지지 않은 . 그리고 헛되이 많은 것들이 있습니다.

 
Vasiliy Sokolov :

처음에 당신의 접근 방식은 순전히 절차적입니다. 내가 보고 노래합니다. 그리고 평균이 가격이 아니라 거래량이나 다른 지표에 대해 계산해야 한다면? 사용자를 다시 강제로 다시 쓰시겠습니까? 평균 계산은 알고리즘입니다. 알고리즘을 적용하려는 것은 데이터입니다. 알고리즘을 즉시 구분하는 대신 데이터와 혼합하고 있습니다(이 의사 코드의 경우).

죄송합니다. 시리즈 색인을 잊어버렸습니다. - 사실, 그러면 안됩니다. 알고리즘을 파이프라인으로 결합하여 링 버퍼의 모든 것을 계산해야 합니다.

모든 작업의 대부분이 이를 위해 수행됩니다. 모든 것의 모든 것을 셀 수 있고 고문 자신이 순서와 관계를 이해합니다. 한 번은 MT4에서 스프레드시트 계산기를 la micro-excel로 만들고 이미지와 유사도에서 계산 구성을 취했습니다.

사용 사례에서 스타일은 가장 일반적으로 기본적으로 절차적입니다. 잠재적인 사용자( 초보 프로그래머 )는 정확히 그렇게 씁니다.