What is a good EA? - page 4

 
Sopheak Khlot #:

Good EA won't trade martingale or grid. It opens trade with TP/SL with a proper risk control. Last but not least, it trades a profitable strategy that provide the high winning rate.

I completely agree with you. Indeed, a good trading advisor will never be based on the Martingale method or a grid strategy.
 
Anatolii Khlenov #:
I completely agree with you. Indeed, a good trading advisor will never be based on the Martingale method or a grid strategy.

Regarding Martingale, I 100% agree.

Grid is a bit of broad term. At the end of the day, a grid is merely horizontal, vertical, or both horizontal and vertical lines on a chart. A bipolarly opposite EA to Martingale is Anti-Martingale. This too is based on a horizontal grid. It also has a bipolarly opposite value because it stacks trades floating in profit. Alternatively known as pyramiding--because the contract/lot size traded is progressively reduced rather than multiplied. As a caveat, a large amount is starting capital is required in order to trade it.

 
Ryan L Johnson #:

Regarding Martingale, I 100% agree.

Grid is a bit of broad term. At the end of the day, a grid is merely horizontal, vertical, or both horizontal and vertical lines on a chart. A bipolarly opposite EA to Martingale is Anti-Martingale. This too is based on a horizontal grid. It also has a bipolarly opposite value because it stacks trades floating in profit. Alternatively known as pyramiding--because the contract/lot size traded is progressively reduced rather than multiplied. As a caveat, a large amount is starting capital is required in order to trade it.

Hello, Ryan. I agree. In my opinion, if you add a grid to a good trend-following EA, you'll likely end up with a good robot. But to do that, I think you first need to create a good trend-following EA.
[Deleted]  

I written a code based on OP idea and trade history. This code is just assumption. 


//+------------------------------------------------------------------+
//|                                                  mimann Idea.mq4 |
//|                             https://www.mql5.com/en/forum/500337 |
//+------------------------------------------------------------------+
#property link      "https://www.mql5.com/en/forum/500337"
#property version   "1.00"
#property strict

//--- Input parameters
input string   Indicator_Settings      = "--- Indicator Settings ---"; // Indicator Settings
extern int    BB_Period = 20;             // Bollinger Bands period
extern double BB_Deviation = 1.5;         // Bollinger Bands deviation
extern int    SMA_Period = 50;            // SMA period for crossover
extern int BandWidth_Min = 200;     // Minimum BB bandwidth
extern int Diff_Compare = 70;         // Minimum pip difference for crossover
extern int PreviousCandle = 3; //Previous Candle for CrossOver

input string   Order_Settings      = "--- Order Settings ---"; // Order Settings
extern double LotSize = 1.0;              // Fixed lot size
extern int    StopLoss = 100;              // Stop Loss in pips
extern int    TakeProfit = 500;           // Take Profit in pips
extern int    TrailingStop = 100;          // Trailing Stop in pips
extern int    TimeExit = 300;             // Time exit in seconds (5 minutes)

input string   EA_Settings      = "--- EA Settings ---"; // EA Settings
extern int    MagicNumber = 54321;        // Magic number for trades


// Global variables
datetime LastBarTime = 0;                 // To detect new bar

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
   
   return(INIT_SUCCEEDED);
  }

//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
   
  }

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
// Check for new bar to avoid multiple signals per bar
   if(Time[0] == LastBarTime)
      return;
   LastBarTime = Time[0];

// Manage existing positions first
   ManagePositions();

// Check for entry signal if no position open
   if(!HasOpenPosition())
     {
      CheckForEntry();
     }
  }

