Tutte le domande dei nuovi arrivati su MQL4 e MQL5, aiuto e discussione su algoritmi e codici - pagina 380

 
Ciao a tutti.
Questa è la mia prima volta sul forum, se sto facendo qualcosa di sbagliato sul forum, per favore perdonatemi in anticipo.
Guardo i grafici con gli indicatori per molto tempo. Recentemente ho perso 2 depositi. Prima di aprire un nuovo conto voglio controllare la redditività della strategia sulla storia. Sto usando un conto demo in MT4.
Non sono affatto un programmatore. Sono solo in grado di installare l'indicatore su MT4 e forse cambiare lo spessore della linea dell'indicatore in MetaEditor (molto probabilmente non sarò in grado di cambiare il colore nel codice dell'indicatore, solo nel terminale).
Hai qualche informazione chiara per qualcuno con le mie conoscenze, dove iniziare a testare passo dopo passo (in inglese semplice "istruzioni per i negri come usare il bagno")? La strategia ha 3 indicatori: MA (3 semplici), Stocastico con livelli standard e CCI con 5 livelli. Apertura di operazioni short dopo aver attraversato i livelli degli indicatori dall'alto verso il basso, operazioni long viceversa (credo sia chiaro...). Impostazione della presa e della perdita.
Vorrei essere in grado di tracciare visivamente la strategia in modalità automatica così come senza visualizzazione per selezionare i parametri degli indicatori e degli ordini.
 
ZebStamp:
Ciao a tutti.
Questa è la mia prima volta sul forum, se sto facendo qualcosa di sbagliato sul forum, per favore perdonatemi in anticipo.
Guardo i grafici con gli indicatori per molto tempo. Recentemente ho perso 2 depositi. Prima di aprire un nuovo conto voglio controllare la redditività della strategia sullo storico. Sto usando un conto demo in MT4.
Non sono affatto un programmatore. Sono solo in grado di installare l'indicatore su MT4 e forse cambiare lo spessore della linea dell'indicatore in MetaEditor (molto probabilmente non sarò in grado di cambiare il colore nel codice dell'indicatore, solo nel terminale).
Avete qualche informazione chiara per qualcuno con le mie conoscenze, da dove iniziare a testare passo dopo passo (in inglese semplice "istruzioni per i negri come usare il bagno")? La strategia ha 3 indicatori: MA (3 semplici), Stocastico con livelli standard e CCI con 5 livelli. Apertura di operazioni short dopo aver attraversato i livelli degli indicatori dall'alto verso il basso, operazioni long viceversa (credo sia chiaro...). Impostazione della presa e della perdita.
Vorrei essere in grado di seguire la strategia in modalità automatica visivamente, così come senza visualizzazione per selezionare i parametri degli indicatori e degli ordini.

Quando si crea un oggetto grafico (GO), come la TrendLine, si seleziona il colore. Quando ricreate la linea di tendenza, questa viene creata con lo stesso colore. Per Hline - si sceglie un colore - e il prossimo è così. Prendete il giallo, il blu, ...

Se CS crea Expert Advisor, indicatore, script - poi come si scrive nel programma. A volte la scelta dei parametri

 
STARIJ:

Se pensate che qualcuno guardando il vostro codice possa trovare rapidamente un errore, vi sbagliate. Il compilatore cerca gli errori. Il testo del programma dovrebbe essere formattato - MetaEditor ha uno strumento di styling per questo. Se ti piace uno stile diverso - usa, per esempio, il programma AStyle.exe. Dopo lo styling, vedrete rapidamente che il programma 1) ha una parentesi di chiusura in più. 2) Variabile dichiarata: datetime date_Buf_1; // indicatore array di date - perché questo sia un array, deve essere [size] o [] per un array dinamico e poi la dimensione deve essere impostata su ArrayResize, sembra. E devi farlo prima di usare un array - vedi i post precedenti a questo proposito. 3) FileOpen(InpDirectoryName+"//"+InpFileName - sembra che i bastoni dovrebbero essere inclinati dall'altra parte. Ed è meglio fare a meno di InpDirectoryName+"//" - troverete comunque il file nella cartella Files.

sulla linea: int copied=CopyTime(NULL,0,0,0,0,date_Buf_1); il compilatore si arrabbia, start=0=0


Grazie. Sono riuscito a risolvere qualcosa, ma più intuitivamente che capendo. Ma abbiamo ancora 3 errori riguardanti l'array:

'Buf_1' - array richiesto 111.mq4 93 21

'date_Buf_1' - array richiesto 111.mq4 94 21

'Buf_1' - array richiesto 111.mq4 100 16


//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
input string             InpFileName="111.csv";      // Имя файла 
input string             InpDirectoryName="Data";     // Имя каталога 

datetime Время=0;   // Время прошлого бара
double Bid1;
double   Buf_1[];
// double ExtBuffer;
long V1; // объем для текущего тика вверх
long V2; // накопленный объем для всех тиков вверх текущего бара
long V3; // объем текущего тика вниз
long V4; // накопленный объем для всех тиков вниз для текущего бара
long V5;  // отрицательные и положительные iVolume нарастающим итогом
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnInit()
  {
   IndicatorDigits(0);
   SetIndexBuffer(0,Buf_1);
//SetIndexBuffer(1,Buf_2);
   Bid1=Bid;
   V5=0;

  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
   datetime Вр=Time[0];   // Время текущего бара
   if(Вр>Время)           // Если новый бар
     {
      Время=Вр;           // Запомнить
                          //      Buf_1[0]=0;         // и обнулить последний элемент буфера
     }

   datetime date_Buf_1[]; // массив дат индикатора 
   datetime time_Buf_1[]; // массив времени 
                          // --- считаю объем для положительных и отрицательных тиков      
   if(Bid>=Bid1)
     {
      if(Bid>Bid1) // если тик положительный..
        {
         V1=iVolume(NULL,0,0); // если повышающий цену тик, то находим его объем
         V2= V1 + V2;
        }
      else
        {
         V1=0;                // если Bid1 = Bid2, т.е. изменение цены = 0, то iVolume этого тика присваиваем 0;
         V2= V1 + V2;
        }
     }
   else
     {
      V3 = iVolume(NULL, 0, 0); // если понижающий цену тик 
      V4 = V3 + V4;             // то находим его объем  
     }

   V5=V2-V4;               // определяем разницу (дельту) между объемами положительных и отрицательных тиков
   Bid1=Bid;
   Buf_1[0]=V5; // в буфер сгружаем  дельту

                //   ExtBuffer = Buf_1 [0];
//   double macurrent=iMAOnArray(ExtBuffer,0,5,0,MODE_LWMA,0); 

// запись в файл данных буфера


//--- установим для массивов признак таймсерии 
   ArraySetAsSeries(Buf_1[0],true);
   ArraySetAsSeries(date_Buf_1[0],true);

//--- скопируем таймсерию 
   int copied=CopyTime(NULL,0,10000,0,date_Buf_1);

//--- подготовим массив Buf_1 
   ArrayResize(Buf_1[0],copied);

//--- скопируем значения линии индикатора  
   for(int i=0;i<copied;i++)
     {
      Buf_1[i]=V5;
     }
//--- откроем файл для записи значений индикатора 
   ResetLastError();
   int file_handle=FileOpen(InpDirectoryName+"//"+InpFileName,FILE_READ|FILE_WRITE|FILE_CSV);
   if(file_handle!=INVALID_HANDLE)
     {
      PrintFormat("Файл %s открыт для записи",InpFileName);
      PrintFormat("Путь к файлу: %s\\Files\\",TerminalInfoString(TERMINAL_DATA_PATH));
      //--- сначала запишем значения индикатора 
      FileWrite(file_handle,Buf_1[0]);
      //--- запишем время и значения в файл 
      for(int i=0;i<Buf_1[0];i++)
         FileWrite(file_handle,time_Buf_1[0],Buf_1[0]);
      //--- закрываем файл 
      FileClose(file_handle);
      PrintFormat("Данные записаны, файл %s закрыт",InpFileName);
     }
   else
      PrintFormat("Не удалось открыть файл %s, Код ошибки = %d",InpFileName,GetLastError());

   return(rates_total);
  }
//+------------------------------------------------------------------+


Non capisco come implementare i tuoi commenti. Ma ho trovato un punto fermo in più :)
 
YarTrade:

Grazie. Sono riuscito a risolvere qualcosa, ma più intuitivamente che capendo. Ma ho ancora 3 errori riguardanti l'array:

'Buf_1' - array richiesto 111.mq4 93 21

'date_Buf_1' - array richiesto 111.mq4 94 21

'Buf_1' - array richiesto 111.mq4 100 16



Non capisco come implementare i tuoi commenti. Ma ho trovato una staffa in più :)
Lascia solo i nomi delle variabili dell'array. Rimuovete "[]" in quelle linee di codice a cui il compilatore vi punta.
 
Artyom Trishkin:
Lascia solo i nomi degli array di variabili. Rimuovete "[]" in quelle linee di codice a cui il compilatore vi punta.

Grazie. Vedrò cosa succede nella vita reale. Ho grandi dubbi che qualcosa verrà scritto nel file :)

 

Sono sorte diverse domande, spero molto nel vostro aiuto. Ho trovato una cosa molto triste, che le prestazioni di EA durante i test e in tempo reale sono molto diverse, quindi vorrei analizzare gli errori più comuni e tipici. Per prima cosa scriverò di quelli che ho incontrato. Vi sarei grato se poteste condividere le vostre esperienze con il programmatore che sa cosa deve tenere a mente e cosa deve tenere nel suo codice.

1. L'errore di divisione per zero appariva nella modalità di trading reale, nonostante il fatto che la divisione per zero non fosse presente nel codice e non si fosse verificato durante i backtest. Il programmatore ha risolto il problema scrivendo ogni divisore come NormalizeDouble(x,Digits);

2. L'accordo non si è aperto. Venerdì, quando ho eseguito il backtest, l'affare si è aperto, ma non quando stavo facendo trading. Inoltre, il giornale dell'Expert Advisor non ha mostrato alcun errore. Non so quale possa essere il problema qui, ma ho un paio di cose. In primo luogo, ho ricevuto avvertimenti come "il valore di ritorno di 'ordersend' dovrebbe essere controllato", ma se ho capito bene, questo non dovrebbe influenzare l'esecuzione del codice? O si tratta solo di slittamento? Il mio valore è 1, che non è troppo piccolo. E la barra alla quale dovrei eseguire un'entrata si è aperta senza un gap.

Ho preso la linea "if(Volume[0]>1) return;" dall'esempio standard con slittamenti e l'ho inserita all'inizio del codice. Cioè, il mio codice viene eseguito solo durante il primo tick quando appare una nuova barra. Può essere che una barra si apra con un volume e il mio codice non venga eseguito?

4. Per favore consigliate sulle cose a cui prestare attenzione o sugli errori tipici quando si lavora con EA con la storia e il tempo reale, per favore


 
LuckySith:

Sono sorte diverse domande, spero molto nel vostro aiuto. Ho trovato una cosa molto triste, che le prestazioni di EA durante i test e in tempo reale sono molto diverse, quindi vorrei analizzare gli errori più comuni e tipici. Per prima cosa scriverò di quelli che ho incontrato. Vi sarei grato se poteste condividere le vostre esperienze con il programmatore che sa cosa deve tenere a mente e cosa deve tenere nel suo codice.

1. L'errore di divisione per zero appariva nella modalità di trading reale, nonostante il fatto che la divisione per zero non fosse presente nel codice e non si fosse verificato durante i backtest. Il programmatore ha risolto il problema scrivendo ogni divisore come NormalizeDouble(x,Digits);

2. L'accordo non si è aperto. Il giorno di venerdì l'affare è stato aperto quando il backtest era in esecuzione, ma nessun affare è stato aperto durante il trading reale. Inoltre, il giornale dell'Expert Advisor non ha mostrato alcun errore. Non so quale possa essere il problema qui, ma ho un paio di cose. In primo luogo, ho ricevuto avvertimenti come "il valore di ritorno di 'ordersend' dovrebbe essere controllato", ma se ho capito bene, questo non dovrebbe influenzare l'esecuzione del codice? O si tratta solo di slittamento? Il mio valore è 1, che non è troppo piccolo. E la barra alla quale dovrei eseguire un'entrata si è aperta senza un gap.

Ho preso la linea "if(Volume[0]>1) return;" dall'esempio standard con slittamenti e l'ho inserita all'inizio del codice. Cioè, il mio codice viene eseguito solo durante il primo tick quando appare una nuova barra. Può essere che una barra si apra con un volume e il mio codice non venga eseguito?

4. Si prega di consigliare le cose a cui prestare attenzione o gli errori tipici quando si lavora con EA con la storia e il tempo reale, per favore

Sostituite questo costrutto selvaggio "if(Volume[0]>1) return;" con un normale controllo "New Bar", il forum ne è pieno.

Gli avvertimenti del tipo "il valore di ritorno di 'ordersend' dovrebbe essere controllato" non sono errori finora, sono potenziali errori per il futuro. Non ci dovrebbero essere avvertimenti nel codice, tanto meno quando si lavora online.

"Ho 1, che non è troppo poco" - questo può essere molto poco all'apertura di una nuova barra, e soprattutto all'apertura di una mezz'ora o di un'ora, in questo momento lo spread si allarga molto.

Ciò di cui abbiamo bisogno: fare un controllo sulla nuova barra, e se è nuova, poi guardare le condizioni per l'ingresso, se hanno coinciso - fare un accordo. Dopo di che dobbiamo registrare che la barra ha funzionato e aspettare quella nuova.

Cosa abbiamo ora: if(Volume[0]>1) return; = se c'è una nuova barra, cerchiamo le condizioni, la condizione non si adattava == grande spread = uscire di nuovo in OnTick(), sul prossimo tick if(Volume[0]>1) return; non andrà oltre, quindi il trade è già mancato, anche se lo spread è 0.0001

 

Salve. Potete per favore dirmi come descrivere quanto segue con il codice: C'è un piano, delimitato da linee orizzontali superiori e inferiori. L'Expert Advisor li rileva e li imposta da solo.

Abbiamo bisogno che l'EA rilevi quando il prezzo lascia la zona piatta e poi ritorna in questa zona. E solo dopo apre una posizione.

Per filtrare il rumore, uso un bersaglio mobile con il parametro 2 o 3

 
Vitaly Muzichenko:

Sostituite tali costruzioni selvagge "if(Volume[0]>1) return;" con un normale controllo "New Bar", ce ne sono molti qui sul forum.

Avvertimenti come "il valore di ritorno di 'ordersend' dovrebbe essere controllato" - questo non è ancora un errore, questo è un potenziale errore per il futuro. Non dovrebbero esserci avvertimenti nel codice, tanto meno quando si lavora online.

"Ho 1, che non è troppo poco" - questo può essere molto poco all'apertura di una nuova barra, e soprattutto all'apertura di una mezz'ora o di un'ora, in questo momento lo spread si allarga molto.

Quello di cui abbiamo bisogno: fare un controllo sulla nuova barra, e se è nuova, poi guardare le condizioni di ingresso, se coincidono - fare un accordo. Dopo di che dobbiamo registrare che la barra ha funzionato e aspettare quella nuova.

Quello che abbiamo ora: if(Volume[0]>1) return; = se c'è una nuova barra, allora guardate le condizioni, la condizione non si adatta == grande spread = uscite di nuovo in OnTick(), sul prossimo tick if(Volume[0]>1) return; non mancherà ulteriormente, quindi il trade sarà mancato anche se lo spread è 0.0001


Sull'apertura di un nuovo bar. Sarebbe buono? :

datetime counted_bar = 0;

int OnInit()
{
   counted_bar = 0; // если нужно, чтоб при перезапуске последний бар был проанализирован
   ...

void OnTick()
{
   // Если появился новый бар
   if ( iTime( _Symbol, _Period, 0 ) > counted_bar )
   {
      counted_bar = iTime( _Symbol, _Period, 0 );

      // Анализируем индикаторы
      ...
   }
 
LuckySith:

Sull'apertura di un nuovo bar. Sarebbe una buona opzione? :

Che sia così all'inizio.

Successivamente, dobbiamo fare una corretta fissazione che la barra è elaborata, ma qui dobbiamo calcolare l'intero approccio alla TOR.

Per quanto posso vedere dal tuo post, dobbiamo farlo in questo modo:

void OnTick()
{
   // Если появился новый бар
   if ( iTime( _Symbol, _Period, 0 ) > counted_bar )
   {
      // Анализируем индикаторы
      if(SpreadMax > текущий спред) return;

      counted_bar = iTime( _Symbol, _Period, 0 );
      ...
   }

L'essenza è questa: se lo spread è più alto del normale, allora usciamo di nuovo aOnTick, e su un nuovo tick controlliamo lo spread, se è normale - inviamo un ordine e ricordiamo che c'è stato un trade su questa barra.

C'è anche un secondo modo:

void OnTick()
{
   // Если появился новый бар
   if ( iTime( _Symbol, _Period, 0 ) > counted_bar )
   {
      if(SpreadMax > текущий спред) return;
      // Анализируем индикаторы
      ...
      result = OrderSend(...);
      // если открылась позиция, то result будет тикет позиции
       if(result>0) counted_bar = iTime( _Symbol, _Period, 0 );
   }

In generale, è necessario definire la logica, quando dovrebbe registrare, e non controllare di nuovo prima della formazione di una "Nuova barra".

Motivazione: