Aprire l'ordine opposto - pagina 2

 

Non potete farlo per regolare lo slippage per i broker a 4/5 cifre, non ha senso.

Lo slippage deve essere un int, quindi un numero intero, per un broker a 4 cifre lo slippage è in pip, quindi Slippage = 3 significa 3 pip, per un broker a 5 cifre lo slippage è in punti, quindi Slippage = 3 significa 3 punti o 0. 3 pip.Quindi, per compensare, per un Broker a 5 cifre la cifra dello slippage deve essere moltiplicata per dieci, dando 30...30 punti = 3 Pip.

Quindi questo codice è sbagliato...

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

Provate questa versione modificata della vostrafunzione 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:

Provate questa versione modificata della vostra funzione OpenOppositeOrder() . . .


Ciao RaptorUk,

Prima di tutto grazie per l'aiuto fornito finora. Ora l'EA inizia a funzionare. Ho fatto altre modifiche su come chiudere tutto se un ordine ha un profitto e questo va bene ma come hai già visto e previsto per questa strategia è necessario che l'ordine che raggiunge il profitto abbia la dimensione del lotto aumentata per compensare gli ordini precedenti. con questo in mente ho introdotto il codice per farlo. Ho bisogno di confermare se l'ultimo ordine ha avuto un profitto o meno e voglio usare OrderProfit() in modo da regolare la dimensione del lotto dell'ordine successivo, ma non ho bisogno di chiudere l'ordine precedente per ottenere questa informazione?

Ecco il codice per aprire un ordine opposto che funziona bene (grazie a te) dove ho introdotto il codice extra per trovare se l'ordine precedente che è aperto ha un profitto. Sono nel modo giusto per ottenerlo?

Grazie, grazie

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:


Ciao RaptorUk,

Prima di tutto grazie per l'aiuto fornito finora. Ora l'EA inizia a funzionare. Ho fatto altre modifiche su come chiudere tutto se un ordine ha un profitto e questo va bene, ma come avete già visto e previsto per questa strategia è necessario che l'ordine che raggiunge il profitto abbia la dimensione del lotto aumentata per compensare gli ordini precedenti. con questo in mente ho introdotto il codice per farlo. Ho bisogno di confermare se l'ultimo ordine ha avuto un profitto o meno e voglio usare OrderProfit() in modo da regolare la dimensione del lotto dell'ordine successivo, ma non ho bisogno di chiudere l'ordine precedente per ottenere questa informazione?

Ecco il codice per aprire un ordine opposto che funziona bene (grazie a te) dove ho introdotto il codice extra per trovare se l'ordine precedente che è aperto ha un profitto. Sono nel modo giusto per ottenere questo

Ho il sospetto che questo ti causerà dei problemi.

mlots = NormalizeDouble(lastlot * Multiplier, Digits);

per esempio, se il risultato fosse 1,12316734 lotti il vostro NormalizeDouble() su un par a 5 cifre lo cambierà in1,12316 e questo non rispetterà il requisito del Lot Step . . . devi usare un po' di matematica per rendere la dimensione del tuo lotto modificato un multiplo del Lot Step MarketInfo(Symbol(),MODE_LOTSTEP)

 
RaptorUK:

Ho il sospetto che questo vi causerà dei problemi...

per esempio, se il risultato fosse 1,12316734 lotti il vostro NormalizeDouble() su un par a 5 cifre lo cambierebbe in1,12316 e questo non sarebbe conforme al requisito del Lot Step . . . dovete usare un po' di matematica per rendere il vostro lotto modificato un multiplo del Lot Step MarketInfo(Symbol(),MODE_LOTSTEP)


Ciao RaptorUK,

Per quanto riguarda il tuo consiglio di cercare di mantenere la mia dimensione del lotto un multiplo di Lot Step sto cercando di documentarmi sull'argomento.

Ora ho un altro problema (più uno...)

Per aprire gli ordini sopra e sotto il prezzo corrente voglio usare una linea dove una volta che l'Ea comincia a correre confronto il prezzo con la linea che è ancora.

Un primo problema viene; come posso confrontare la linea con una differenza di prezzo?

Ecco il codice che ho finora. Qui come posso dare il nome da confrontare perché se metto iHigh dopo priceline non funziona.

Grazie in anticipo per qualsiasi indizio in questi problemi.

Luis

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

Questo sembra non funzionare affatto (...)

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();
            }

Ho messo qui l'oggetto delete, perché ho bisogno che la linea sia cancellata con la chiusura di tutti gli ordini. sono corretto ?

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:

Questo sembra non funzionare affatto (...)

Ho messo qui l'oggetto delete, perché ho bisogno che la linea sia cancellata con la chiusura di tutti gli ordini. sono corretto?

Ok, penso di aver capito cosa vuoi fare, vuoi controllare dove si trova Bid rispetto alla tua linea, per fare questo hai bisogno di ottenere la posizione della linea... usa ObjectGet() con il nome dell'oggetto e l'indice della proprietà dell'oggettoOBJPROP_TIME1 questo restituirà il prezzo a cui si trova la linea.

La tua chiamata ObjectDelete() mi sembra ok. Non mi piace particolarmente l'uso di ObjectsDeleteAll() penso che sia pigro e pericoloso . . . o per lo meno scomodo per gli altri.

 
RaptorUK:

Ok, penso di aver capito cosa vuoi fare, vuoi controllare dove si trova Bid rispetto alla tua linea, per fare questo hai bisogno di ottenere la posizione della linea... usa ObjectGet() con il nome dell'oggetto e l'indice della proprietà dell'oggettoOBJPROP_TIME1 questo restituirà il prezzo a cui si trova la linea.

La tua chiamata ObjectDelete() mi sembra ok.


Ciao RaptorUK,

Sto cercando di chiudere tutti gli ordini se uno si chiude in profitto, ma quando ciò accade un ordine pendente è ancora aperto, tuttavia l'istruzione di chiudere è inclusa nella funzione CloseAll(). Qualche indizio su questo problema?

Grazie in anticipo per qualsiasi aiuto

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:


Ciao RaptorUK,

Sto cercando di chiudere tutti gli ordini se uno si chiude in profitto, ma quando ciò accade un ordine pendente è ancora aperto, tuttavia l'istruzione di chiudere è inclusa nella funzione CloseAll(). Qualche indizio su questo problema?

Devi capire come funzionano le espressioni . . . non puoi fare questo . . .

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

è una situazione simile a questa, ma non esattamente la stessa:https://www.mql5.com/en/forum/141790


Qual è il risultato di . . .

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

|| è un operatore boleano, quindi funziona solo su boole . . .


questo risulta in un valore risultante bool . . .

( Op == OP_SELLSTOP )

. . . se vuoi usare un operatore bitwise sui tuoi valori allora puoi usare questo . . . .

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

. . . ma non è quello che stai cercando di fare.

 
RaptorUK:

Devi capire come funzionano le espressioni . . . non puoi fare questo . . .

è una situazione simile a questa, ma non esattamente la stessa:https://www.mql5.com/en/forum/141790


Qual è il risultato di . . .

|| è un operatore boleano, quindi funziona solo su boole . . .


questo risulta in un valore risultante bool . . .

. . . se vuoi usare un operatore bitwise sui tuoi valori allora puoi usare questo . . . .

. . . ma non è quello che stai cercando di fare.


Ciao RaptorUK,

Capisco, ma ora con questo in mente ho modificato il codice e l'ordine pendente è ancora lì...

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:


Ciao RaptorUK,

Capisco, ma ora con questo in mente ho modificato il codice e l'ordine pendente è ancora lì...

Può essere se ha un numero magico diverso daMagicNumber o è per un simbolo diverso dal simbolo che l'EA sta eseguendo o se è un OP_SELLLIMIT o OP_BUYLIMIT . . inoltre, è necessario controllare i valori di ritorno dalle chiamate OrderDelete() e OrderClose() .

Perché hai bisogno di chiamare RefreshRates()? Non voglio dire di sbarazzarmene, ma puoi spiegare perché stai chiamando RefreshRates() dove sei?


Cosa sono i valori di ritorno delle funzioni? Come posso usarli?

Motivazione: