robot de trading

 

Hola, he intentado crear un robot, pero estoy teniendo un problema, cuando lo inicio en el probador de estrategias hay error. El robot debe iniciar con una compra/venta segun lo que elija y luego copiar una orden pendiente. Ni siquiera le pongo SL y me dice precio invalido y SL invalido.

Dejo los errores y el codigo.


failed market buy 0.01 XAUUSDx sl: 2059.99 [Invalid stops]

CTrade::OrderSend: market buy 0.01 XAUUSDx sl: 2059.99 [invalid stops]

failed buy limit 0.01 XAUUSDx at 2059.91 tp: 2060.91 [Invalid price]

CTrade::OrderSend: buy limit 0.01 XAUUSDx at 2059.91 tp: 2060.91 [invalid price]

//+------------------------------------------------------------------+
//|                                                    EA.mq5        |
//|                        Copyright 2024, MetaQuotes Software Corp. |
//|                                        http://www.metaquotes.net |
//+------------------------------------------------------------------+
#property strict
#include <Trade\Trade.mqh>
CTrade trade;

// Parámetros de entrada
input bool BuyOrder = true; // Verdadero para Compra, Falso para Venta
input double InitialLotSize = 0.01;
input double TakeProfit = 100.0; // en pips
input double DistanceBetweenOrders = 100.0; // en pips
input double MaxSpreadOpen = 12.0; // en pips
input double MaxSpreadClose = 20.0; // en pips
input int MaxTicks = 25; // Máximo de ticks en 10 segundos

// Variables globales
int orderDirection;
double point;
datetime lastTickTime;
int tickCount;

//+------------------------------------------------------------------+
//| Función de inicialización del experto                            |
//+------------------------------------------------------------------+
int OnInit()
  {
   // Determinar la dirección de la orden
   orderDirection = BuyOrder ? ORDER_TYPE_BUY : ORDER_TYPE_SELL;
   point = _Point * (Digits() == 3 || Digits() == 5 ? 10 : 1);

   // Inicializar las variables de control de ticks
   lastTickTime = TimeCurrent();
   tickCount = 0;

   // Abrir la orden inicial
   if(OpenOrder())
     {
      Print("EA iniciado y primer orden enviada correctamente");
     }
   else
     {
      Print("Spread alto, la orden no pudo abrirse");
     }

   // Colocar la primera orden pendiente
   PlacePendingOrder();

   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Función de desinicialización del experto                         |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
  }
//+------------------------------------------------------------------+
//| Función de tick del experto                                      |
//+------------------------------------------------------------------+
void OnTick()
  {
   // Controlar el conteo de ticks dentro de 10 segundos
   if(TimeCurrent() - lastTickTime <= 10)
     {
      tickCount++;
      if(tickCount > MaxTicks)
        {
         Print("Volumen alto, No se pudo abrir la orden. Ticks en los últimos 10 segundos: ", tickCount);
         return;
        }
     }
   else
     {
      lastTickTime = TimeCurrent();
      tickCount = 0;
     }

   // Verificar y colocar órdenes pendientes
   CheckAndPlacePendingOrder();
   
   // Verificar y cerrar órdenes si es necesario
   CheckAndCloseOrders();
  }
//+------------------------------------------------------------------+
//| Abrir orden inicial                                              |
//+------------------------------------------------------------------+
bool OpenOrder()
  {
   // Calcular el spread en pips
   double spread = (SymbolInfoDouble(_Symbol, SYMBOL_ASK) - SymbolInfoDouble(_Symbol, SYMBOL_BID)) / point;
   
   // Solo abrir la orden si el spread es menor o igual al MaxSpreadOpen
   if(spread <= MaxSpreadOpen)
     {
      double price = orderDirection == ORDER_TYPE_BUY ? SymbolInfoDouble(_Symbol, SYMBOL_ASK) : SymbolInfoDouble(_Symbol, SYMBOL_BID);
      double tp = orderDirection == ORDER_TYPE_BUY ? price + TakeProfit * point : price - TakeProfit * point;

      if(orderDirection == ORDER_TYPE_BUY)
        return trade.Buy(InitialLotSize, NULL, 0, tp);  // Sin Stop Loss
      else
        return trade.Sell(InitialLotSize, NULL, 0, tp);  // Sin Stop Loss
     }
   else
     {
      Print("Spread alto, la orden no pudo abrirse");
      return false;
     }
  }
