Mt4 지원 종료. - 페이지 27

 
Реter Konow :
선형, 비선형 ... 프로그래밍에서 오페라를 다시 말씀하시는 건가요?

절대 안돼

 
Реter Konow :

확인. 귀하의 솔루션은 진드기에서만 작동합니다. 내 것은 타이머에 있습니다. 막대 모양과 동기화하는 내 방법에 단점이 있다고 생각합니까? 확인. 그러면 그렇게 해. 나는 새로운 바의 플래그를 설정하기 전에 견적의 도착에 대한 수표를 추가할 것입니다. 함수에 다른 매개변수인 기호를 추가하겠습니다. 사용자는 새 막대의 이벤트를 수신하고 함수로 보내는 데 필요한 기호를 선택합니다. 함수는 이 기호 의 마지막 인용 시간을 확인합니다 . 다음으로, 바의 정식 출현 시간과 인용 시간을 비교하여 이벤트 플래그를 설정합니다.

방금 이 주제를 이해하기 시작했지만 어려움이 보이지 않습니다.

거래, 자동 거래 시스템 및 거래 전략 테스트에 관한 포럼

Mt4 지원 종료.

Artyom Trishkin , 2017.09.10 22:27

견적을 받는 방법을 알고 있습니다 :)

다중 통화 프로그램 에서 - 필요한 기호에 대한 주기의 타이머에서 . 그리고 새로운 막대(실제, 가상이 아닌 - 오류가 있는 것)를 여는 것은 마지막 인용 시간 및 이 시간을 기호의 0 막대 시간과 비교한 시간에 의해 제어됩니다 .

당신은 무작위로 그것을 합니다 - 존재하지 않을 수도 있는 가상 바. 주말에는 사용할 수 없지만 가지고 있다고 합니다. 이것은 예로 들 수 있는 가장 간단한 것입니다.

그리고, 당신 혼자는 이것을 하지 않을 것임을 이해하십시오. 나머지는 옳고 안전한 일을 합니다. 그러나 이것은 물론 당신 자신의 일입니다.

OOP로 작성하는 단순함과 같은 문제를 풀 때 절차적 스타일의 복잡한 우여곡절에서 큰 차이를 보여주고 제대로 하는 방법을 알려드리고 싶었습니다.

하지만 더 많이 알고 있을 것이고 필요하지 않을 것입니다. 나는 더 이상 감히 당신 앞에서 아무것도 아는 것처럼 보이지 않습니다. 죄송합니다.


 
Galina Bobro :

물론 문제가 아닙니다. 고객이 미치광이이고 동시에 모든 기호를 거래할 경우 문자열 연산의 비교를 저장하기 위한 헤지입니다.

따라서 작업과 메모리를 저장할 다른 곳이 없는 것 같습니다.

void OnTimer(){

   Alert(Fn_new_bar("EURUSD", PERIOD_D1)); }

//+------------------------------------------------------------------+

uint Sp_Adler32(string line){

   ulong s1 = 1;

   ulong s2 = 0;

   uint buflength=StringLen(line);

   uchar char_array[];

   ArrayResize(char_array, buflength,0);

   StringToCharArray(line, char_array, 0, -1, CP_ACP);

   for (uint n=0; n<buflength; n++){

      s1 = (s1 + char_array[n]) % 65521;

      s2 = (s2 + s1)     % 65521;}

   return ((s2 << 16) + s1);}

//+------------------------------------------------------------------+

bool Fn_new_bar(string symb, ENUM_TIMEFRAMES tf){

   static datetime st_time[]; 

   static uint     st_id[];

   

   //---- set

   datetime new_time = iTime(symb, tf, 0);     if(new_time==0) return(false); 

   uint     new_id   = Sp_Adler32(StringConcatenate(symb,EnumToString(tf))); 

   datetime old_time = 0; 

   uint     old_id   = 0;

   

   //---- find

   int size = ArraySize(st_time); 

   for(int i=0; i<size; i++){

      if(st_id[i]!=new_id) continue; 

      old_id   = st_id  [i]; 

      old_time = st_time[i];

      break;}

   

   //----add new element

   if(old_time==0){

      ArrayResize(st_time, size+1); st_time[size]=new_time;

      ArrayResize(st_id,   size+1); st_id  [size]=new_id; }

   

   //----

   return(old_time>0 && old_time<new_time);}


이것은 오늘날 구조 면에서 가장 정상적인 코드인 것 같습니다. 새로운 기호와 tf에 대한 검사가 있으며 예외 없이 모든 것을 검사하지는 않지만 필요한 것만 검사하고 불필요한 작업은 없으므로 매우 빨리 수행되어야 합니다.

감사합니다.

추신: 여기에 추가할 수 있는 유일한 작은 것은 st_time 및 st_id 배열을 구조로 결합하는 것입니다. 서로 연결되어 있기 때문에 코드에서 배열 증가 작업의 수를 줄일 수 있습니다.

 
Artyom Trishkin :

내 목표는 그의 절차적 스타일 코드가 다음과 같은 루프에서 실행되도록 하는 것이었습니다.

 ENUM_TIMEFRAMES array_timeframes[]=
      {
       PERIOD_M1 , PERIOD_M2 , PERIOD_M3 , PERIOD_M4 , PERIOD_M5 , PERIOD_M6 , PERIOD_M10 , PERIOD_M12 , PERIOD_M15 , PERIOD_M30 ,
       PERIOD_H1 , PERIOD_H2 , PERIOD_H3 , PERIOD_H4 , PERIOD_H6 , PERIOD_H8 , PERIOD_H12 , PERIOD_D1 , PERIOD_W1 , PERIOD_MN1
      };
   int total= SymbolsTotal ( true ), total_tf= ArraySize (array_timeframes);
   for ( int i= 0 ; i<total; i++){
       string symbol_name= SymbolName (i, true );
       for ( int j= 0 ; j<total_tf; j++){
         if (IsNewBar(symbol_name,array_timeframes[j])){
             Print ( "Новый бар на " ,symbol_name, " " , EnumToString (array_timeframes[j]));
            }
         }
      }


음, 다음과 같습니다(MQL5용 코드).

 int OnInit ()
  {
   IsNewBar();  // сбор информации - можно включить здесь, но не обязательно
   EventSetMillisecondTimer ( 100 );
   return ( INIT_SUCCEEDED );
  }

void OnDeinit ( const int reason)
  {
   EventKillTimer ();
  }

void OnTimer ()
  {
   IsNewBar();   // сбор информации - можно включить здесь, но не обязательно
                 // различные варианты проверки новых баров
   if (IsNewBar( true )) Print ( "Пришел новый бар текущего ТФ текущего инструмента" );   // режим вывода информации
   if (IsNewBar( true , PERIOD_H4 )) Print ( "Пришел новый бар H4 текущего инструмента" );   // режим вывода информации
   if (IsNewBar( true , PERIOD_D1 )) Print ( "Пришел новый бар D1 текущего инструмента" );   // режим вывода информации
   if (IsNewBar( true , PERIOD_M1 , "GBPUSD.m" )) Print ( "Пришел новый бар M1 GBPUSD" );     // режим вывода информации
   if (IsNewBar( true , PERIOD_M3 , "GBPUSD.m" )) Print ( "Пришел новый бар M3 GBPUSD" );      // режим вывода информации
   if (IsNewBar( true , PERIOD_M2 , "USDCHF.m" )) Print ( "Пришел новый бар M2 USDCHF" );      // режим вывода информации
  }

void OnTick ()
  {
   IsNewBar();   // сбор информации - можно включить здесь, но не обязательно
                 // различные варианты проверки новых баров
   if (IsNewBar( true )) Print ( "Пришел новый бар текущего ТФ текущего инструмента" );   // режим вывода информации
   if (IsNewBar( true , PERIOD_H4 )) Print ( "Пришел новый бар H4 текущего инструмента" );   // режим вывода информации
   if (IsNewBar( true , PERIOD_D1 )) Print ( "Пришел новый бар D1 текущего инструмента" );   // режим вывода информации
   if (IsNewBar( true , PERIOD_M1 , "GBPUSD.m" )) Print ( "Пришел новый бар M1 GBPUSD" );      // режим вывода информации
   if (IsNewBar( true , PERIOD_M3 , "GBPUSD.m" )) Print ( "Пришел новый бар M3 GBPUSD" );      // режим вывода информации
   if (IsNewBar( true , PERIOD_M2 , "USDCHF.m" )) Print ( "Пришел новый бар M2 USDCHF" );      // режим вывода информации
  }
//+---------------------------------------------------------------------------------------------------+
//|   Функция определения нового бара по всем ТФ всех инструментов в окне "Обзор рынка"               |
//|   два режима работы:                                                                              |
//|   - режим сбора информации, out=false (значение по умолчанию). Достаточно запустить IsNewBar();   |
//|   - режим вывода информации, out=true                                                             |
//|   tf - период таймфрейма, по умолчанию текущий ТФ (необходим только при выводе информации)        |
//|   Sym - символ инструмента, по умолчанию текущий символ (необходим только при выводе информации)  |
//+---------------------------------------------------------------------------------------------------+
bool IsNewBar( bool out= false , ENUM_TIMEFRAMES tf= PERIOD_CURRENT , string Sym= "" ) 
  {
   static const ENUM_TIMEFRAMES TF[ 22 ]=
     {
       PERIOD_CURRENT , PERIOD_M1 , PERIOD_M2 , PERIOD_M3 , PERIOD_M4 , PERIOD_M5 , PERIOD_M6 , PERIOD_M10 , PERIOD_M12 , PERIOD_M15 , PERIOD_M20 , PERIOD_M30 ,
       PERIOD_H1 , PERIOD_H2 , PERIOD_H3 , PERIOD_H4 , PERIOD_H6 , PERIOD_H8 , PERIOD_H12 , PERIOD_D1 , PERIOD_W1 , PERIOD_MN1
     };
   static bool newbar[];
   static long acb[]; // array of current bars
   static int N_Sym= 0 ;
   if (Sym== "" ) Sym= Symbol ();
   int total= SymbolsTotal ( true );
   int n_cur=- 1 ;
   for ( int i= 0 ; i<total; i++) if (Sym== SymbolName (i, true )){ n_cur=i; break ;}
   if (n_cur< 0 ) { Print ( "данного символа нет в списке MarketWatch(окошко слева - Обзор рынка)" ); return ( false );}
   if (out && N_Sym> 0 ) // если режим вывода информации 
     {
       int curtf= 0 ;
       while (TF[curtf]!=tf) curtf++;
       return (newbar[n_cur* 22 +curtf]);
     }
// режим сбора информации
   if (total!=N_Sym) { ArrayResize (acb, 22 *total); ArrayInitialize (acb, 0 ); ArrayResize (newbar, 22 *total); ArrayInitialize (newbar, false ); N_Sym=total;}
   for ( int j= 0 ,j1= 0 ; j<total; j++,j1+= 22 )
       for ( int i= 0 ;i< 22 ;i++)
        {
         long CurBars= SeriesInfoInteger ( SymbolName (j, true ),TF[i], SERIES_LASTBAR_DATE );
         if (acb[j1+i]<CurBars) // пришел новый бар
           {
             //if (acb[j1+i]>0) Print ("Новый бар: "+SymbolName(j,true)+"   "+EnumToString(TF[i]));
            acb[j1+i]=CurBars;
            newbar[j1+i]= true ;
           }
         else
           {
            newbar[j1+i]= false ;
             if (i== 1 ) for (;i< 22 ;i++) newbar[j1+i]= false ;   // если минутный бар тот же, то нет смысла продолжать проверять старшие ТФ
           }
        }
   return ( false );
  }

하지만 반복합니다. 저는 OOP의 지지자입니다.
절차적 프로그래밍으로 할 수 없는 것을 보여주는 정말 나쁜 예일 뿐입니다.

 
Andrey Kisselyov :
이것은 Expert Advisor에서 함수를 호출하는 것이 아니라 범용 인터페이스(핸들러)를 작성하는 것입니다.

로봇을 작성 하기 위한 1000개의 참조 용어가 있습니다. 사실 각 용어는 다음으로 구성됩니다.
열릴 1 신호 수신 기능
2 주문 열기 기능
3 주문 추적 기능
4 신호 수신 기능을 닫습니다.
등.
각 로봇에는 고유한 기능이 있지만 1000개 프로젝트 내에서 반복됩니다. 결과적으로 기능을 범용 모듈로 결합하고 작업에 따라 올바른 모듈을 호출할 수 있습니다.

글쎄, 이러한 기능이 있다면 더 이상 현명하지 않아도됩니다. 함수의 입력 매개변수는 인터페이스입니다. 각 추가 지혜는 가능한 오류의 수와 프로그래머의 작업 시간을 증가시킵니다.

 
Nikolai Semko :

음, 다음과 같습니다(MQL5용 코드).

하지만 반복합니다. 저는 OOP의 지지자입니다.
절차적 프로그래밍으로 할 수 없는 것을 보여주는 정말 나쁜 예일 뿐입니다.

그런 예가 실제로 존재 합니까? 당신의 것이 아니라? 깊은 의심이 있습니다. 2000년대 초에 디버깅하고 작업한 코드 줄 수를 세는 것을 중단했는데, 백만 개를 초과했기 때문에 재미가 없었습니다. 그리고 작업의 다양성과 범위가 매우 다르지만 자신만의 클래스를 만들 필요가 전혀 없었습니다. 절차형 변수는 여러 사람의 작업을 병렬화해야 할 때 사용해야 했지만 더 이상은 필요하지 않습니다. 왜 그런 겁니까?

그런데 왜 OOP의 대안으로 절차적 프로그래밍에 대해 이야기하고 있습니까? 기본적으로 비절차적(SQL) OOP가 없는 언어가 있으며 언어 개발 방향도 있습니다. 기능 프로그래밍 https://ru.wikipedia.org/wiki/%D0%A4%D1% 83%D0%BD%D0%BA%D1% 86%D0%B8%D0%BE%D0%BD%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B5_% D0%BF%D1%80%D0%BE% D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0% B0%D0%BD%D0%B8%D0% B5 : "일부 개념과 패러다임은 함수형 프로그래밍에만 해당되며 대부분 명령형 프로그래밍( 객체 지향 프로그래밍 포함)에는 익숙하지 않습니다.", "함수형 프로그램의 또 다른 장점은 다음을 제공한다는 것입니다. 계산의 자동 병렬화 를 위한 가장 넓은 가능성." OOP는 계산의 자동 병렬화를 방지합니다. 이제 이것은 매우 심각한 결점으로 간주되어야 하며 전망은 OOP에 대한 것이 아닙니다.

 
Vladimir :

그런 예가 실제로 존재 합니까? 당신의 것이 아니라? 깊은 의심이 있습니다.


나는 그러한 예를 찾을 수 없을 가능성이 높다고 생각합니다. 개인적으로 OOP의 주요 장점은 대규모 프로젝트 의 프로그래밍이 더 편리하고 향후 개발을 사용하기 위한 편리한 메커니즘이라고 생각합니다. 이것은 여기에서 여러 번 올바르게 말한 것입니다.

 
Andrei :

단일 인터페이스는 모든 계산 작업을 프로그래밍하는 데 완전히 적용할 수 없다는 것은 이미 논의된 것 같습니다... 인터페이스의 형태로 아름다움을 가져오는 것은 기성 코드에만 적용할 수 있는 순전히 미용적인 절차이며, 코드의 추가 지원 및 개선 ...

음 ... 아니. '전혀 적용 불가'가 아니라 '적용할 가치가 없다'는 얘기다.

인터페이스는 "완성된 코드에 적용할 수 있는 순전히 미학적 절차"가 아닙니다.

정반대로 인터페이스는 시스템 아키텍처의 기초입니다. 디자인 이 시작되는 곳. 인터페이스는 "지원 및 개선을 방해"하지 않고 오히려 허용 가능한 경계를 명확하게 설명하여 지원합니다. 인터페이스가 없으면 이러한 경계를 쉽게 넘고 의도하지 않은 부분을 변경하여 계산하기 어려운 오류가 발생합니다.

모든 복잡한 시스템(프로그래밍뿐 아니라)은 해당 부분의 상호 작용에 대한 기본 원칙의 개발로 시작됩니다. 그리고 프로그래밍에서 - 처음에는 일반적으로 작업이 매우 작기 때문에 반대 방향으로 진행됩니다. 첫째, 부분이 작성된 다음 전체로 결합됩니다. 종종 부분이 서로 잘 호환되지 않는다는 사실에 직면합니다. 그런데 이것이 바로 "사용 가능한 모든 변수에 액세스할 수 있는 권한을 갖고자 하는 욕구"를 설명하는 것입니다. ."

 

isNewBar() 함수가 자연계에 전혀 존재하지 않아야 한다는 사실을 제외하고는 모든 것이 정상입니다. 그런 사소한 일 주위에 많은 춤이 있다는 것이 웃기다.

변수일 뿐이고 막대의 시간과 비교했을 뿐입니다. 모든 경우가 성공했다면 마지막에 변수에 새 막대 의 시간이 할당됩니다. 그렇지 않으면 모든 경우에 한 번의 시도만 할당됩니다.

 
Dmitry Fedoseev :

isNewBar() 함수가 자연에 전혀 존재하지 않아야 한다는 사실을 제외하고는 모든 것이 괜찮습니다. 그런 사소한 일 주위에 많은 춤이 있다는 것이 웃기다.

변수일 뿐이고 막대의 시간과 비교했을 뿐입니다. 모든 경우가 성공했다면 마지막에 변수에 새 막대 의 시간이 할당됩니다. 그렇지 않으면 모든 경우에 한 번의 시도만 할당됩니다.


+1

사유: