Abrir la orden contraria - página 2

 

No se puede hacer esto para ajustar el deslizamiento para los corredores de 4/5 dígitos, simplemente no tiene sentido.

El deslizamiento debe ser un int, es decir, un número entero, para un corredor de 4 dígitos el deslizamiento es en Pips, por lo que Slippage = 3 significa 3 Pips, para un corredor de 5 dígitos el deslizamiento es en puntos, por lo que Slippage = 3 significa 3 puntos o 0. 3 Pips.Así que para compensar, para un corredor de 5 dígitos la cifra de deslizamiento debe ser multiplicada por diez dando 30... 30 puntos = 3 Pips.

Así que este código está mal....

int init()
   {
   if (Digits ==3 || Digits ==5) pt = 10 * Point;
   else pt = Point;
   Slippage = Slippage * pt;    
   }
 

Pruebe esta versión modificada de sufunción OpenOppositeOrder() .

void OpenOppositeOrder() 
   {
   int Op;  
 
   for(int Counter = OrdersTotal()-1; Counter >= 0; Counter--)
      {
      if(OrderSelect(Counter,SELECT_BY_POS,MODE_TRADES))  // only continue if the OrderSelect() worked
         {
         if(OrderSymbol() == Symbol()&& OrderMagicNumber() == MagicNumber)
            {
            Op = OrderType();

            if(Op == OP_BUY && Bid < OrderOpenPrice())
               {      
               Ticket = OrderSend(Symbol(), OP_SELL, LotSize, Bid, Slippage, 0, 0, "Sell Order", MagicNumber, 0, Red);
               if(Ticket > 0) 
                  {
                  Print("Opposite Sell order placed # ", Ticket);
                  AddLimitsSell();
                  }
               else
                  {
                  Print("Order Send failed, error # ", GetLastError() );
                  }
               }
               
            if(Op == OP_SELL && Ask > OrderOpenPrice())
               {      
               Ticket = OrderSend(Symbol(), OP_BUY, LotSize, Ask, Slippage, 0, 0, "Buy Order", MagicNumber, 0, Green);
               if(Ticket > 0)
                  {
                  Print("Opposite Buy order placed # ", Ticket);
                  AddLimitsBuy();
                  }
               else
                  {  
                  Print("Order Send failed, error # ", GetLastError() );
                  }   
               }
            }
         }
      }
   }
 
RaptorUK:

Pruebe esta versión modificada de su función OpenOppositeOrder() .


Hola RaptorUk,

Antes de todo gracias por la ayuda proporcionada hasta ahora. Ahora el EA empieza a funcionar. He hecho otras modificaciones sobre cómo cerrar todo si una orden tiene beneficios y eso está bien pero como ya viste y predijiste para que esta estrategia funcione es necesario que la orden que alcance beneficios tenga el tamaño del lote aumentado para compensar las órdenes anteriores. con eso en mente he introducido código para hacer eso. Así que estoy lidiando con una confusión aquí. Necesito confirmar si la última orden tuvo beneficios o no y quiero usar OrderProfit() de forma que se ajuste el tamaño del lote de la siguiente orden pero, ¿no necesito cerrar la orden anterior para obtener esa información?

Aquí está el código para abrir una orden opuesta que funciona bien (gracias a ti) donde introduzco el código extra para encontrar si la orden anterior que está abierta tiene un beneficio. ¿Estoy en el camino correcto para conseguirlo?

Gracias

Luis

 void OpenOppositeOrder() 
 {
// LastOrder Loss Compensation 
   int Orders;
   Orders= OrdersTotal();
   if (Orders>0)
   {  
    for(i=0;i<Orders;i++)
   {
    OrderSelect(i,SELECT_BY_POS,MODE_TRADES);
    if(OrderSymbol()==Symbol()&& OrderMagicNumber()== MagicNumber)
   {
    lastprofit = OrderProfit();
    lastlot = OrderLots();
   }
  }
 }
  mlots=0;
  if (lastprofit<0)mlots=NormalizeDouble(lastlot*Multiplier,Digits);
  else mlots=LotSize;
 
//+------------------------------------------------------------------+ 
//Open Opposite Order 
   int Op;  
 
   for(int Counter = OrdersTotal()-1; Counter >= 0; Counter--)
      {
      if(OrderSelect(Counter,SELECT_BY_POS,MODE_TRADES))  
         {
         if(OrderSymbol() == Symbol()&& OrderMagicNumber() == MagicNumber)
            {
            Op = OrderType();

            if(Op == OP_BUY && Bid < OrderOpenPrice())
               {  
               if(Martingale)ilots=mlots;else ilots=LotSize; 
               Ticket = OrderSend(Symbol(), OP_SELL, ilots, Bid, UseSlippage, 0, 0, "Sell Order", MagicNumber, 0, Red);
               if(Ticket > 0) 
                  {
                  Print("Opposite Sell order placed # ", Ticket);
                  AddLimitsSell();
                  }
               else
                  {
                  Print("Order Send failed, error # ", GetLastError() );
                  }
               }
               
            if(Op == OP_SELL && Ask > OrderOpenPrice())
               { 
               if(Martingale)ilots=mlots;else ilots=LotSize;
               Ticket = OrderSend(Symbol(), OP_BUY, ilots, Ask, UseSlippage, 0, 0, "Buy Order", MagicNumber, 0, Green);
               if(Ticket > 0)
                  {
                  Print("Opposite Buy order placed # ", Ticket);
                  AddLimitsBuy();
                  }
               else
                  {  
                  Print("Order Send failed, error # ", GetLastError() );
                  }   
               }
            }
         }
      }
   }
 
luisneves:


Hola RaptorUk,

Antes de todo gracias por la ayuda proporcionada hasta ahora. Ahora el EA empieza a funcionar. He hecho otras modificaciones sobre como cerrar todo si una orden tiene beneficio y eso está bien pero como ya visteis y predijisteis para que esta estrategia funcione es necesario que la orden que alcance beneficio tenga el tamaño de lote aumentado para compensar las órdenes anteriores. con eso en mente he introducido código para hacer eso. así que estoy lidiando con una confusión aquí. Necesito confirmar si la última orden tuvo beneficios o no y quiero usar OrderProfit() de forma que se ajuste el tamaño del lote de la siguiente orden pero, ¿no necesito cerrar la orden anterior para obtener esa información?

Aquí está el código para abrir una orden opuesta que funciona bien (gracias a ti) donde introduzco el código extra para encontrar si la orden anterior que está abierta tiene un beneficio. ¿Estoy en el camino correcto para conseguirlo?

Sospecho que esto te va a causar problemas....

mlots = NormalizeDouble(lastlot * Multiplier, Digits);

por ejemplo, si el resultado fue 1.12316734 lotes su NormalizeDouble() en un par de 5 dígitos lo cambiará a1.12316 y esto no cumplirá con el requisito de Lot Step . . . necesita usar algunas matemáticas para hacer que su tamaño de lote modificado sea un múltiplo del Paso de Lote MarketInfo(Symbol(),MODE_LOTSTEP)

 
RaptorUK:

Sospecho que esto te va a causar problemas .

por ejemplo, si el resultado fue 1.12316734 lotes su NormalizeDouble() en un par de 5 dígitos lo cambiará a1.12316 y esto no cumplirá con el requisito de Lot Step . .. necesita utilizar algunas matemáticas para hacer que su tamaño de lote modificado sea un múltiplo del paso de lote MarketInfo(Symbol(),MODE_LOTSTEP)


Hola RaptorUK,

Con respecto a tu consejo de buscar mantener mi tamaño de lote un múltiplo de Lot Step estoy buscando documentarme sobre el tema.

Ahora tengo otro problema (más uno...)

Para abrir las órdenes por encima y por debajo del precio actual quiero utilizar una línea en la que una vez que la Ea es empezar a correr comparo el precio con la la línea que es todavía.

Viene un primer problema, ¿cómo puedo comparar la línea con una diferencia en el precio?

Aquí está el código que tengo hasta ahora. Aquí cómo puedo dar el nombre para comparar porque si pongo iHigh en después de la línea de precios simplemente no funciona.

Gracias de antemano por cualquier pista en estos temas.

Luis

priceline=iHigh(Symbol(),0,0);
 ObjectCreate("highline",OBJ_HLINE,0,0,Bid); 
 ObjectSet("highline",OBJPROP_COLOR,LimeGreen);
 ObjectSet("highline",OBJPROP_WIDTH,1);
 WindowRedraw();

Esto parece que no funciona en absoluto (...)

if(Bid > priceline+Distance*pt)                      
                {       
// Open buy order

                            while(IsTradeContextBusy()) Sleep(10);
                                 RefreshRates();        
                       
             Ticket=OrderSend(Symbol(),OP_BUY,LotSize,Ask,UseSlippage,0,0,"Buy Order",MagicNumber,0,Green);
             if(Ticket>0)AddLimitsBuy();
            }

He puesto aquí el objeto delete, porque necesito que la línea se borre con el cierre de todas las órdenes. ¿estoy en lo cierto?

void CloseAll()
      {
         int i,Op,Error;
         int Total=OrdersTotal();
     
         if(Total>0)
         {
         for(int pos=OrdersTotal()-1;pos>=0;pos--)
         if(OrderSelect(pos,SELECT_BY_POS)
         && OrderMagicNumber()==MagicNumber && OrderSymbol()==Symbol())
         {
         Op=OrderType();
         if(Op==OP_BUY)
         {
         OrderClose(OrderTicket(),OrderLots(),Bid, UseSlippage, Yellow);
         }
         if(Op==OP_SELL)
         {
         OrderClose(OrderTicket(),OrderLots(),Ask, UseSlippage, Yellow);
         }
         else
         {
         ObjectDelete("highline");
         }
        }
       }
      }
 
luisneves:

Parece que esto no funciona en absoluto (...)

He puesto aquí el objeto delete, porque necesito que la línea se borre con el cierre de todas las órdenes.

OK, creo que entiendo lo que quieres hacer, quieres comprobar donde se encuentra Bid en comparación con tu línea, para ello necesitas obtener la posición de la línea... utiliza ObjectGet() con el nombre del objeto y el índice de la propiedadOBJPROP_TIME1 esto te devolverá el precio en el que se encuentra la línea.

Tu llamada a ObjectDelete() me parece bien. Particularmente no me gusta el uso de ObjectsDeleteAll() creo que es perezoso y peligroso . . . o al menos inconveniente para los demás.

 
RaptorUK:

OK, creo que entiendo lo que quieres hacer, quieres comprobar donde se encuentra Bid en comparación con tu línea, para ello necesitas obtener la posición de la línea... utiliza ObjectGet() con el nombre del objeto y el índice de la propiedadOBJPROP_TIME1 esto te devolverá el precio en el que se encuentra la línea.

Tu llamada a ObjectDelete() me parece correcta.


Hola RaptorUK,

Estoy tratando de cerrar todas las órdenes si una se cierra en beneficio, pero cuando eso ocurre una orden pendiente sigue abierta a pesar de que la instrucción de cerrar está incluida en la función CloseAll(). ¿Alguna pista sobre este tema?

Gracias de antemano por cualquier ayuda que me proporcionen

Luis

int GoToClose()
 {
  int pos;  
 {
  for(int Profit=OrdersTotal()-1;pos>=0;pos--)
  if(OrderSelect(Profit,SELECT_BY_POS)
  && OrderMagicNumber()==MagicNumber && OrderSymbol()==Symbol()
  && OrderProfit()+OrderSwap()+OrderCommission()>0||OrdersTotal()> MaxOrders)CloseAll();  
 }
}
//+---------------------------------------------------------------------------+  
      void CloseAll()
      {
         int Op,Error;
                    
         for(int pos=OrdersTotal()-1;pos>=0;pos--)
         if(OrderSelect(pos,SELECT_BY_POS)
         && OrderMagicNumber()==MagicNumber && OrderSymbol()==Symbol())
         {
         Op=OrderType();
         if(Op==OP_BUY)
         {
         RefreshRates();
         OrderClose(OrderTicket(),OrderLots(),Bid, UseSlippage, Yellow);
         }
         if(Op==OP_SELL)
         {
         RefreshRates();
         OrderClose(OrderTicket(),OrderLots(),Ask, UseSlippage, Yellow);
         }
         if(Op==OP_SELLSTOP||OP_BUYSTOP||OP_SELLLIMIT||OP_BUYLIMIT)
         {
         RefreshRates();
         OrderDelete(OrderTicket());
         }
         else Print("Error opening BUY Stop Order : ",GetLastError());         
         }
        }             
 
luisneves:


Hola RaptorUK,

Estoy tratando de cerrar todas las órdenes si una se cierra en beneficio, pero cuando eso ocurre una orden pendiente sigue abierta a pesar de que la instrucción de cerrar está incluida en la función CloseAll(). ¿Alguna pista sobre este tema?

Tienes que entender cómo funcionan las expresiones... no puedes hacer esto...

if(Op == OP_SELLSTOP || OP_BUYSTOP || OP_SELLLIMIT || OP_BUYLIMIT)

es una situación similar a esta, pero no exactamente igual:https://www.mql5.com/en/forum/141790


¿Cuál es el resultado de . . .

WhatValue = (5  || 4  ||  3  ||  2 );

|| es un operador boleano, por lo que sólo funciona con bools. . .


esto da como resultado un valor resultante bool . . .

( Op == OP_SELLSTOP )

. . . si quieres usar un operador bitwise en tus valores entonces puedes usar esto . . .

int WhatValue = (5  | 4  |  3  |  2 );

. . pero no es lo que estás tratando de hacer.

 
RaptorUK:

Tienes que entender cómo funcionan las expresiones... no puedes hacer esto...

es una situación similar a esta, pero no exactamente igual:https://www.mql5.com/en/forum/141790


Que es lo que resulta de ...........................

|| es un operador boleano, por lo que sólo funciona con bools. . .


esto da como resultado un valor resultante bool . . .

. . . si quieres usar un operador bitwise en tus valores entonces puedes usar esto . . .

. . pero no es lo que estás tratando de hacer.


Hola RaptorUK,

Ya veo, pero ahora con eso en mente he modificado el código y la orden pendiente sigue ahí...

void CloseAll()
      {
         int Op,Error;
                    
         for(int pos=OrdersTotal()-1;pos>=0;pos--)
         if(OrderSelect(pos,SELECT_BY_POS)
         && OrderMagicNumber()==MagicNumber && OrderSymbol()==Symbol())
         {
         Op=OrderType();
         if(Op==OP_BUY)
         {
         RefreshRates();
         OrderClose(OrderTicket(),OrderLots(),Bid, UseSlippage, Yellow);
         }
         if(Op==OP_SELL)
         {
         RefreshRates();
         OrderClose(OrderTicket(),OrderLots(),Ask, UseSlippage, Yellow);
         }
         if(Op==OP_SELLSTOP)
         {
         RefreshRates();
         OrderDelete(OrderTicket());
         }
         if(Op==OP_BUYSTOP)
         {
         RefreshRates();
         OrderDelete(OrderTicket());
         }
         else Print("Error opening BUY Stop Order : ",GetLastError());         
         }
        }        
 
luisneves:


Hola RaptorUK,

Ya veo, pero ahora con eso en mente he modificado el código y la orden pendiente sigue ahí...

Puede ser si tiene un Número Mágico diferente alMagicNumber o es para un símbolo diferente al que el EA está ejecutando o si es un OP_SELLLIMIT o OP_BUYLIMIT . . también, necesita comprobar los valores de retorno de sus llamadas OrderDelete() y OrderClose() .

¿Por qué necesita llamar a RefreshRates()? No me refiero a deshacerse de ellos, sino que puede explicar por qué llama a RefreshRates() donde lo hace?


¿Qué son los valores de retorno de la función? ¿Cómo los utilizo?