//+------------------------------------------------------------------+
//| Check for entry signal                                           |
//+------------------------------------------------------------------+
void CheckForEntry()
  {
// Get indicator values
   double sma_previous, bb_middle_previous;
   double bb_middle_current = iBands(NULL, 0, BB_Period, BB_Deviation, 0, PRICE_CLOSE, MODE_MAIN, 0);
   double sma_current = iMA(NULL, 0, SMA_Period, 0, MODE_SMA, PRICE_CLOSE, 0);

// Calculate BB bandwidth (relative: (upper - lower) / middle)
   double bb_upper_current = iBands(NULL, 0, BB_Period, BB_Deviation, 0, PRICE_CLOSE, MODE_UPPER, 0);
   double bb_lower_current = iBands(NULL, 0, BB_Period, BB_Deviation, 0, PRICE_CLOSE, MODE_LOWER, 0);
   double bandwidth = MathAbs(bb_upper_current - bb_lower_current);

//Check previous for BUY
   bool CrossOverPrevious_Buy = false;
   for(int i = 1; i <= PreviousCandle; i++)
     {
      sma_previous = iMA(NULL, 0, SMA_Period, 0, MODE_SMA, PRICE_CLOSE, i);
      bb_middle_previous = iBands(NULL, 0, BB_Period, BB_Deviation, 0, PRICE_CLOSE, MODE_MAIN, i);

      if(sma_previous <= bb_middle_previous)
        {
         CrossOverPrevious_Buy = true;
         break;
        }
     }

// Crossover condition: SMA crosses above BB middle
   bool crossover_up = (sma_current > bb_middle_current) && (CrossOverPrevious_Buy) && (Bid > sma_current || Ask > sma_current);

// Diff check: current difference in pips
   double diff_pips_buy = MathAbs(sma_current - bb_middle_current);

// Entry filters for BUY
   if(crossover_up && bandwidth >= BandWidth_Min * Point && diff_pips_buy >= Diff_Compare * Point)
     {
      if(StopLoss <= 0 || TakeProfit <= 0)
         return;
      // Calculate SL and TP
      double sl = Ask - StopLoss * Point;
      double tp = Ask + TakeProfit * Point;

      // Open buy order
      int ticket = OrderSend(Symbol(), OP_BUY, LotSize, Ask, 3, sl, tp, "SMA crosses above BB middle", MagicNumber, 0, clrGreen);

      if(ticket > 0)
        {
         Print("Buy order opened: Ticket=", ticket, " at ", Ask);
        }
      else
        {
         Print("Error opening buy order: ", GetLastError());
        }
     }

//Check previous for SELL
   bool CrossOverPrevious_Sell = false;
   for(int i = 1; i <= PreviousCandle; i++)
     {
      sma_previous = iMA(NULL, 0, SMA_Period, 0, MODE_SMA, PRICE_CLOSE, i);
      bb_middle_previous = iBands(NULL, 0, BB_Period, BB_Deviation, 0, PRICE_CLOSE, MODE_MAIN, i);

      if(sma_previous >= bb_middle_previous)
        {
         CrossOverPrevious_Sell = true;
         break;
        }
     }

// Crossover condition: SMA crosses below BB middle
   bool crossover_down = (sma_current < bb_middle_current) && (CrossOverPrevious_Sell) && (Bid < sma_current || Ask < sma_current);

// Diff check: current difference in pips
   double diff_pips_sell = MathAbs(bb_middle_current - sma_current);

// Entry filters for SELL
   if(crossover_down && bandwidth >= BandWidth_Min * Point && diff_pips_sell >= Diff_Compare * Point)
     {
      if(StopLoss <= 0 || TakeProfit <= 0)
         return;
      // Calculate SL and TP
      double sl = Bid + StopLoss * Point;
      double tp = Bid - TakeProfit * Point;

      // Open sell order
      int ticket = OrderSend(Symbol(), OP_SELL, LotSize, Bid, 3, sl, tp, "SMA crosses below BB middle", MagicNumber, 0, clrRed);

      if(ticket > 0)
        {
         Print("Sell order opened: Ticket=", ticket, " at ", Bid);
        }
      else
        {
         Print("Error opening sell order: ", GetLastError());
        }
     }
  }

//+------------------------------------------------------------------+
//| Manage open positions                                            |
//+------------------------------------------------------------------+
void ManagePositions()
  {
   for(int i = OrdersTotal() - 1; i >= 0; i--)
     {
      if(OrderSelect(i, SELECT_BY_POS) && OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber)
        {
         // Time exit (common for both)
         if(TimeCurrent() - OrderOpenTime() > TimeExit)
           {
            CloseOrder(OrderTicket(), "Time Exit");
            continue;
           }

         if(OrderType() == OP_BUY)
           {
            // Reverse signal exit for BUY
            double bb_middle_current = iBands(NULL, 0, BB_Period, BB_Deviation, 0, PRICE_CLOSE, MODE_MAIN, 0);
            double bb_middle_previous = iBands(NULL, 0, BB_Period, BB_Deviation, 0, PRICE_CLOSE, MODE_MAIN, 1);
            double sma_current = iMA(NULL, 0, SMA_Period, 0, MODE_SMA, PRICE_CLOSE, 0);
            double sma_previous = iMA(NULL, 0, SMA_Period, 0, MODE_SMA, PRICE_CLOSE, 1);

            bool crossover_down = (sma_current < bb_middle_current) && (sma_previous >= bb_middle_previous);
            if(crossover_down)
              {
               CloseOrder(OrderTicket(), "Reverse Signal");
               continue;
              }

            // Trailing stop for BUY
            if(Bid - OrderOpenPrice() > TrailingStop * Point)
              {
               double new_sl = Bid - TrailingStop * Point;
               if(new_sl > OrderStopLoss())
                 {
                  bool modified = OrderModify(OrderTicket(), OrderOpenPrice(), new_sl, OrderTakeProfit(), 0, clrBlue);
                  if(modified)
                     Print("Trailing stop updated to: ", new_sl);
                  else
                     Print("Error modifying order: ", GetLastError());
                 }
              }
           }
         else if(OrderType() == OP_SELL)
           {
            // Reverse signal exit for SELL
            double bb_middle_current = iBands(NULL, 0, BB_Period, BB_Deviation, 0, PRICE_CLOSE, MODE_MAIN, 0);
            double bb_middle_previous = iBands(NULL, 0, BB_Period, BB_Deviation, 0, PRICE_CLOSE, MODE_MAIN, 1);
            double sma_current = iMA(NULL, 0, SMA_Period, 0, MODE_SMA, PRICE_CLOSE, 0);
            double sma_previous = iMA(NULL, 0, SMA_Period, 0, MODE_SMA, PRICE_CLOSE, 1);

            bool crossover_up = (sma_current > bb_middle_current) && (sma_previous <= bb_middle_previous);
            if(crossover_up)
              {
               CloseOrder(OrderTicket(), "Reverse Signal");
               continue;
              }

            // Trailing stop for SELL
            if(OrderOpenPrice() - Ask > TrailingStop * Point)
              {
               double new_sl = Ask + TrailingStop * Point;
               if(new_sl < OrderStopLoss() || OrderStopLoss() == 0)
                 {
                  bool modified = OrderModify(OrderTicket(), OrderOpenPrice(), new_sl, OrderTakeProfit(), 0, clrBlue);
                  if(modified)
                     Print("Trailing stop updated to: ", new_sl);
                  else
                     Print("Error modifying order: ", GetLastError());
                 }
              }
           }
        }
     }
  }

//+------------------------------------------------------------------+
//| Check if there is an open position                               |
//+------------------------------------------------------------------+
bool HasOpenPosition()
  {
   for(int i = 0; i < OrdersTotal(); i++)
     {
      if(OrderSelect(i, SELECT_BY_POS) && OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber)
        {
         return true;
        }
     }
   return false;
  }

//+------------------------------------------------------------------+
//| Close order                                                      |
//+------------------------------------------------------------------+
void CloseOrder(int ticket, string reason)
  {
   if(OrderSelect(ticket, SELECT_BY_TICKET))
     {
      double close_price = (OrderType() == OP_BUY) ? Bid : Ask;
      bool closed = OrderClose(ticket, OrderLots(), close_price, 3, clrRed);
      if(closed)
        {
         Print("Order closed: Ticket=", ticket, " Reason=", reason);
        }
      else
        {
         Print("Error closing order: ", GetLastError());
        }
     }
  }
//+------------------------------------------------------------------+
 
Anatolii Khlenov #:
Hello, Ryan. I agree. In my opinion, if you add a grid to a good trend-following EA, you'll likely end up with a good robot. But to do that, I think you first need to create a good trend-following EA.

