Meno codice, più azione... scrivere un EA - pagina 4

 
Maxim Kuznetsov:
Perché hai tolto il post sul prossimo passo?

Per favore, metti alla prova la tua arroganza. E leggere le regole della risorsa.

Tutti voi potete scrivere nei post del forum e nella descrizione in KodoBaz.

 
Maxim Kuznetsov:
Perché hai tolto il post sul prossimo passo?

Ho visto il post, non ho visto nulla di criminale. Credo di non aver cercato abbastanza.

 
Maxim Kuznetsov:

Certo che l'equilibrio sta scendendo, cosa vi aspettate da "due MA che si incrociano"?


Puoi prendere una base diversa per l'EA - le MA sono tutt'altro che la migliore opzione.

 
aleger:

Puoi prendere una base diversa per l'EA - il mashki è tutt'altro che la migliore opzione.

Se guardate un po' più attentamente, noterete che potete già implementare parecchie cose :-)

Quindi risulta quanto segue:

* il programmatore dell'applicazione (utente della libreria) ha dichiarato di avere un micro-excel con diverse colonne (nel caso d'uso queste sono FAST_MA, SLOW_MA, SIGNAL_BUY, SIGNAL_SELL)

* e ha abbozzato una funzione come sa calcolare le singole celle. Nell'esempio si riferiva a iMA.

* allo stesso tempo può accedere liberamente ad altre celle di questa tabella (DataFrame romperà le sequenze se possibile)

* e separatamente l'utente ha scritto la funzione "controlla i valori di riga e se è il momento di commerciare"

Ovviamente, questo è sufficiente per l'EA per iniziare il trading. E la strategia può essere cambiata in modo molto flessibile - tutto ciò che si può pensare come calcolo di una tabella è possibile.
L'altra cosa è che questo è solo il primo mezzo passo :-) finora, l'EA sta facendo trading come il monkey-shifter, solo con il lotto minimo, su un simbolo e da un timeframe.

 

Nelle prime due parti, abbiamo ottenuto un Expert Advisor che può eseguire le strategie più semplici, che sono descritte come "scimmie" o "lanci per segnale".
I segnali stessi sono programmati molto semplicemente, quasi come in Excel :-)

È il momento di insegnare un po' di più all'Expert Advisor. Almeno metti StopLoss e traina.

Completa la descrizione artistica della strategia con la frase "Lo stop loss è posto sulla distanza STOPLOSS_POINTS e trainato dai frattali". Introduciamo anche dei cambiamenti nel caso d'uso descritto sopra:

  • nuovo ingresso parametro EA int STOPLOSS_POINTS=100;
  • aggiungere due campi calcolati UPPER_FRACTAL,LOWER_FRACTAL in ENUM_SERIES
  • e nella funzione GetData aggiungere due "case:" per calcolarli

e fornire all'utente una funzione (metodo della classe EA), per impostare l'EA. La voce più semplice può essere vista come

SetStopLoss(STOPLOSS_POINTS,LOWER_FRACTAL,UPPER_FRACTAL);

recita "imposta lo Stop Loss ad una distanza specificata, e traina l'acquisto per colonna LOWER_FRACTAL, la vendita per UPPER_FRACTAL"; penso che il metodo abbia un nome ovvio e la sua sintassi sia più o meno chiara.

L'utente ipotetico ha fatto un sacco di gesti (ha dichiarato l'input, ha aggiunto due colonne e chiamato le impostazioni della funzione), svilupperemo la libreria in modo che le sue azioni portino al risultato atteso. Dovremo anche sviluppare calcoli tabellari e gettare le basi per il meccanismo di messaggi/eventi.

Nel copia-incolla, tutti i commenti non necessari e il codice MQL5 sono stati rimossi per la compattezza

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;

// начальные значения StopLoss, TakeProfit
input int STOPLOSS_POINTS=100;
input int TAKEPROFIT_POINTS=200;

#include "EA/EA.mqh"

enum ENUM_SERIES {
   FAST_MA,       // id. значений FAST_MA
   SLOW_MA,       // id. значений SLOW_MA 
   SIGNAL_BUY,    // сигнал к покупкам
   SIGNAL_SELL,   // сигнал к продажам
   UPPER_FRACTAL,       // верхний фрактал (для трала стопов ордеров sell)
   LOWER_FRACTAL, // нижний фрактал
   TOTAL_SERIES   // последний элемент перечисления = кол-во элементов
};

double GetData(EA *ea,int id,int shift,DataFrame *table)
{
   switch ((ENUM_SERIES)id) {
      case FAST_MA:
         return table[FAST_MA][shift]=iMA(ea.Symbol,ea.Period,FAST_MA_PERIOD,0,FAST_MA_METHOD,FAST_MA_PRICE,shift);
      case SLOW_MA:
         return table[SLOW_MA][shift]=iMA(ea.Symbol,ea.Period,SLOW_MA_PERIOD,0,SLOW_MA_METHOD,SLOW_MA_PRICE,shift);
      case SIGNAL_BUY:
         return table[SIGNAL_BUY][shift]=table.CrossedUp(FAST_MA,SLOW_MA,shift);
      break;
      case SIGNAL_SELL:
         return table[SIGNAL_SELL][shift]=table.CrossedDn(FAST_MA,SLOW_MA,shift);
      break;
      // Расчёт уровней трала
      case UPPER_FRACTAL:
         // верхний фрактал. уровень по которому тралятся sell
         return table[UPPER_FRACTAL][shift]=iFractal(ea.Symbol,ea.Period,MODE_UPPER,shift+2);
      case LOWER_FRACTAL:
         return table[UPPER_FRACTAL][shift]=iFractal(ea.Symbol,ea.Period,MODE_LOWER,shift+2);
   }
   return EMPTY_VALUE;
}
int SignalOfCross(EA *ea,int shift,DataFrame *data)
{
   if (FAST_MA_PRICE!=PRICE_OPEN || SLOW_MA_PRICE!=PRICE_OPEN) shift++;
   if (data[SIGNAL_BUY][shift]==1.0)  return OP_BUY;
   if (data[SIGNAL_SELL][shift]==1.0) return OP_SELL;
   return -1;
}
EA *ea=NULL;

int OnInit()
{
   ea = new EA();
   ea.SetupTimeframe(_Symbol,_Period,TOTAL_SERIES,30,GetData);
   ea.SetupSignal(SignalOfCross);

        // укажем начальный стоп-лосс ордеров и уровни для тралов 
   ea.SetupStopLoss(STOPLOSS_POINTS,LOWER_FRACTAL,UPPER_FRACTAL);
   // и заодно тейк-профит
   ea.SetupTakeProfit(TAKEPROFIT_POINTS);
   // остальная часть одинакова для всех советников
   //................
}


 
Maxim Kuznetsov:

È già difficile guardare il codice in questo modo. Scrivere in modo semplice è un compito difficile. La concisione è importante, ma anche con essa la semplicità può facilmente sfuggire.

La tua opinione sul tuo codice, come la mia opinione sul mio, è molto soggettiva. Gli osservatori dall'esterno possono dire molto più obiettivamente se è complicato o semplice.

Come osservatore del vostro codice - complicato.

 
fxsaber:

È già difficile guardare il codice in questo modo. Scrivere in modo semplice è un compito difficile. La concisione è importante, ma anche con essa la semplicità può facilmente sfuggire.

La tua opinione sul tuo codice, come la mia opinione sul mio, è molto soggettiva. Gli osservatori dall'esterno possono dire molto più obiettivamente se è complicato o semplice.

Come osservatore del vostro codice - complicato.

Suggerisci una voce più chiara e concisa solo per il caso d'uso. O modifiche a quello attuale.

Questo è il punto più difficile - ed è quello che più spesso viene offerto alla discussione.




 
Maxim Kuznetsov:

Hanno suggerito una notazione più lucida e concisa solo per i casi d'uso. O modifiche a quello attuale.

Questo è il punto più difficile - e proprio quello che viene maggiormente proposto per la discussione.

Non lo suggerisco, perché non so e non capisco nemmeno perché sia necessario. MQL4 difficilmente sarà più semplice di MQL4 per un osservatore esterno. Gli sviluppatori di MQL4 hanno brillantemente trovato un'architettura semplice.

 

Cosa vuoi ottenere? Per essere onesto, non capisco. All'inizio ho pensato che fosse previsto un framework, ma no, nessuna classe wrapper per indicatori, ordini, algoritmi standard di decisione, niente. Anche se è molto più leggibile questo costrutto: fast.Get(2)>=slow.Get(1); (è solo per fare un esempio), ma la dichiarazione:

CMA fast=nuovo CMA(NULL,0,12,...);

CMA slow=nuovo CMA(NULL,0,100,...);

Questo è qualcosa di cui possiamo discutere, mentre tu, IMHO, stai calpestando il punto.

 
fxsaber:

Come osservatore del vostro codice - difficile.

Sono d'accordo, è molto difficile leggere il tuo codice, anche se conosci il linguaggio.