No puedo realizar una nueva compra, necesito ayuda

 

Mi programa ejecuta las compras y ventas correctamente, solo le agregué un código el cual si la posición llega a take profit me hace una pequeña compra, pero cuando lo ejecuto no me abre esa pequeña operación. Si me ayudan o me aconsejan como solucionar este problema se los agradecería mucho

#include <Trade\Trade.mqh>
//Configuracion ALMA
 double pips_TP = 0; // Take profit
 double pips_SL = 0; // Stop loss
input int ALMA_Period1 = 10; // ALMA rápida
input int ALMA_Period2 = 55; // ALMA lenta
input double Sigma = 6.0;    // Parámetro Sigma
input double Offset = 0.85;  // Offset de la distribución Gaussiana
input int Shift = 0;         // Shift en barras

int handle_alma1 = 0;
int handle_alma2 = 0;
double array_alma_fast[];
double array_alma_slow[];
CTrade trade;
datetime date = 0;
double entry = 0;

// ATR PRUEBA
int handle_ATR = 0;
input int ATR_Period = 20;
input double Factor = 3.0;
input ENUM_MA_METHOD MA_Method = MODE_SMA;
input double MA_Period = 20; //Hay que dejarlo en 1 siempre
input ENUM_APPLIED_PRICE IPC = PRICE_CLOSE;
double MA_Buffer[]; 
double UpATRBuffer[]; 
double DnATRBuffer[];

///
input double Lote = 0.1;
double nuevoLote = Lote * 0.75;
double TP2 = 0;


//+------------------------------------------------------------------+
//| OnInit function                                                  |
//+------------------------------------------------------------------+
int OnInit()
{
   // Crear el handle del indicador ALMA con los parámetros necesarios
   handle_alma1 = iCustom(Symbol(), Period(), "Alma indicador", ALMA_Period1,0, Sigma, Offset, Shift,PRICE_CLOSE);
   handle_alma2 = iCustom(Symbol(), Period(), "Alma indicador", 0,ALMA_Period2, Sigma, Offset, Shift,PRICE_CLOSE);
   //ATR HANDLE
   handle_ATR = iCustom(Symbol(), Period(), "kc", MA_Method, MA_Period, ATR_Period, Factor,IPC, Shift);
   
   return INIT_SUCCEEDED;
}

//+------------------------------------------------------------------+
//| OnTick function                                                   |
//+------------------------------------------------------------------+
void OnTick()
{
      //INFO ACTIVO
     double ask = SymbolInfoDouble(_Symbol,SYMBOL_ASK);
     ask = NormalizeDouble(ask,_Digits);
     double bid = SymbolInfoDouble(_Symbol,SYMBOL_BID);
     bid = NormalizeDouble(bid,_Digits);
     
   if (iTime(Symbol(), Period(), 0) != date)
   {
      if (entradaCompra())
      { // Comprar
      Print("Se abrio operacion Alcista");
      if (PositionsTotal() > 0) 
      { 
         for (int i = PositionsTotal() - 1; i >= 0; i--) 
         { 
            if (PositionGetSymbol(i) == Symbol() && PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL) 
            { 
               trade.PositionClose(PositionGetInteger(POSITION_TICKET)); Print("Cerrado por condición de nueva señal de Compra"); 
            } 
         } 
      }
         entry = SymbolInfoDouble(Symbol(), SYMBOL_ASK);
         trade.Buy(Lote, Symbol(), NormalizeDouble(entry, _Digits),
                   NormalizeDouble(pips_SL, _Digits),
                   NormalizeDouble(pips_TP , _Digits), "----LONG realizado----");
         //Cuando la operacion de arriba alcance el Take Profit abre nueva operacion mas pequeña
         for (int P = PositionsTotal()-1;P>=0;P--)
         {
            ulong Ticket = PositionGetTicket(P);
            if (PositionSelectByTicket(Ticket))
            {
            double takeProfit = PositionGetDouble(POSITION_TP);
            ENUM_POSITION_TYPE PosType =(ENUM_POSITION_TYPE) PositionGetInteger(POSITION_TYPE);
            if (PosType == POSITION_TYPE_BUY)
            {
               if (bid >= takeProfit){ // Hay que corregir esto 
                  entry = SymbolInfoDouble(Symbol(), SYMBOL_ASK);
                  if(trade.Buy(0.030, Symbol(), NormalizeDouble(entry, _Digits),0,0, "----LONG NUEVO realizado----"))// Nueva operacion
                  {
                     Print("Nueva orden ejecutada");
                  } 
                  else{Print("Algo salio mal" ,GetLastError());}
               }
            }
            }
         }
      }
      else if (entradaVenta())
      { // Venta
      Print("Se abrio operacion Bajista");
      if (PositionsTotal() > 0) { 
         for (int i = PositionsTotal() - 1; i >= 0; i--) 
         { 
            if (PositionGetSymbol(i) == Symbol() && PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY) 
            { 
               trade.PositionClose(PositionGetInteger(POSITION_TICKET)); 
               Print("Cerrado por condición de nueva señal de Venta"); 
            } 
         } 
      }
         entry = SymbolInfoDouble(Symbol(), SYMBOL_ASK);
         trade.Sell(Lote, Symbol(), NormalizeDouble(entry, _Digits),
                    NormalizeDouble(pips_SL, _Digits),
                    NormalizeDouble(pips_TP, _Digits), "----SHORT realizado----");
      }
      date = iTime(Symbol(), Period(), 0);
   }
}

//+------------------------------------------------------------------+
//| OnDeinit function                                                |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
   if(handle_alma1 != INVALID_HANDLE)
    IndicatorRelease(handle_alma1); if(handle_alma2 != INVALID_HANDLE)
     IndicatorRelease(handle_alma2);
}

//+------------------------------------------------------------------+
//| Función de entrada para compra                                    |
//+------------------------------------------------------------------+
bool entradaCompra()
{
   //Buffer ATR
   ArraySetAsSeries(MA_Buffer, true); 
   ArraySetAsSeries(UpATRBuffer, true); 
   ArraySetAsSeries(DnATRBuffer, true); 
   CopyBuffer(handle_ATR, 0, 0, 3, MA_Buffer); 
   CopyBuffer(handle_ATR, 1, 0, 3, UpATRBuffer); 
   CopyBuffer(handle_ATR, 2, 0, 3, DnATRBuffer);
   pips_SL = DnATRBuffer[0]; // Take profit Dinamico
   pips_TP = UpATRBuffer[0]; // Stop loss Dinamico
   TP2 = pips_TP;
   
   //Buffer ALMA
   ArraySetAsSeries(array_alma_fast, true);
   CopyBuffer(handle_alma1, 0, 1, 2, array_alma_fast);

   ArraySetAsSeries(array_alma_slow, true);
   CopyBuffer(handle_alma2, 1, 1, 2, array_alma_slow);

   if (array_alma_fast[0] > array_alma_slow[0] && array_alma_fast[1] < array_alma_slow[1])
   {
      return true;
   }
   else
   {
      return false;
   }
}

//+------------------------------------------------------------------+
//| Función de entrada para venta                                     |
//+------------------------------------------------------------------+
bool entradaVenta()
{
   //Buffer ATR
   ArraySetAsSeries(MA_Buffer, true); 
   ArraySetAsSeries(UpATRBuffer, true); 
   ArraySetAsSeries(DnATRBuffer, true); 
   CopyBuffer(handle_ATR, 0, 0, 3, MA_Buffer); 
   CopyBuffer(handle_ATR, 1, 0, 3, UpATRBuffer); 
   CopyBuffer(handle_ATR, 2, 0, 3, DnATRBuffer);
   pips_TP = DnATRBuffer[0]; // Take Profit Dinamico
   pips_SL = UpATRBuffer[0]; // Stop Loss Dinamico
   //Buffer ALMA
   ArraySetAsSeries(array_alma_fast, true);
   CopyBuffer(handle_alma1, 0, 1, 2, array_alma_fast);

   ArraySetAsSeries(array_alma_slow, true);
   CopyBuffer(handle_alma2, 1, 1, 2, array_alma_slow);

   if (array_alma_fast[0] < array_alma_slow[0] && array_alma_fast[1] > array_alma_slow[1])
   {
      return true;
   }
   else
   {
      return false;
   }
}
Principios generales - Operaciones comerciales - Guía de ayuda de MetaTrader 5
Principios generales - Operaciones comerciales - Guía de ayuda de MetaTrader 5
  • www.metatrader5.com
Antes de empezar a estudiar las funciones comerciales de la plataforma, es necesario formar una idea clara sobre los términos principales...
 
luisardo:

Mi programa ejecuta las compras y ventas correctamente, solo le agregué un código el cual si la posición llega a take profit me hace una pequeña compra, pero cuando lo ejecuto no me abre esa pequeña operación. Si me ayudan o me aconsejan como solucionar este problema se los agradecería mucho

Hola,

El problema que estás experimentando se debe a la ubicación del código que verifica si la posición ha alcanzado el take profit y abre una nueva operación pequeña. Actualmente, este código está dentro del bloque que solo se ejecuta cuando se cumplen las condiciones de entrada para una compra (dentro de if (entradaCompra()) ).

Esto significa que la verificación solo ocurre cuando se genera una nueva señal de compra, no cuando la posición realmente alcanza el take profit.

Para resolver este problema, necesitas mover el código que verifica si la posición ha alcanzado el take profit fuera del bloque if (entradaCompra()) y posiblemente fuera del bloque que verifica si hay una nueva barra ( if (iTime(Symbol(), Period(), 0) != date) ).

De esta manera, el código se ejecutará en cada tick, permitiéndole detectar cuando el precio alcanza el take profit y abrir la nueva operación pequeña en consecuencia.

A continuación, te muestro cómo puedes modificar tu función OnTick() :


#include <Trade\Trade.mqh>
// Configuración ALMA
double pips_TP = 0; // Take profit
double pips_SL = 0; // Stop loss
input int ALMA_Period1 = 10; // ALMA rápida
input int ALMA_Period2 = 55; // ALMA lenta
input double Sigma = 6.0;    // Parámetro Sigma
input double Offset = 0.85;  // Offset de la distribución Gaussiana
input int Shift = 0;         // Shift en barras

int handle_alma1 = 0;
int handle_alma2 = 0;
double array_alma_fast[];
double array_alma_slow[];
CTrade trade;
datetime date = 0;
double Entrada = 0;

// ATR PRUEBA
int handle_ATR = 0;
input int ATR_Period = 20;
input double Factor = 3.0;
input ENUM_MA_METHOD MA_Method = MODE_SMA;
input double MA_Period = 20; // Hay que dejarlo en 1 siempre
input ENUM_APPLIED_PRICE IPC = PRICE_CLOSE;
double MA_Buffer[];
double UpATRBuffer[];
double DnATRBuffer[];

//
input double Lote = 0.1;
double nuevoLote = Lote * 0.75;
double TP2 = 0;

//+------------------------------------------------------------------+
//| OnInit function                                                  |
//+------------------------------------------------------------------+
int OnInit()
{
   // Crear el handle del indicador ALMA con los parámetros necesarios
   handle_alma1 = iCustom(Symbol(), Period(), "Alma indicador", ALMA_Period1, 0, Sigma, Offset, Shift, PRICE_CLOSE);
   handle_alma2 = iCustom(Symbol(), Period(), "Alma indicador", 0, ALMA_Period2, Sigma, Offset, Shift, PRICE_CLOSE);
   // ATR HANDLE
   handle_ATR = iCustom(Symbol(), Period(), "kc", MA_Method, MA_Period, ATR_Period, Factor, IPC, Shift);
   
   return INIT_SUCCEEDED;
}

//+------------------------------------------------------------------+
//| OnTick function                                                  |
//+------------------------------------------------------------------+
void OnTick()
{
   // Obtener precios actuales
   double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
   ask = NormalizeDouble(ask, _Digits);
   double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);
   bid = NormalizeDouble(bid, _Digits);

   // Verificar si hay una nueva barra
   if (iTime(Symbol(), Period(), 0) != date)
   {
      if (entradaCompra())
      { // Comprar
         Print("Se abrió operación Alcista");
         if (PositionsTotal() > 0) 
         { 
            for (int i = PositionsTotal() - 1; i >= 0; i--) 
            { 
               if (PositionGetSymbol(i) == Symbol() && PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL) 
               { 
                  trade.PositionClose(PositionGetInteger(POSITION_TICKET)); 
                  Print("Cerrado por condición de nueva señal de Compra"); 
               } 
            } 
         }
         Entrada = SymbolInfoDouble(Symbol(), SYMBOL_ASK);
         trade.Buy(Lote, Symbol(), NormalizeDouble(Entrada, _Digits),
                   NormalizeDouble(pips_SL, _Digits),
                   NormalizeDouble(pips_TP , _Digits), "----LONG realizado----");
      }
      else if (entradaVenta())
      { // Venta
         Print("Se abrió operación Bajista");
         if (PositionsTotal() > 0) 
         { 
            for (int i = PositionsTotal() - 1; i >= 0; i--) 
            { 
               if (PositionGetSymbol(i) == Symbol() && PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY) 
               { 
                  trade.PositionClose(PositionGetInteger(POSITION_TICKET)); 
                  Print("Cerrado por condición de nueva señal de Venta"); 
               } 
            } 
         }
         Entrada = SymbolInfoDouble(Symbol(), SYMBOL_BID);
         trade.Sell(Lote, Symbol(), NormalizeDouble(Entrada, _Digits),
                    NormalizeDouble(pips_SL, _Digits),
                    NormalizeDouble(pips_TP, _Digits), "----SHORT realizado----");
      }
      date = iTime(Symbol(), Period(), 0);
   }

   // Verificar si alguna posición alcanzó el take profit y abrir una nueva operación más pequeña
   for (int P = PositionsTotal() - 1; P >= 0; P--)
   {
      ulong Ticket = PositionGetTicket(P);
      if (PositionSelectByTicket(Ticket))
      {
         double takeProfit = PositionGetDouble(POSITION_TP);
         ENUM_POSITION_TYPE PosType = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);

         if (PosType == POSITION_TYPE_BUY)
         {
            if (takeProfit > 0 && bid >= takeProfit)
            {
               Entrada = SymbolInfoDouble(Symbol(), SYMBOL_ASK);
               if (trade.Buy(0.030, Symbol(), NormalizeDouble(Entrada, _Digits), 0, 0, "----LONG NUEVO realizado----"))
               {
                  Print("Nueva orden ejecutada");
               }
               else
               {
                  Print("Algo salió mal: ", GetLastError());
               }
            }
         }
         else if (PosType == POSITION_TYPE_SELL)
         {
            if (takeProfit > 0 && ask <= takeProfit)
            {
               Entrada = SymbolInfoDouble(Symbol(), SYMBOL_BID);
               if (trade.Sell(0.030, Symbol(), NormalizeDouble(Entrada, _Digits), 0, 0, "----SHORT NUEVO realizado----"))
               {
                  Print("Nueva orden ejecutada");
               }
               else
               {
                  Print("Algo salió mal: ", GetLastError());
               }
            }
         }
      }
   }
}

//+------------------------------------------------------------------+
//| OnDeinit function                                                |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
   if (handle_alma1 != INVALID_HANDLE)
      IndicatorRelease(handle_alma1);
   if (handle_alma2 != INVALID_HANDLE)
      IndicatorRelease(handle_alma2);
}

//+------------------------------------------------------------------+
//| Función de entrada para compra                                   |
//+------------------------------------------------------------------+
bool entradaCompra()
{
   // Buffer ATR
   ArraySetAsSeries(MA_Buffer, true); 
   ArraySetAsSeries(UpATRBuffer, true); 
   ArraySetAsSeries(DnATRBuffer, true); 
   CopyBuffer(handle_ATR, 0, 0, 3, MA_Buffer); 
   CopyBuffer(handle_ATR, 1, 0, 3, UpATRBuffer); 
   CopyBuffer(handle_ATR, 2, 0, 3, DnATRBuffer);
   pips_SL = DnATRBuffer[0]; // Stop loss dinámico
   pips_TP = UpATRBuffer[0]; // Take profit dinámico
   TP2 = pips_TP;
   
   // Buffer ALMA
   ArraySetAsSeries(array_alma_fast, true);
   CopyBuffer(handle_alma1, 0, 1, 2, array_alma_fast);

   ArraySetAsSeries(array_alma_slow, true);
   CopyBuffer(handle_alma2, 1, 1, 2, array_alma_slow);

   if (array_alma_fast[0] > array_alma_slow[0] && array_alma_fast[1] < array_alma_slow[1])
   {
      return true;
   }
   else
   {
      return false;
   }
}

//+------------------------------------------------------------------+
//| Función de entrada para venta                                    |
//+------------------------------------------------------------------+
bool entradaVenta()
{
   // Buffer ATR
   ArraySetAsSeries(MA_Buffer, true); 
   ArraySetAsSeries(UpATRBuffer, true); 
   ArraySetAsSeries(DnATRBuffer, true); 
   CopyBuffer(handle_ATR, 0, 0, 3, MA_Buffer); 
   CopyBuffer(handle_ATR, 1, 0, 3, UpATRBuffer); 
   CopyBuffer(handle_ATR, 2, 0, 3, DnATRBuffer);
   pips_TP = DnATRBuffer[0]; // Take profit dinámico
   pips_SL = UpATRBuffer[0]; // Stop loss dinámico
   // Buffer ALMA
   ArraySetAsSeries(array_alma_fast, true);
   CopyBuffer(handle_alma1, 0, 1, 2, array_alma_fast);

   ArraySetAsSeries(array_alma_slow, true);
   CopyBuffer(handle_alma2, 1, 1, 2, array_alma_slow);

   if (array_alma_fast[0] < array_alma_slow[0] && array_alma_fast[1] > array_alma_slow[1])
   {
      return true;
   }
   else
   {
      return false;
   }
}


 
Muchas gracias por tu ayuda