One would certainly tend to think so, including me, but after I added ATR, MA, and MA crossover filters to an Anti-Martingale EA, that proved counterproductive.

To be clear, I used a stepped levels indicator--the sequential steps of which you could say determine directional bias. Those steps are best used alone.

 
Ryan L Johnson #:

One would certainly tend to think so, including me, but after I added ATR, MA, and MA crossover filters to an Anti-Martingale EA, that proved counterproductive.

To be clear, I used a stepped levels indicator--the sequential steps of which you could say determine directional bias. Those steps are best used alone.

At first glance, ATR and MA seem mathematically sound, but I'm skeptical of them. I generally assume that we know what was and what is currently happening, but we don't know what will happen in 1 second, 1 minute, 1 day, and so on. That's the market. Therefore, I try to base my strategy on knowledge of history and the current situation. Assumptions about what might happen in 1 second based on all sorts of theories are too much of a luxury, which in trading leads to big losses. Therefore, I'm trying to develop my own theory based on mathematical methods. How I'll succeed, I can't say. Time will tell.
 
Anatolii Khlenov #:
At first glance, ATR and MA seem mathematically sound, but I'm skeptical of them. I generally assume that we know what was and what is currently happening, but we don't know what will happen in 1 second, 1 minute, 1 day, and so on. That's the market. Therefore, I try to base my strategy on knowledge of history and the current situation. Assumptions about what might happen in 1 second based on all sorts of theories are too much of a luxury, which in trading leads to big losses. Therefore, I'm trying to develop my own theory based on mathematical methods. How I'll succeed, I can't say. Time will tell.

Hi Anatolii,


Based on my own limited experience, but having worked as a programmer, I agree with you.

It's the randomness of the incoming ticks I find hard to program, even in a downtrend you can get a small uptrend which can trigger a stop loss, increasing the stop loss is pointless.

You end up with a reactive program which can't handle all conditions.

I think you are right in looking at trying to find a method of predicting the overall trend using math.

What I miss is having a database you can select and process, that's where my expertise was.

It's interesting though, keeps me busy.

regerds

Mike

 
mimann #:

Hi Anatolii,


Based on my own limited experience, but having worked as a programmer, I agree with you.

It's the randomness of the incoming ticks I find hard to program, even in a downtrend you can get a small uptrend which can trigger a stop loss, increasing the stop loss is pointless.

You end up with a reactive program which can't handle all conditions.

I think you are right in looking at trying to find a method of predicting the overall trend using math.

What I miss is having a database you can select and process, that's where my expertise was.

It's interesting though, keeps me busy.

regerds

Mike

Hi, Mike. I sincerely wish you and me success. Indeed, in my opinion, robotics lacks mathematics and relies heavily on pure programming and computational work, which requires significant computing resources. And resources are always limited. Sooner or later, we'll reach a dead end. It's logical to assume that the future of artificial intelligence lies in constructing mathematical objects, not in mindlessly building networks.
 
Anatolii Khlenov #:
Hi, Mike. I sincerely wish you and me success. Indeed, in my opinion, robotics lacks mathematics and relies heavily on pure programming and computational work, which requires significant computing resources. And resources are always limited. Sooner or later, we'll reach a dead end. It's logical to assume that the future of artificial intelligence lies in constructing mathematical objects, not in mindlessly building networks.
It is all random,  for retail traders you are at the  mercy  of  banks etc , the whole retail space was developed to get a collective of mugs and take their cash .The act should be random the management of it should be math based and law of avg and then with patience and discipline you can grind a profit . My biggest winners were all random and the emotional disengage is a revelation . 
 
Victor Paul Hamilton #:
It is all random,  for retail traders you are at the  mercy  of  banks etc , the whole retail space was developed to get a collective of mugs and take their cash .The act should be random the management of it should be math based and law of avg and then with patience and discipline you can grind a profit . My biggest winners were all random and the emotional disengage is a revelation . 
Hello. Everything you've written is true. I'd just like to point out that any random process has its own patterns. Only mathematical tools can help us uncover these patterns and get closer to reality. Those who succeed in this will have a competitive advantage.