Mt4 Fine del supporto. - pagina 27

 
Реter Konow:
Lineare, non lineare... Stai parlando di nuovo dell'opera nella programmazione?

non se ne parla.

 
Реter Konow:

OK. La tua soluzione funziona solo sulle zecche. Il mio è su un timer. Pensate che il mio metodo di sincronizzazione con le apparizioni delle barre abbia un inconveniente. Ok. Che sia così. Aggiungerò un controllo per l'arrivo di una citazione prima di impostare una nuova bandiera a barre. Aggiungerò un altro parametro alla funzione - un simbolo. L'utente sceglierà il simbolo con cui vuole ricevere l'evento della nuova barra e lo invierà alla funzione. La funzione controlla il tempo dell'ultima citazione di questo simbolo. Poi confronteremo l'ora dell'apparizione formale della barra e l'ora della quotazione e imposteremo il flag dell'evento.

Ho appena iniziato a studiare questa materia, ma non vedo alcuna difficoltà.

Forum sul trading, sistemi di trading automatico e test di strategia

Mt4 Fine del supporto.

Artyom Trishkin, 2017.09.10 22:27

So come ottenere preventivi :)

In un programma multi-valuta - in un timer in un ciclo sui simboli giusti. E l'apertura di una nuova barra (fisica, non virtuale - errata - come da voi) è controllata dal tempo dell'ultima quotazione e confrontando quel tempo con il tempo del simbolo della barra zero.

Tu, d'altra parte, stai facendo a caso - un bar virtuale che potrebbe non esistere. Non li hai nel fine settimana, ma si suppone che tu li abbia - questa è la cosa più semplice da dare come esempio.

E, vedi, tu sei l'unico che non lo farebbe in questo modo. Il resto di noi lo fa nel modo giusto e affidabile. Ma questo, ovviamente, è solo affar suo.

Volevo dirvi come farlo bene e mostrare la grande differenza tra la semplicità di scrivere in OOP e le complicate torsioni in stile procedurale quando si risolve lo stesso compito.

Ma probabilmente ne sai di più e non ne hai bisogno. Non oso dare l'impressione di sapere qualcosa di più. Mi dispiace.


 
Galina Bobro:

Nessun problema. Hedge per salvare il confronto delle operazioni sulle stringhe, beh, se il cliente è un maniaco e scambierà su tutti i caratteri contemporaneamente.

Ma sembra che non ci sia nessun altro posto dove salvare le operazioni e la memoria - tutto è minimo

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);}


Sembra essere il codice strutturalmente più sensato finora. Ha un controllo per un nuovo simbolo e un tf, non controlla tutto, ma solo ciò che è necessario, nessuna operazione inutile, il che significa che dovrebbe funzionare abbastanza velocemente.

i migliori saluti.

P.S. l'unica piccola cosa che si potrebbe aggiungere qui è combinare gli array st_time e st_id in una struttura, dato che sono correlati, questo ridurrebbe il numero di operazioni di incremento dell'array nel codice.

 
Artyom Trishkin:

Avevo l'obiettivo di far sì che il suo codice in stile procedurale finisse per funzionare in un ciclo come questo:

 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]));
            }
         }
      }


qualcosa del genere (codice per 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);
  }

Ma lo dirò di nuovo - sono un sostenitore dell'OOP.
Solo un esempio davvero spiacevole per mostrare cosa non si può fare nella programmazione procedurale.

 
Andrey Kisselyov:
Non si tratta di chiamare una funzione in un EA, ma di scrivere interfacce universali (gestori).

avete 1000 compiti da scrivere robot; infatti, ognuno di essi consiste in
1 funzione di ottenere un segnale di apertura
2. funzione di apertura dell'ordine
3 funzione di monitoraggio dell'ordine
4) La funzione di ricevere un segnale per chiudere un ordine.
e così via.
Queste funzioni sono diverse per ogni robot, ma si ripetono in 1000 progetti. Di conseguenza, è possibile unire le funzioni in moduli universali e, a seconda del compito, chiamare quella giusta.

Bene, se avete queste funzioni, non avete bisogno di fare altro. I parametri di ingresso della funzione sono l'interfaccia. Ogni complessità in più aumenta il numero di possibili errori e aumenta il tempo di lavoro del programmatore.

 
Nikolai Semko:

qualcosa del genere (codice per MQL5):

Ma ripeto - sono un sostenitore dell'OOP.
È solo uno sfortunato esempio per mostrare cosa non si può fare nella programmazione procedurale.

Esiste un tale esempio in linea di principio? Anche se non il tuo? Ho profondi dubbi. Nei primi anni 2000 ho smesso di contare il numero di linee di codice debuggate e funzionanti che avevo scritto, perché superavano il milione - è diventato poco interessante. E non ho mai incontrato la necessità di creare la mia classe, anche se la varietà e la portata dei miei compiti erano molto diverse. Ho dovuto usare variabili di tipo procedura quando era necessario parallelizzare il lavoro per diverse persone, ma non più. Perché?

A proposito, perché parla di programmazione procedurale come alternativa a OOP? Ci sono linguaggi senza OOP, non procedurali in linea di principio (SQL), c'è anche una direzione di sviluppo dei linguaggi - la programmazione funzionale 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:"Alcuni concetti e paradigmi sono specifici della programmazione funzionale e sono per lo più estranei alla programmazione imperativa (compresa la programmazione orientata agli oggetti)", "Un altro vantaggio dei programmi funzionali è che forniscono vaste opportunità per la programmazione automatica Si scopre che l'OOP impedisce il parallelismo automatico dei calcoli. Questo dovrebbe ora essere considerato uno svantaggio molto serio, la prospettiva non è per OOP.

 
Vladimir:

C'è, in linea di principio, un esempio di questo? Anche se non il tuo? Ho profondi dubbi.


Penso che sia abbastanza possibile che un tale esempio non si trovi. Personalmente, credo che i principali vantaggi di OOP siano una programmazione più conveniente di grandi progetti e un meccanismo conveniente per utilizzare i vostri sviluppi in futuro. Questo è stato giustamente affermato qui molte volte.

 
Andrei:

È già stato discusso che una singola interfaccia non è applicabile alla programmazione di nessun compito computazionale... Mettere cose belle sotto forma di interfacce è una procedura puramente cosmetica, che è applicabile solo al codice già pronto e che impedisce anche un ulteriore supporto e perfezionamento del codice...

No. Non è "non applicabile a tutti" ma "non ha senso usarli".

Le interfacce non sono "una procedura puramente estetica applicabile al codice già pronto".

Al contrario, le interfacce sono al centro dell'architettura del sistema. È dove inizia il design. Le interfacce non "intralciano affatto il supporto e la rielaborazione", ma piuttosto li aiutano delineando chiaramente i confini di ciò che è ammissibile. Se non ci sono interfacce, è facile attraversare questi confini, e fare cambiamenti dove non erano previsti, con il risultato di errori difficili da calcolare.

Qualsiasi sistema complesso (non solo nella programmazione) inizia con lo sviluppo dei principi di base dell'interazione tra le sue parti. Ma nella programmazione, poiché il compito iniziale è di solito molto piccolo, vanno nella direzione opposta. Le parti vengono scritte prima e poi combinate in un tutto, spesso scoprendo che le parti non sono compatibili tra loro - a proposito, questo spiega il desiderio di "avere accesso a tutte le variabili disponibili".

 

Va bene, tranne per il fatto che la funzione isNewBar() non dovrebbe esistere affatto. È divertente che si balli così tanto intorno a una cosa così banale.

È solo una variabile, e viene semplicemente confrontata con il tempo della barra; se tutti i casi hanno successo, alla variabile viene assegnato il tempo della nuova barra alla fine. Altrimenti viene assegnato un solo tentativo a tutti i casi.

 
Dmitry Fedoseev:

Va bene, tranne per il fatto che la funzione isNewBar() non dovrebbe esistere affatto. È divertente che si balli così tanto intorno a una cosa così banale.

È solo una variabile, e viene semplicemente confrontata con il tempo della barra; se tutti i casi hanno successo, alla variabile viene assegnato il tempo della nuova barra alla fine. Altrimenti viene assegnato un solo tentativo a tutti i casi.


+1

Motivazione: