Hacer que los EAs no cierren por indicador.

 

Muy buenas,

¿Alguien sabe como hacer que las operaciones no se cierren por indicadores? Ya que no he visto la opción por más que la he buscado.

Gracias, atte.

 
sergiogj_:

Muy buenas,

¿Alguien sabe como hacer que las operaciones no se cierren por indicadores? Ya que no he visto la opción por más que la he buscado.

Gracias, atte.

Buenos dias,

entiendo su pregunta, pero en realidad no tiene mucho sentido, puesto que el cierre será como usted quiera que sea, bien por indicadores, por TP y SL, etc.

Muestre sus intentos (código) para que podamos ayudarle en base a algo concreto, no podemos codificar por usted con un simple deseo.

Importante que utilice el botón 'Código' cuando adjunte código en el foro.

 

 
Miguel Angel Vico Alba #:

Buenos dias,

entiendo su pregunta, pero en realidad no tiene mucho sentido, puesto que el cierre será como usted quiera que sea, bien por indicadores, por TP y SL, etc.

Muestre sus intentos (código) para que podamos ayudarle en base a algo concreto, no podemos codificar por usted con un simple deseo.

Importante que utilice el botón 'Código' cuando adjunte código en el foro.

 

Buenas Miguel Ángel,


Tengo estrategias que tienen SL y TP pero aún así cierran por indicadores, y al crear los EAs desde la página me gustaría saber si puedo modificarlo. O si es posible después, no importa.

Dicho esto adjunto el código de uno de ellos:

static input string _Properties_ = "------"; // --- Expert Properties ---
static input int    Magic_Number = 1372214169; // Magic number
double Entry_Amount;
input double MaxRiskPerTrade = 1;
input int Maximum_Lots = 5;
input double Minimum_Lots = 0.01;
       input int    Stop_Loss    =       21; // Stop Loss   (pips)
       input int    Take_Profit  =       22; // Take Profit (pips)

static input string ___0______   = "------"; // --- Bollinger Bands ---
       input int    Ind0Param0   =        5; // Period
       input double Ind0Param1   =     2.34; // Deviation

static input string ___1______   = "------"; // --- Directional Indicators ---
       input int    Ind1Param0   =       35; // Period


// "Entry protections" prevents new entry if a protection is activated
static input string Entry_prot__ = "------"; // --- Entry Protections ---
static input int    Max_Spread   =        0; // Max spread (points)
static input int    Max_OpenPos  =        0; // Max open positions
static input double Max_OpenLots =        0; // Max open lots

// "Account protections" stops the expert if a protection is activated
static input string Account_prot = "------"; // --- Account Protections ---
static input int    MaxDailyLoss =        0; // Maximum daily loss (currency)
static input int    Min_Equity   =        0; // Minimum equity (currency)
static input int    Max_Equity   =        0; // Maximum equity (currency)

static input string _NewsFilter_ = "------"; // --- News Filter ---
enum NewsFilterPriority
  {
   News_filter_disabled,       // News filter disabled
   High_news_filter,           // High news filter
   Medium_and_High_news_filter // Medium and High news filter
  };
static input NewsFilterPriority News_Priority = News_filter_disabled;           // News priority
static input string News_Currencies_Txt    = "USD,EUR,JPY,GBP,CAD,AUD,CHF,NZD"; // News currencies
static input int    newsFilterBeforeMedium = 2; // Before Medium news (minutes)
static input int    newsFilterAfterMedium  = 2; // After Medium news (minutes)
static input int    newsFilterBeforeHigh   = 2; // Before High news (minutes)
static input int    newsFilterAfterHigh    = 5; // After High news (minutes)

static input string __Stats_____ = "------"; // --- Stats ---
static input bool   Pos_Stat     =     true; // Position stats
static input bool   Expert_Stat  =     true; // Expert stats
static input bool   Account_Stat =    false; // Account stats

#define TRADE_RETRY_COUNT   4
#define TRADE_RETRY_WAIT  100
#define OP_FLAT            -1

string TAG_LINE = "An Expert Advisor from Expert Advisor Studio";

// Session time is set in seconds from 00:00
int  sessionSundayOpen          =     0; // 00:00
int  sessionSundayClose         = 86400; // 24:00
int  sessionMondayThursdayOpen  =     0; // 00:00
int  sessionMondayThursdayClose = 86400; // 24:00
int  sessionFridayOpen          =     0; // 00:00
int  sessionFridayClose         = 86400; // 24:00
bool sessionIgnoreSunday        = false;
bool sessionCloseAtSessionClose = false;
bool sessionCloseAtFridayClose  = false;

const double sigma = 0.000001;

int    posType       = OP_FLAT;
int    posTicket     = 0;
double posLots       = 0;
double posStopLoss   = 0;
double posTakeProfit = 0;
double posProfit     = 0;
double posPriceOpen  = 0;
double posPriceCurr  = 0;

datetime lastStatsUpdate = 0;
datetime barTime;
double   pip;
double   stopLevel;
bool     isTrailingStop=false;
bool     setProtectionSeparately = false;

int    maxRectangles = 0;
int    maxLabels     = 0;
int    posStatCount  = 0;
double posStatLots   = 0;
double posStatProfit = 0;

string accountProtectionMessage = "";
string entryProtectionMessage   = "";

struct NewsRecord
  {
   datetime          time;
   string            priority;
   string            currency;
   string            title;
  };

NewsRecord newsRecords[];
string   newsCurrencies[];
datetime lastNewsUpdate = 0;
string   loadNewsError  = "";
bool     isNewsFeedOk   = true;

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int OnInit(void)
  {
   barTime         = Time[0];
   stopLevel       = MarketInfo(_Symbol, MODE_STOPLEVEL);
   pip             = GetPipValue();
   isTrailingStop  = isTrailingStop && Stop_Loss > 0;
   lastStatsUpdate = 0;

   Comment("");
   UpdatePosition();

   ParseNewsCurrenciesText();
   lastNewsUpdate = TimeCurrent();
   if(!MQLInfoInteger(MQL_TESTER))
      LoadNews();

   UpdateStats();

   return ValidateInit();
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
   DeleteObjects();

   if(accountProtectionMessage != "")
      Comment(accountProtectionMessage);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void DeleteObjects(void)
  {
   if(maxRectangles == 1)
      ObjectDelete(0, "Stats_background");
   for(int i = 0; i < maxLabels; i += 1)
      ObjectDelete(0, "label" + IntegerToString(i));
   maxRectangles = 0;
   maxLabels     = 0;
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnTick()
{
int margin=(int) MarketInfo(_Symbol,MODE_MARGINREQUIRED);
Entry_Amount=(AccountBalance()*MaxRiskPerTrade/1000)/(Stop_Loss);
Entry_Amount = NormalizeEntrySize(Entry_Amount);
if(Time[0]>barTime)
{
barTime=Time[0];
OnBar();
}
}
double NormalizeEntrySize(double size) {
double minlot = MarketInfo(_Symbol, MODE_MINLOT);
double maxlot = MarketInfo(_Symbol, MODE_MAXLOT);
double lotstep = MarketInfo(_Symbol, MODE_LOTSTEP);
if (size <= minlot)
size = minlot;
if (size <=Minimum_Lots)
size = Minimum_Lots;
if (size >= maxlot)
size = maxlot;
if (size >=Maximum_Lots)
size = Maximum_Lots;
size = NormalizeDouble(size, _Digits);
return (size);
}
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnBar(void)
  {
   UpdatePosition();

   if(posType != OP_FLAT && IsForceSessionClose())
     {
      ClosePosition();
      return;
     }

   if(IsOutOfSession())
      return;

   if(posType != OP_FLAT)
     {
      ManageClose();
      UpdatePosition();
     }

   if(posType != OP_FLAT && isTrailingStop)
     {
      double trailingStop = GetTrailingStopPrice();
      ManageTrailingStop(trailingStop);
      UpdatePosition();
     }

   int entrySignal = GetEntrySignal();

   if ((posType == OP_BUY  && entrySignal == OP_SELL) ||
       (posType == OP_SELL && entrySignal == OP_BUY ))
     {
      ClosePosition();

      // Hack to prevent MT bug https://forexsb.com/forum/post/73434/#p73434
      int repeatCount = 80;
      int delay       = 50;
      for (int i = 0; i < repeatCount; i++)
      {
         UpdatePosition();
         if (posType == OP_FLAT) break;
         Sleep(delay);
      }
     }

   if(posType == OP_FLAT && entrySignal != OP_FLAT)
     {
      OpenPosition(entrySignal);
      UpdatePosition();
     }
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void UpdatePosition(void)
  {
   posType       = OP_FLAT;
   posTicket     = 0;
   posLots       = 0;
   posProfit     = 0;
   posStopLoss   = 0;
   posTakeProfit = 0;
   posPriceOpen  = 0;
   posPriceCurr  = 0;

   for(int pos = OrdersTotal() - 1; pos >= 0; pos -= 1)
     {
      if(OrderSelect(pos, SELECT_BY_POS) &&
         OrderSymbol()      == _Symbol   &&
         OrderMagicNumber() == Magic_Number)
        {
         posType       = OrderType();
         posTicket     = OrderTicket();
         posLots       = OrderLots();
         posProfit     = OrderProfit();
         posStopLoss   = OrderStopLoss();
         posTakeProfit = OrderTakeProfit();
         posPriceOpen  = NormalizeDouble(OrderOpenPrice(),  _Digits);
         posPriceCurr  = NormalizeDouble(OrderClosePrice(), _Digits);
         break;
        }
     }
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int GetEntrySignal(void)
  {
   // Bollinger Bands (Close, 5, 2.34)
   double ind0upBand1 = iBands(NULL, 0, Ind0Param0, Ind0Param1, 0, PRICE_CLOSE, MODE_UPPER, 1);
   double ind0dnBand1 = iBands(NULL, 0, Ind0Param0, Ind0Param1, 0, PRICE_CLOSE, MODE_LOWER, 1);
   double ind0upBand2 = iBands(NULL, 0, Ind0Param0, Ind0Param1, 0, PRICE_CLOSE, MODE_UPPER, 2);
   double ind0dnBand2 = iBands(NULL, 0, Ind0Param0, Ind0Param1, 0, PRICE_CLOSE, MODE_LOWER, 2);
   bool   ind0long    = Open(0) < ind0dnBand1 - sigma && Open(1) > ind0dnBand2 + sigma;
   bool   ind0short   = Open(0) > ind0upBand1 + sigma && Open(1) < ind0upBand2 - sigma;

   bool canOpenLong  = ind0long;
   bool canOpenShort = ind0short;

   return canOpenLong  && !canOpenShort ? OP_BUY
        : canOpenShort && !canOpenLong  ? OP_SELL
        : OP_FLAT;
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void ManageClose(void)
  {
   // Directional Indicators (35)
   double ind1val1  = iADX(NULL, 0, Ind1Param0, PRICE_CLOSE, 1, 1);
   double ind1val2  = iADX(NULL ,0 ,Ind1Param0, PRICE_CLOSE, 2, 1);
   double ind1val3  = iADX(NULL, 0, Ind1Param0, PRICE_CLOSE, 1, 2);
   double ind1val4  = iADX(NULL ,0 ,Ind1Param0, PRICE_CLOSE, 2, 2);
   bool   ind1long  = ind1val1 < ind1val2 - sigma && ind1val3 > ind1val4 + sigma;
   bool   ind1short = ind1val1 > ind1val2 + sigma && ind1val3 < ind1val4 - sigma;

   if((posType == OP_BUY  && ind1long) ||
        (posType == OP_SELL && ind1short) )
      ClosePosition();
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OpenPosition(const int command)
  {
   entryProtectionMessage = "";
   const int spread = (int)((Ask() - Bid()) / _Point);
   if(Max_OpenPos  > sigma && posStatCount > Max_OpenPos)
      entryProtectionMessage += StringFormat("Protection: Max open positions: %d, current: %d\n",
                                             Max_OpenPos, posStatCount);
   if(Max_OpenLots > sigma && posStatLots > Max_OpenLots)
      entryProtectionMessage += StringFormat("Protection: Max open lots: %.2f, current: %.2f\n",
                                             Max_OpenLots, posStatLots);
   if(Max_Spread > sigma && spread > Max_Spread)
      entryProtectionMessage += StringFormat("Protection: Max spread: %d, current: %d\n",
                                             Max_Spread, spread);

   const int newsIndex = NewsFilterActive();
   if(newsIndex > -1)
     {
      const NewsRecord newsRecord = newsRecords[newsIndex];
      const datetime timeShift = (datetime) MathRound((TimeLocal() - TimeGMT()) / 3600.0) * 3600;
      const string   priority  = newsRecord.priority == "high" ? "[high]" : "[med]";
      entryProtectionMessage  += StringFormat("News filter: %s %s %s %s\n",
                                              priority,
                                              TimeToString(newsRecord.time + timeShift,
                                                    TIME_DATE | TIME_MINUTES),
                                              newsRecord.currency,
                                              newsRecord.title);
     }

   if(entryProtectionMessage != "")
     {
      entryProtectionMessage = TimeToString(TimeCurrent()) + " " +
                               "Entry order was canceled:\n" +
                               entryProtectionMessage;
      return;
     }

   for(int attempt = 0; attempt < TRADE_RETRY_COUNT; attempt++)
     {
      int    ticket     = 0;
      int    lastError  = 0;
      bool   modified   = false;
      string comment    = IntegerToString(Magic_Number);
      color  arrowColor = command == OP_BUY ? clrGreen : clrRed;

      if(IsTradeContextFree())
        {
         const double price      = command == OP_BUY ? Ask() : Bid();
         const double stopLoss   = GetStopLossPrice(command);
         const double takeProfit = GetTakeProfitPrice(command);

         if(setProtectionSeparately)
           {
            // Send an entry order without SL and TP
            ticket = OrderSend(_Symbol, command, Entry_Amount, price, 10, 0, 0, comment, Magic_Number, 0, arrowColor);

            // If the order is successful, modify the position with the corresponding SL and TP
            if(ticket > 0 && (Stop_Loss > 0 || Take_Profit > 0))
               modified = OrderModify(ticket, 0, stopLoss, takeProfit, 0, clrBlue);
           }
         else
           {
            // Send an entry order with SL and TP
            ticket    = OrderSend(_Symbol, command, Entry_Amount, price, 10, stopLoss, takeProfit, comment, Magic_Number, 0, arrowColor);
            lastError = GetLastError();

            // If order fails, check if it is because inability to set SL or TP
            if(ticket <= 0 && lastError == 130)
              {
               // Send an entry order without SL and TP
               ticket = OrderSend(_Symbol, command, Entry_Amount, price, 10, 0, 0, comment, Magic_Number, 0, arrowColor);

               // Try setting SL and TP
               if(ticket > 0 && (Stop_Loss > 0 || Take_Profit > 0))
                  modified = OrderModify(ticket, 0, stopLoss, takeProfit, 0, clrBlue);

               // Mark the expert to set SL and TP with a separate order
               if(ticket > 0 && modified)
                 {
                  setProtectionSeparately = true;
                  Print("Detected ECN type position protection.");
                 }
              }
           }
        }

      if(ticket > 0) break;

      lastError = GetLastError();
      if(lastError != 135 && lastError != 136 && lastError != 137 && lastError != 138)
         break;

      Sleep(TRADE_RETRY_WAIT);
      Print("Open Position retry no: " + IntegerToString(attempt + 2));
     }
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void ClosePosition(void)
  {
   for(int attempt = 0; attempt < TRADE_RETRY_COUNT; attempt++)
     {
      bool closed;
      int lastError = 0;

      if(IsTradeContextFree())
        {
         const double price = posType == OP_BUY ? Bid() : Ask();
         closed    = OrderClose(posTicket, posLots, price, 10, clrYellow);
         lastError = GetLastError();
        }

      if(closed) break;
      if(lastError == 4108) break;

      Sleep(TRADE_RETRY_WAIT);
      Print("Close Position retry no: " + IntegerToString(attempt + 2));
     }
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void ModifyPosition(void)
  {
   for(int attempt = 0; attempt < TRADE_RETRY_COUNT; attempt++)
     {
      bool modified;
      int lastError = 0;

      if(IsTradeContextFree())
        {
         modified  = OrderModify(posTicket, 0, posStopLoss, posTakeProfit, 0, clrBlue);
         lastError = GetLastError();
        }

      if(modified)
         break;

      if(lastError == 4108) break;

      Sleep(TRADE_RETRY_WAIT);
      Print("Modify Position retry no: " + IntegerToString(attempt + 2));
     }
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double GetStopLossPrice(int command)
  {
   if(Stop_Loss == 0) return 0;

   const double delta    = MathMax(pip * Stop_Loss, _Point * stopLevel);
   const double stopLoss = command == OP_BUY ? Bid() - delta : Ask() + delta;

   return NormalizeDouble(stopLoss, _Digits);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double GetTakeProfitPrice(int command)
  {
   if(Take_Profit == 0) return 0;

   const double delta      = MathMax(pip * Take_Profit, _Point * stopLevel);
   const double takeProfit = command == OP_BUY ? Bid() + delta : Ask() - delta;

   return NormalizeDouble(takeProfit, _Digits);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double GetTrailingStopPrice(void)
  {
   const double bid = Bid();
   const double ask = Ask();
   const double spread = ask - bid;
   const double stopLevelPoints = _Point * stopLevel;
   const double stopLossPoints  = pip * Stop_Loss;

   if(posType == OP_BUY)
     {
      const double newStopLoss = High(1) - stopLossPoints;
      if(posStopLoss <= newStopLoss - pip)
         return newStopLoss < bid
                 ? newStopLoss >= bid - stopLevelPoints
                    ? bid - stopLevelPoints
                    : newStopLoss
                 : bid;
     }

   if(posType == OP_SELL)
     {
      const double newStopLoss = Low(1) + spread + stopLossPoints;
      if(posStopLoss >= newStopLoss + pip)
         return newStopLoss > ask
                 ? newStopLoss <= ask + stopLevelPoints
                    ? ask + stopLevelPoints
                    : newStopLoss
                 : ask;
     }

   return posStopLoss;
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void ManageTrailingStop(double trailingStop)
  {
   if((posType == OP_BUY  && MathAbs(trailingStop - Bid()) < _Point) ||
      (posType == OP_SELL && MathAbs(trailingStop - Ask()) < _Point))
     {
      ClosePosition();
      return;
     }

   if( MathAbs(trailingStop - posStopLoss) > _Point )
     {
      posStopLoss = NormalizeDouble(trailingStop, _Digits);
      ModifyPosition();
     }
  }
 
sergiogj_ #:

Buenas Miguel Ángel,

Tengo estrategias que tienen SL y TP pero aún así cierran por indicadores, y al crear los EAs desde la página me gustaría saber si puedo modificarlo. O si es posible después, no importa.

Dicho esto adjunto el código de uno de ellos:

Si está utilizando una web del tipo "generador de EAs", eso lo cambia todo.

De entrada no recibirá ayuda sobre este tipo de código aquí en el foro, ya que esas webs generalmente crean un código inconexo y difícil de descifrar, que ya utilizan plantillas para su creación y realmente la mitad del código suele ser innecesario (paja).

Puede que tenga suerte y alguien decida "descifrar" ese galimatías y ayudarle, pero sinceramente y por experiencia puede decirle que lo dudo.

Por otro lado, tenga en cuenta que aunque le den alguna pista, si usted no sabe programar, ¿De qué vale lo que yo o alguien le podamos decir? ¿Sabrá interpretarlo y hacer los ajustes necesarios, o simplemente pretende que se lo den hecho y alguien pierda más tiempo del que usted le dedicó a hacer ese EA en una web?

Mi recomendación es que no empiece la casa por el tejado, es más sencillo aprender a programar que dedicarle tiempo a crear un EA en una web con multitud de errores que luego no sabrá corregirlos y que además debe cruzar los dedos para que funcione.

 
Miguel Angel Vico Alba #:

Si está utilizando una web del tipo "generador de EAs", eso lo cambia todo.

De entrada no recibirá ayuda sobre este tipo de código aquí en el foro, ya que esas webs generalmente crean un código inconexo y difícil de descifrar, que ya utilizan plantillas para su creación y realmente la mitad del código suele ser innecesario (paja).

Puede que tenga suerte y alguien decida "descifrar" ese galimatías y ayudarle, pero sinceramente y por experiencia puede decirle que lo dudo.

Por otro lado, tenga en cuenta que aunque le den alguna pista, si usted no sabe programar, ¿De qué vale lo que yo o alguien le podamos decir? ¿Sabrá interpretarlo y hacer los ajustes necesarios, o simplemente pretende que se lo den hecho y alguien pierda más tiempo del que usted le dedicó a hacer ese EA en una web?

Mi recomendación es que no empiece la casa por el tejado, es más sencillo aprender a programar que dedicarle tiempo a crear un EA en una web con multitud de errores que luego no sabrá corregirlos y que además debe cruzar los dedos para que funcione.

Muchas gracias, empezaremos la casa por los cimientos.
 
sergiogj_ #Muchas gracias, empezaremos la casa por los cimientos.

Perfecto. Cualquier duda que vaya teniendo sobre la marcha estaremos encantados de ayudarle.