Estrategia comercial Heads or Tails análisis del código del robot comercial.
La estrategia de trading "Águila o Cara" pertenece a la categoría de enfoques de trading de corto plazo de alto riesgo, utilizados principalmente en el mercado de valores y en el mercado Forex. Su nombre se debe a la aleatoriedad en la toma de decisiones, similar a lanzar una moneda ("águila" - comprar un activo, "cara" - vender). Esta estrategia se basa exclusivamente en decisiones intuitivas o señales aleatorias e ignora los factores fundamentales del análisis de mercado.
Se ha agregado el código fuente de la estrategia de trading a la base de códigos:
MetaTrader 5: https://www.mql5.com/es/code/11637
#property copyright "Copyright 2025, Trading-Go." // Setting copyright property #property link "https://www.mql5.com/en/channels/tradingo-go-en" // Setting developer resource link #property version "26.010" // Program version
El código proporcionado son directivas del compilador para un programa de Expert Advisor (EA) o indicador de MetaTrader, escrito en el lenguaje MQL4/MQL5.
Veamos cada línea por separado:
1. #property copyright "Copyright 2025, Trading-Go."
Esta línea establece el derecho de propiedad legal sobre el código fuente del EA o indicador. Define al propietario de los derechos de autor y ayuda a identificar la pertenencia del producto a una organización o persona específica ("Trading-Go"). Esta información se muestra en la ventana de propiedades del EA/indicador en el terminal de cliente de MetaTrader.
2. #property link " "
Esta línea permite establecer un enlace a un recurso web del desarrollador. Cuando los traders utilizan este EA o indicador, este enlace se vuelve accesible en las propiedades de la herramienta. Esto es conveniente para los desarrolladores, ya que de esta manera pueden dirigir a los usuarios a páginas de soporte, documentación o comunidad relacionada con el producto.
3. #property version "26.010"
Aquí se establece la versión del producto de software. Normalmente, los desarrolladores especifican la versión en el formato "XX.XX", donde el primer dígito representa el número de la versión principal, el segundo el de la versión secundaria y el tercero el de la corrección. La versión ayuda a los usuarios a rastrear fácilmente las actualizaciones y mantener la compatibilidad de las herramientas.
#include // Including Trade.mqh library CTrade trade; // Object of class CTrade to manage trades #include // Including PositionInfo.mqh library CPositionInfo posit; // Object of class CPositionInfo to process positions
Este bloque de código incluye bibliotecas y crea objetos de clases para administrar operaciones de trading y posiciones en la plataforma de trading MetaTrader.
Veamos cada línea detalladamente:
1. #include
Esta es una directiva de inclusión de un archivo de encabezado (Trade.mqh) que contiene la clase CTrade. Este archivo se encuentra en la carpeta /Trade, lo que indica que la biblioteca pertenece a la biblioteca estándar de operaciones de trading proporcionada por la plataforma MetaTrader. La clase CTrade se utiliza para interactuar convenientemente con el trading, incluyendo la apertura de posiciones, el cierre de operaciones, la modificación de órdenes y la obtención de información sobre el estado del trading.
2. CTrade trade;
Se crea un objeto de la clase CTrade con el nombre "trade". Este objeto le permitirá administrar todos los aspectos del trading, como la apertura de nuevas posiciones, la configuración de stop loss y take profit, el cierre de posiciones existentes y la ejecución de muchas otras acciones relacionadas con el proceso de trading.
3. #include
Directiva de inclusión del segundo archivo de encabezado (PositionInfo.mqh) de la misma carpeta /Trade. Este archivo contiene la definición de la clase CPositionInfo, que se utiliza para procesar información sobre las posiciones abiertas actuales en la cuenta. A través de esta clase, se pueden obtener detalles específicos de cada operación abierta, como el volumen de la operación, el precio de apertura, la ganancia/pérdida y muchos otros.
4. CPositionInfo posit;
Se crea un objeto de la clase CPositionInfo con el nombre "posit". Utilizando este objeto, podrá solicitar información detallada sobre todas las posiciones activas de su cuenta de trading, lo que es útil para analizar el estado actual de la cartera y tomar decisiones basadas en la información obtenida.
Propósito general del bloque:
Este bloque proporciona la base para automatizar el proceso de trading mediante la provisión de una API de alto nivel (interfaz de programación de aplicaciones). Con los objetos "trade" y "posit" creados, puede implementar la toma automática de decisiones de trading, el monitoreo de posiciones y la automatización de operaciones rutinarias.
Por lo tanto, estas dos bibliotecas permiten simplificar el desarrollo de algoritmos complejos de trading automático, permitiendo centrarse directamente en la lógica de la estrategia, en lugar de en los aspectos de bajo nivel de la interacción con el servidor del corredor.
input double iLots = 0.10; // Input parameter for lot size (trade volume) input int iTakeProfit = 450; // Input parameter for profit fixing level (Take Profit) input int iStopLoss = 390; // Input parameter for loss limitation level (Stop Loss) input int iMagicNumber = 227; // Input parameter for unique deal number (Magic Number) input int iSlippage = 30; // Input parameter for maximum price slippage string sy = ""; // Variable to store instrument symbol double pt = 0; // Variable for point calculation step int dt = 0; // Variable for decimal places count
Veamos cada elemento del bloque de código proporcionado por separado, explicando su propósito y su papel en el proceso de configuración del Expert Advisor (EA) automático en la plataforma de trading MetaTrader.
Parámetros de entrada (Input Parameters):
1. iLots = 0.10;
Este es un parámetro de entrada de tipo double que define el tamaño del lote (volumen de la operación). El valor predeterminado está establecido en 0.10. El tamaño del lote regula la cantidad de activos que se compran o venden en una sola operación. Por ejemplo, si el instrumento es EURUSD, un lote de tamaño 0.1 corresponde a 10,000 unidades de la moneda base (por ejemplo, euros).
2. iTakeProfit = 450;
Parámetro de tipo int que establece el nivel de fijación de ganancias (Take Profit). El valor predeterminado es 450. Take Profit cierra automáticamente la posición si el precio del mercado alcanza el nivel de ganancias especificado en relación con el precio de entrada en la operación. El nivel se especifica en puntos (pips).
3. iStopLoss = 390;
Parámetro de tipo int que establece el nivel de limitación de pérdidas (Stop Loss). El valor predeterminado es 390. Stop Loss cierra automáticamente la posición si el mercado se mueve en contra de su posición y la pérdida alcanza el nivel especificado. La pérdida se fija en puntos.
4. iMagicNumber = 227;
Parámetro de tipo int que sirve como número de identificación único (Magic Number) para las transacciones. Cada evento (apertura de posición, cierre, etc.) recibe un Magic Number único, lo que permite filtrar las operaciones por este número. El valor predeterminado es 227.
5. iSlippage = 30;
Parámetro de tipo int que limita la desviación máxima del precio de ejecución de la orden con respecto al precio especificado. El valor establecido es de 30 puntos. Si el precio real difiere más de lo especificado, la operación no se ejecutará. Se utiliza para protegerse de deslizamientos excesivos de precios.
Variables locales (Local Variables):
1. sy = "";
Variable de tipo string que almacena el símbolo del instrumento financiero (por ejemplo, "EURUSD") utilizado en el trading. Inicialmente, es una cadena vacía ("").
2. pt = 0;
Variable de tipo double calculada para almacenar el tamaño del punto del instrumento específico. Se utiliza para calcular los niveles de Take Profit y Stop Loss en función de la cantidad de puntos. Por defecto, es igual a cero (0).
3. dt = 0;
Variable de tipo int destinada a contar el número de cifras decimales después de la coma en las cotizaciones del instrumento seleccionado. La cantidad de cifras decimales es importante para calcular correctamente el beneficio y el stop loss, así como otras métricas. El valor inicial es cero (0).
Este bloque de código está destinado a establecer las configuraciones iniciales y preparar el entorno para el Expert Advisor automático en MetaTrader. El bloque de parámetros de entrada permite configurar flexiblemente el comportamiento del EA justo antes de comenzar el trading.
sy = _Symbol; // Getting current trading instrument pt = _Point; // Getting minimum unit change size dt = _Digits; // Getting number of decimal digits in price trade.SetExpertMagicNumber(iMagicNumber); // Setting unique deal number for trade operations trade.SetDeviationInPoints(iSlippage); // Setting maximum price deviation points trade.SetTypeFillingBySymbol(sy); // Setting order execution type according to instrument settings trade.SetMarginMode(); // Setting margin mode
Este bloque de código demuestra la inicialización de los parámetros principales y la configuración de las operaciones de trading en el Expert Advisor automático en MetaTrader. Cada operador juega un papel importante en la preparación de las condiciones para el funcionamiento exitoso del EA.
Veamos con más detalle cada expresión.
Variables de entorno:
1. sy = _Symbol;
Asigna a la variable global "sy" el nombre del instrumento de trading actual con el que trabaja el EA. _Symbol es una constante incorporada que devuelve el nombre del activo seleccionado en el terminal. De esta manera, obtenemos acceso al nombre del instrumento necesario para los cálculos posteriores y el trabajo con él.
2. pt = _Point;
Establece la variable "pt", que toma el cambio mínimo en el precio del instrumento en puntos (_Point). Esta es la unidad básica de medición del cambio en el precio, necesaria para interpretar correctamente las señales del sistema y ajustar las órdenes.
3. dt = _Digits;
Define la variable "dt", que representa el número de cifras decimales en el precio del instrumento actual. Como diferentes instrumentos tienen diferentes cantidades de cifras decimales (por ejemplo, USDJPY tiene dos cifras, EURUSD tiene cuatro), esta variable es importante para redondear correctamente los números y realizar cálculos.
Configuración del objeto de trading:
4. trade.SetExpertMagicNumber(iMagicNumber);
Establece un número mágico único (Magic Number) para todas las operaciones iniciadas por este EA. El número mágico se utiliza para identificar las operaciones realizadas por un EA específico y simplifica el filtrado de posiciones por este criterio. La unicidad del número garantiza que no haya confusión entre diferentes estrategias robotizadas.
5. trade.SetDeviationInPoints(iSlippage);
Al establecer un límite máximo de desviación del precio de ejecución de la orden con respecto al precio esperado (slippage), se protege contra grandes fluctuaciones del mercado. Establecer el valor en puntos evita la ejecución de operaciones si el precio cambia demasiado. Cuanto menor sea el valor, más precisa será la ejecución de sus solicitudes.
6. trade.SetTypeFillingBySymbol(sy);
Configura el tipo de ejecución de órdenes en función de las características del instrumento en sí (_Symbol). Algunos instrumentos requieren ejecución instantánea ("Market Execution"), mientras que otros pueden admitir ejecución diferida ("Instant Execution"). Este comando selecciona automáticamente el modo correcto de acuerdo con las especificaciones del símbolo.
7. trade.SetMarginMode();
Configura el modo de margen del EA. Los métodos de gestión de margen varían según el instrumento y el modo de trading. La configuración correcta del margen afecta a la cantidad de fondos disponibles necesarios para mantener la posición y minimiza el riesgo de cierre forzoso de la posición debido a la falta de capital.
double stepvol = SymbolInfoDouble(sy, SYMBOL_VOLUME_STEP); // Get the lot size change step for the selected symbol if(stepvol > 0.0) // If the lot size step is positive, apply calculation of adjusted lot size lt = stepvol * (MathFloor(iLots / stepvol) - 1); // Round down the lot size to the nearest step value and decrease by one step //--- double minvol = SymbolInfoDouble(sy, SYMBOL_VOLUME_MIN); // Get minimum allowed lot size for the specified symbol if(lt < minvol) // If the adjusted lot size is less than the minimum possible value, reset it to zero lt = 0.0; ::MathSrand(GetTickCount()); // Generating initial number for random generator
El bloque de código presentado realiza un ajuste dinámico del volumen de las operaciones (lotes) dentro de un instrumento determinado (divisa, acción, contrato, etc.). La tarea principal es ajustar el tamaño del lote dentro de los valores permitidos por el mercado, evitando errores al abrir posiciones y manteniendo la seguridad de las operaciones.
Veamos cada paso con más detalle:
1. Determinación del paso de cambio de volumen:
double stepvol = SymbolInfoDouble(sy, SYMBOL_VOLUME_STEP);
La función SymbolInfoDouble() obtiene el paso de cambio de volumen (lote) para el símbolo seleccionado (SYMBOL_VOLUME_STEP). El paso define el intervalo mínimo en el que se puede cambiar el tamaño del lote. Por ejemplo, para algunos instrumentos financieros, el paso es de 0.01, lo que significa que el trading solo puede realizarse en múltiplos de cien partes del lote.
2. Comprobación de la positividad del paso:
if(stepvol > 0.0)
Se comprueba si realmente existe un paso de cambio de lote positivo. Si el paso es cero o negativo, los cálculos posteriores no tienen sentido.
3. Redondeo y reducción del lote en una etapa:
lt = stepvol * (MathFloor(iLots / stepvol) - 1);
El algoritmo reduce el volumen de la operación especificado por el trader (iLots) en una unidad del paso mínimo.
Aquí está lo que sucede dentro de la expresión:
iLots / stepvol: se calcula la cantidad entera de pasos que caben en el lote introducido.
MathFloor(): redondea el valor decimal hacia abajo al número entero más cercano.
Restamos una unidad: se reduce la cantidad de pasos completos en uno.
Multiplicamos nuevamente por el paso: obtenemos el nuevo volumen de lote ajustado.
4. Obtener el lote mínimo posible:
double minvol = SymbolInfoDouble(sy, SYMBOL_VOLUME_MIN);
Las órdenes obtienen el volumen mínimo permitido del lote para el símbolo especificado (SYMBOL_VOLUME_MIN). El mercado puede limitar los volúmenes mínimos, por debajo de los cuales no se pueden realizar operaciones.
5. Comprobación del límite mínimo:
if(lt < minvol)
lt = 0.0;
Si el volumen ajustado después de la reducción es menor que el mínimo establecido por el mercado, se establece un valor igual a cero. De esta manera, se evitan situaciones en las que el robot intente colocar un pedido con un volumen inferior al mínimo permitido.
6. Generación del valor inicial del generador de números aleatorios:
::MathSrand(GetTickCount());
Se genera un valor inicial para el uso posterior de funciones de números aleatorios. La orden toma el valor actual del contador de ticks (GetTickCount()) y lo utiliza como semilla para las secuencias pseudorandomes posteriores. Esto se hace para aumentar la imprevisibilidad de los resultados de los procesos aleatorios.
int total = ::PositionsTotal(), b = 0, s = 0; // Total open positions and purchase/sale counters double Bid = ::SymbolInfoDouble(sy, SYMBOL_BID); // Current bid price (selling price) double Ask = ::SymbolInfoDouble(sy, SYMBOL_ASK); // Current ask price (buying price) double new_sl = 0, new_tp = 0, old_sl = 0, old_tp = 0; // New and old stop loss and take profit levels if(Bid <= 0 || Ask <= 0) // If prices are incorrect return; // Exit function
El bloque de código presentado realiza una serie de operaciones preparatorias importantes antes de ejecutar la lógica adicional de trading en el Expert Advisor automático en la plataforma de trading MetaTrader. Veamos cada etapa con detalle.
Inicialización de variables:
1. Obtener el total de posiciones abiertas:
int total = ::PositionsTotal();
La función PositionsTotal() devuelve el total de posiciones abiertas en la cuenta, independientemente de la dirección y el instrumento. Estos datos son importantes para el análisis posterior y la posible optimización de las posiciones.
2. Inicialización de los contadores de compra y venta:
b = 0, s = 0;
Las variables "b" y "s" se utilizan para contar la cantidad de posiciones abiertas largas (buy) y cortas (sell), respectivamente. Inicialmente se restablecen a cero y luego se incrementan al analizar las posiciones.
Obtención de los precios actuales del mercado:
3. Solicitud del precio BID (precio de venta):
Bid = ::SymbolInfoDouble(sy, SYMBOL_BID);
La función SymbolInfoDouble() devuelve el último precio de compra conocido (BID) para el instrumento actual (sy). El precio BID refleja el mejor precio de mercado al que el trader puede vender el instrumento inmediatamente.
4. Solicitud del precio ASK (precio de compra):
Ask = ::SymbolInfoDouble(sy, SYMBOL_ASK);
Del mismo modo que en el punto anterior, se solicita el último precio de venta conocido (ASK) para el instrumento. El precio ASK muestra el mejor precio al que se puede comprar el instrumento inmediatamente.
Preparación de los niveles de stop loss y take profit:
5. Declaración de los niveles nuevos y antiguos de Stop Loss y Take Profit:
new_sl = 0, new_tp = 0, old_sl = 0, old_tp = 0;
Inicialización previa de las variables para los cálculos y comparación de los niveles de stop loss y take profit. Los valores cero indican que aún no se han establecido niveles mientras no se produzca la lógica correspondiente en el programa.
Seguridad y comprobación de la corrección de los precios:
6. Comprobación de la corrección de los precios obtenidos:
if(Bid <= 0 || Ask <= 0)
return;
Se realiza una comprobación simple para detectar precios incorrectos. Si el precio BID o ASK es cero o negativo, el programa sale de la rutina actual (return) para evitar operaciones erróneas. Esta condición protege al sistema de consecuencias indeseadas debido a datos incorrectos.
for(int i = 0; i < total; i++) // Loop through open positions if(posit.SelectByIndex(i)) // Select position by index if(posit.Symbol() == sy) // Check instrument of position if(posit.Magic() == iMagicNumber) // Check unique number of position { old_sl = ::NormalizeDouble(posit.StopLoss(), dt); // Converting old stop loss to required decimal places old_tp = ::NormalizeDouble(posit.TakeProfit(), dt); // Converting old take profit to required decimal places if(posit.PositionType() == POSITION_TYPE_BUY) // If position is BUY (purchase) { new_sl = ::NormalizeDouble(Ask - iStopLoss * pt, dt); // New stop loss below current ask price new_tp = ::NormalizeDouble(Ask + iTakeProfit * pt, dt); // New take profit above current ask price b++; // Increment purchases counter } if(posit.PositionType() == POSITION_TYPE_SELL) // If position is SELL (sale) { new_sl = ::NormalizeDouble(Bid + iStopLoss * pt, dt); // New stop loss above current bid price new_tp = ::NormalizeDouble(Bid - iTakeProfit * pt, dt); // New take profit below current bid price s++; // Increment sales counter } if(old_sl == 0 || old_tp == 0) // If new levels differ from old ones trade.PositionModify(posit.Ticket(), new_sl, new_tp);// Modify position with new SL and TP levels }
El bloque de código considerado implementa un ciclo de recorrido de las posiciones abiertas en la cuenta y la actualización de los niveles de stop loss (SL) y take profit (TP) para las posiciones correspondientes. Veamos cada operación secuencialmente:
Recorrido de posiciones abiertas:
for(int i = 0; i < total; i++)
Se realiza una iteración a través de la lista de posiciones abiertas. La variable "total" se ha establecido previamente con el número de posiciones abiertas en la cuenta (PositionsTotal()). Cada posición abierta se procesa individualmente.
Selección de posición por índice:
if(posit.SelectByIndex(i))
Se utiliza el método SelectByIndex() para seleccionar una posición por su número de índice en la lista. Una vez seleccionada, la posición está disponible para su procesamiento posterior.
Comprobación de la correspondencia del símbolo y el número mágico:
if(posit.Symbol() == sy && posit.Magic() == iMagicNumber)
Primero se comprueba si el instrumento de la posición seleccionada coincide con el símbolo especificado en la configuración (sy). Luego, se compara el número mágico único de la posición (Magic Number) con el establecido en los parámetros del EA (iMagicNumber). Ambas condiciones son necesarias para seleccionar la posición correcta.
Guardado de los niveles antiguos de SL y TP:
old_sl = NormalizeDouble(posit.StopLoss(), dt);
old_tp = NormalizeDouble(posit.TakeProfit(), dt);
Para la posición seleccionada, se guardan los niveles actuales de stop loss y take profit. Es importante normalizar los valores obtenidos teniendo en cuenta el número de cifras decimales del instrumento (dt) para garantizar el correcto procesamiento de los valores de punto flotante.
Procesamiento de la posición larga (BUY):
if(posit.PositionType() == POSITION_TYPE_BUY)
Si la posición seleccionada está abierta en compra (POSITION_TYPE_BUY), se ejecuta el siguiente bloque:
Cálculo del nuevo nivel de Stop Loss: la nueva línea de stop loss se coloca por debajo del precio de mercado actual (Ask), reducido por el nivel de stop loss preestablecido (iStopLoss), expresado en puntos (pt).
Cálculo del nuevo nivel de Take Profit: el nuevo nivel de fijación de ganancias se coloca por encima del precio de mercado actual (Ask), aumentado por el nivel de beneficio preestablecido (iTakeProfit), expresado en puntos.
Contabilidad: se incrementa el contador de compras abiertas (b++).
Procesamiento de la posición corta (SELL):
if(posit.PositionType() == POSITION_TYPE_SELL)
Si la posición es corta (POSITION_TYPE_SELL), se ejecutan acciones similares:
Nuevo Stop Loss: por encima del precio actual (Bid), aumentado por el nivel de stop loss.
Nuevo Take Profit: por debajo del precio actual (Bid), reducido por el nivel de beneficio.
Contabilidad: se incrementa el contador de ventas (s++).
Actualización de los niveles de SL y TP:
if(old_sl == 0 || old_tp == 0)
trade.PositionModify(posit.Ticket(), new_sl, new_tp);
Si el valor antiguo de SL o TP no existía (igual a cero), la posición se modifica con los nuevos niveles. El método PositionModify() se utiliza para aplicar los cambios en los niveles de protección y fijación de ganancias.
if((b + s) == 0) // If there are no active positions if(::MathRand() % 2 == 0) // Randomly choosing direction of opening position { if(trade.CheckVolume(sy, lt, Ask, ORDER_TYPE_BUY)) // Verification of the sufficiency of funds to perform the required trading operation if(trade.Buy(lt)) // Opening long position (BUY) return; // End function execution } else if(trade.CheckVolume(sy, lt, Bid, ORDER_TYPE_SELL)) // Verification of the sufficiency of funds to perform the required trading operation if(trade.Sell(lt)) // Opening short position (SELL) return; // End function execution
El bloque de código anterior describe el algoritmo de apertura aleatoria de una posición larga (BUY) o corta (SELL) si en el momento actual no hay posiciones activas en la cuenta. Veamos el proceso con detalle:
Análisis de la existencia de posiciones abiertas:
if((b + s) == 0)
Se comprueba la suma de los contadores de posiciones abiertas en compra (b) y venta (s). Si la suma es cero, significa que no hay posiciones activas en la cuenta. Solo en este caso se inicia el procedimiento de apertura de una nueva posición.
Elección aleatoria de la dirección de la posición:
if(MathRand() % 2 == 0)
Se elige aleatoriamente la dirección de la posición futura. Se utiliza un generador de números aleatorios (MathRand()). El operador % 2 devuelve el resto de la división del resultado del número aleatorio por 2, lo que da una probabilidad del 50% de obtener cero (número aleatorio par) y una probabilidad del 50% de obtener un valor distinto de cero (número aleatorio impar).
Si el resto es cero, se elige la compra (ORDER_TYPE_BUY).
De lo contrario, se abre una posición corta (ORDER_TYPE_SELL).
Apertura de una posición larga (BUY):
if(trade.CheckVolume(sy, lt, Ask, ORDER_TYPE_BUY))
Antes de comprar, se comprueba la suficiencia de fondos para realizar la operación requerida mediante el método CheckVolume(). Los argumentos son:
- Instrumento (sy),
- Volumen del lote (lt),
- Precio actual de compra (Ask),
- Tipo de orden (ORDER_TYPE_BUY).
El método comprueba el saldo y la disponibilidad de fondos para abrir la posición con el volumen especificado.
if(trade.Buy(lt))
Si los fondos son suficientes, se abre una posición larga mediante el comando Buy(), pasando el volumen del lote (lt). Si la operación tiene éxito, la ejecución del bloque se interrumpe (return).
Apertura de una posición corta (SELL):
else
if(trade.CheckVolume(sy, lt, Bid, ORDER_TYPE_SELL))
Si el caso anterior no se cumple (se elige la venta), se comprueban los fondos para la posición corta:
- Instrumento (sy),
- Volumen del lote (lt),
- Precio actual de venta (Bid),
- Tipo de orden (ORDER_TYPE_SELL).
if(trade.Sell(lt))
Si todo es correcto, se crea una posición corta mediante el comando Sell(), y la ejecución se detiene (return).
void OnDeinit(const int reason) // Deinitialization function { }
El bloque OnDeinit se deja en blanco si no se requieren acciones especiales de limpieza. Sin embargo, incluso un bloque vacío es útil, ya que recuerda al desarrollador la posibilidad de implementar la limpieza de recursos si en el futuro fuera necesario.
Por ejemplo, si su EA trabajaba con gráficos, creaba ventanas de salida o realizaba solicitudes de red, cerrar la ventana del gráfico, liberar la memoria o terminar la conexión sería una acción razonable.
Conclusión:
El código implementa una estrategia simple de apertura aleatoria de posiciones en situaciones en las que no hay posiciones activas en la cuenta. La atención principal se centra en la comprobación de la disponibilidad de fondos y en la posibilidad de realizar el trading al precio de mercado. Este enfoque puede utilizarse con fines de prueba o en sistemas en los que no hay una dirección específica de las operaciones, priorizando la frecuencia de las operaciones u otros factores.