//+------------------------------------------------------------------+
//| Colocar orden pendiente                                          |
//+------------------------------------------------------------------+
void PlacePendingOrder()
  {
   // Calcular el spread en pips
   double spread = (SymbolInfoDouble(_Symbol, SYMBOL_ASK) - SymbolInfoDouble(_Symbol, SYMBOL_BID)) / point;
   
   // Solo colocar la orden pendiente si el spread es menor o igual al MaxSpreadOpen
   if(spread <= MaxSpreadOpen)
     {
      double price = orderDirection == ORDER_TYPE_BUY ? SymbolInfoDouble(_Symbol, SYMBOL_BID) + DistanceBetweenOrders * point : SymbolInfoDouble(_Symbol, SYMBOL_ASK) - DistanceBetweenOrders * point;
      double tp = orderDirection == ORDER_TYPE_BUY ? price + TakeProfit * point : price - TakeProfit * point;

      if(orderDirection == ORDER_TYPE_BUY)
         trade.BuyLimit(InitialLotSize, price, NULL, 0, tp);  // Sin Stop Loss
      else
         trade.SellLimit(InitialLotSize, price, NULL, 0, tp);  // Sin Stop Loss
     }
   else
     {
      Print("Spread alto, la orden pendiente no pudo colocarse");
     }
  }
//+------------------------------------------------------------------+
//| Verificar y colocar órdenes pendientes                           |
//+------------------------------------------------------------------+
void CheckAndPlacePendingOrder()
  {
   bool hasActiveOrder = false;
   
   for(int i = 0; i < PositionsTotal(); i++)
     {
      if(PositionSelect(_Symbol))
        {
         if(PositionGetInteger(POSITION_TYPE) == orderDirection)
           {
            hasActiveOrder = true;
            break;
           }
        }
     }
   if (!hasActiveOrder)
     {
      PlacePendingOrder();
     }
  }
//+------------------------------------------------------------------+
//| Verificar y cerrar órdenes si es necesario                       |
//+------------------------------------------------------------------+
void CheckAndCloseOrders()
  {
   double spread = (SymbolInfoDouble(_Symbol, SYMBOL_ASK) - SymbolInfoDouble(_Symbol, SYMBOL_BID)) / point;

   for(int i = 0; i < PositionsTotal(); i++)
     {
      if(PositionSelect(_Symbol))
        {
         if(PositionGetInteger(POSITION_TYPE) == orderDirection)
           {
            if(spread > MaxSpreadClose)
              {
               Print("Spread alto, no se pudo cerrar la orden: ", spread);
               continue;
              }

            trade.PositionClose(_Symbol);
           }
        }
     }
  }
//+------------------------------------------------------------------+
MetaQuotes — the developer of trading platforms for brokers, banks, exchanges and hedge funds
MetaQuotes — the developer of trading platforms for brokers, banks, exchanges and hedge funds
  • www.metaquotes.net
MetaTrader 5 trading platform is a free Forex and stock trading tool
 
Franco Ferrante:

Esta escribiendo mal la orden de compra/venta. Fíjese en el orden de los valores.

bool  Buy(
   double        volume,          // volumen de la posición
   const string  symbol=NULL,     // símbolo
   double        price=0.0,       // precio
   double        sl=0.0,          // precio stop loss
   double        tp=0.0,          // precio take profit
   const string  comment=""       // comentario
   )

Y comparelos en como los rellena usted.

trade.Buy(InitialLotSize, NULL, 0, tp);

Aquí toda la información en la documentación: https://www.mql5.com/es/docs/standardlibrary/tradeclasses/ctrade/ctradebuy

Documentación para MQL5: Biblioteca estándar / Clases de comercio / CTrade / Buy
Documentación para MQL5: Biblioteca estándar / Clases de comercio / CTrade / Buy
  • www.mql5.com
Abre la posición larga con los parámetros especificados. Parámetros volume [in]  Volumen de la posición. symbol=...