Less code, more action... writing an EA - page 4

 
Maxim Kuznetsov:
Why did you take down the post about the next step?

Please put your arrogance to the test. And read the rules of the resource.

You all can write in the forum posts and in the description in KodoBaz.

 
Maxim Kuznetsov:
Why did you take down the post about the next step?

Saw the post, didn't see anything criminal. I guess I wasn't looking hard enough.

 
Maxim Kuznetsov:

Of course the balance is going down. What do you expect from "two MAs crossing"?


You can take a different basis for the EA - the MAs are far from the best option.

 
aleger:

You can take a different basis for the EA - mashki is far from the best option.

If you look a bit more carefully, you'll notice that you can already implement quite a few things :-)

So it turns out the following:

* application programmer (library user) declared that he/she has micro-excel with several columns (in use-case these are FAST_MA,SLOW_MA,SIGNAL_BUY,SIGNAL_SELL)

* and sketched a function how he knows how to calculate individual cells. In the example he referred to iMA.

* at the same time he can freely access other cells of this table (DataFrame will break sequences if possible)

* and separately the user wrote the function "check row values and if it's time to trade"

Obviously, this is enough for the EA to start trading. And the strategy can be changed very flexibly - anything you can think of as a table calculation is possible.
The other thing is that this is only the first half-step :-) so far, the EA is trading like the monkey-shifter, only with the minimum lot, on one symbol and from one timeframe.

 

In the first two parts, we obtained an Expert Advisor, which can execute the most simple strategy, commonly described as "monkeys" or "flip by signal".
The signals themselves are programmed very simply, almost like in Excel :-)

It's time to teach the Expert Advisor a little more. At least put StopLoss and trawl it.

Supplement the artistic description of the strategy with the phrase "Stop Loss is placed on the distance STOPLOSS_POINTS and trailing by fractals". We also introduce changes in the use-case described above:

  • new EA parameter input int STOPLOSS_POINTS=100;
  • add two calculated fields UPPER_FRACTAL,LOWER_FRACTAL into ENUM_SERIES
  • and in the GetData function add two "case:" to calculate them

and provide the user with a function (method of class EA), to set up the EA. The simplest entry can be seen as

SetStopLoss(STOPLOSS_POINTS,LOWER_FRACTAL,UPPER_FRACTAL);

reads "sets Stop Loss at a specified distance, and trawls buy by column LOWER_FRACTAL,sell by UPPER_FRACTAL"; I think the method has an obvious name and its syntax is more or less clear.

Hypothetical user made a lot of gestures (declared input, added two columns and called function settings), we'll develop the library so that his actions will lead to the expected result. We will also have to develop tabular calculations and lay the foundation for message/event mechanism.

In copy-paste, superfluous comments and MQL5 code have been removed for the compactness

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:

It's already hard to look at code like this. Writing outwardly simple is a difficult task. Conciseness is important, but even with it, simplicity can easily escape.

Your opinion of your code, like my opinion of mine, is very subjective. Observers from the outside can tell much more objectively whether it's complicated or simple.

As an observer of your code - complicated.

 
fxsaber:

It's already hard to look at code like this. Writing outwardly simple is a difficult task. Conciseness is important, but even with it, simplicity can easily escape.

Your opinion of your code, like my opinion of mine, is very subjective. Observers from the outside can tell much more objectively whether it's complicated or simple.

As an observer of your code - complicated.

Suggest a more clear and concise entry just for use-case. Or edits to the current one.

This is the most difficult point - and it's the one that's mostly offered for discussion.




 
Maxim Kuznetsov:

They have suggested a more lucid and concise notation just for use-case. Or edits to the current one.

This is the most difficult point - and just the one that is mostly proposed for discussion.

I won't suggest it, as I don't know and don't even understand why it's needed. MQL4 will hardly be simpler than MQL4 for an outside observer. The MQL4 developers have brilliantly hit upon a simple architecture.

 

What do you want to get out of it? To be honest, I don't understand. At first I thought a la framework was intended, but no, no wrapper classes for indicators, orders, standard algorithms of decision making, nothing. Although much more readable is this construct: fast.Get(2)>=slow.Get(1); (it's just for the sake of example), but the declaration:

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

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

That's something we can discuss, while you, IMHO, are stomping on the spot.

 
fxsaber:

As an observer of your code - difficult.

I agree, it is very difficult to read your code, even if you know the language.

Reason: