Tutte le domande dei nuovi arrivati su MQL4 e MQL5, aiuto e discussione su algoritmi e codici - pagina 1920

 
MrBrooklin #:

Grazie per il suggerimento, Alexey! Prima aspetterò una risposta in questo thread, ma se non succede nulla, allora mi rivolgerò al thread Errori, bug, domande.

Sinceramente, Vladimir.

Non avrai risposte dagli sviluppatori in questo thread. Se hai trovato un errore, assicurati che sia davvero un errore, segnalalo al ramo di cui parla Alexey. Non c'è bisogno di aspettarsi azioni da parte dei moderatori su questo - anche noi siamo esseri umani, e anche noi a volte non abbiamo tempo.

 
Artyom Trishkin #:

È improbabile che tu ottenga delle risposte dagli sviluppatori in questo thread. Se trovi un errore, assicurati che sia davvero un errore, segnalalo al ramo di Alexey. Non c'è bisogno di aspettarsi azioni da parte dei moderatori in questa occasione - anche noi siamo persone, e anche noi non abbiamo tempo.

Ciao Artem!

Tutto è chiaro.

Sinceramente, Vladimir.

 

Buon pomeriggio!!!!

Qui ci sono due funzioni per il consigliere della griglia la prima funzione è il calcolo del profitto, tenendo conto della chiusura parziale degli ordini perdenti

//+----------------------------------------------------------------------------+
//| Калькуляция сетки ордеров                                                  |
//+----------------------------------------------------------------------------+
bool CalculiteProfit()
  {
   double oProfit=0,oLoss=0,percent;
   int i;
   nOrd=0;
   for(i = OrdersTotal()-1; i>=0; i--)
     {
      if(!OrderSelect(i, SELECT_BY_POS, MODE_TRADES) || OrderSymbol()!=Symbol() || OrderMagicNumber()!=Magic || OrderType()>OP_SELL)
         continue;
      if(OrderProfit()>=0)
         oProfit += OrderProfit();
      else
        {
         oLoss+=OrderProfit();
         Ord_ticket[nOrd]=OrderTicket();
         Ord_lot[nOrd]=OrderLots();
         nOrd++;
        }
     }
   oLoss = MathAbs(oLoss+GetOrderSwap()+GetOrderCommission());
   if(oLoss>0)
      percent=oProfit/oLoss*100;
   else
      percent=100;
   if(percent<MinPercentForClose) //MinPercentForClose переменная из настроек 
      return(false);
   for(i=0; i<nOrd; i++)
     {
      Ord_lot[i]=(MathCeil((Ord_lot[i]*RowLots)*percent)/100)/RowLots;
     }
   return(true);
  }

La seconda funzione è la chiusura degli ordini con chiusura parziale degli ordini non redditizi

//+----------------------------------------------------------------------------+
//| Закрытие сетки ордеров при заданной команде с учетом части ордеров         |
//+----------------------------------------------------------------------------+
void ClosseAll()
  {
   int i,j,tkt;

   for(i = OrdersTotal()-1; i>=0; i--)
     {
      if(!OrderSelect(i, SELECT_BY_POS, MODE_TRADES) || OrderSymbol()!=Symbol() || OrderMagicNumber()!=Magic)
         continue;
      tkt=OrderTicket();
      RefreshRates();
      if(OrderProfit()>=0)
        {
         if(OrderType() == OP_BUY)
           {
            if(!OrderClose(OrderTicket(), OrderLots(), Bid, slip))
               Print("Не удалось закрыть ордера на покупку!");
           }
         else
            if(OrderType() == OP_SELL)
              {
               if(!OrderClose(OrderTicket(), OrderLots(), Ask, slip))
                  Print("Не удалось закрыть ордер на продажу!");
              }
        }
      else
         for(j=0; j<nOrd; j++)
            if(tkt==Ord_ticket[j])
              {
               if(OrderLots()<Ord_lot[j])
                  Ord_lot[j]=OrderLots();
               Ord_lot[j]=NRL(Ord_lot[j]);
               if(OrderType() == OP_BUY)
                 {
                  if(!OrderClose(OrderTicket(), Ord_lot[j], Bid, slip))
                     Print("Не удалось закрыть ордера на покупку!");
                 }
               else
                  if(OrderType() == OP_SELL)
                    {
                     if(!OrderClose(OrderTicket(), Ord_lot[j], Ask, slip))
                        Print("Не удалось закрыть ордер на продажу!");
                    }
               break;
              }
     }
  }

La situazione è la seguente: se chiudo una griglia di ordini tenendo conto della chiusura parziale degli ordini perdenti, ottengo una perdita come risultato dell'arrotondamento al lato maggiore di alcuni lotti che devono essere chiusi

La domanda è se è possibile utilizzare queste due funzioni per scrivere una funzione per calcolare gli ordini perdenti, o piuttosto una parte di un ordine da chiudere.

Se è così, per favore aiutatemi a scriverlo

Grazie

 
EVGENII SHELIPOV #:

Buon pomeriggio!!!!

Se è così, aiutatemi a scriverlo.

Non è un buon momento.

Intendi scriverlo per te?

 
Andrey Sokolov #:

Questi non sono bei tempi.

Vuoi dire scrivere per te?

Non si strappi Alexander

 

perso nelle cose elementari:

come organizzo una posa a strascico - co-diretto, per qualche motivo strascica una posa, cioè non strascica... MT5

for (i=0; i<PositionsTotal(); i++)   
     if (a_position.Select(_Symbol))       
     if (PositionSelect(_Symbol)) if(Symbol()==PositionGetSymbol(i))  
     if (Magic==PositionGetInteger(POSITION_MAGIC))  
   //  magic = myposition.Magic();   
      {
         //  ------------   перевод в бу  BUY   ------------    
         //if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY) 
         if (a_position.PositionType() == POSITION_TYPE_BUY)
          if (NLb_fun > 0)
            {
                Print(" перевод в безубыток BUY, _SL = ", _SL, " POSITION_PRICE_OPEN: ",
                     NormalizeDouble(PositionGetDouble(POSITION_PRICE_OPEN),_Digits),
                     " NLb_fun = ", NormalizeDouble(NLb_fun,_Digits));
               Modify = true;
 if(Modify)
              {
               Print(" серия рыночных позиций BUY назначена к переводу в безубыток, текущией позы POSITION_PRICE_OPEN = ",
               NormalizeDouble(PositionGetDouble(POSITION_PRICE_OPEN),_Digits)," тикет = ",PositionGetInteger(POSITION_TICKET));
                
               trade.PositionModify(_Symbol,SymbolInfoDouble(_Symbol, SYMBOL_BID) - 50*_Point,PositionGetDouble(POSITION_TP));
               Print(" Перенос в бу стоп лосса позиции Buy № ",  PositionGetInteger(POSITION_TICKET));
    ...
           } // к if(Modify)
        }    // к if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY) 

...

posso usare una semplice sezione di codice come enumerazione di posizioni per un trawl con posizioni di mercato HEDGE - grazie.

il problema è risolto! Congratulazioni ancora una volta a Vladimir Karputov!!!

con la sua pesca a strascico!

https://www.mql5.com/ru/code/17263

il trucco chiave è guardare l'indice nel ciclo e modificarlo con l'opzione ticket!!!

//--- при таком методе мы будет сюда попадать на каждом тике.
   for(int i=PositionsTotal()-1;i>=0;i--)
      if(m_position.SelectByIndex(i))
         if(m_position.Symbol()==Symbol() && m_position.Magic()==m_magic)
           {
            //--- TrailingStop -> подтягивание StopLoss у ПРИБЫЛЬНОЙ позиции
            if(m_position.PositionType()==POSITION_TYPE_BUY)
              {
               //--- когда у позиции ещё нет StopLoss
               if(m_position.StopLoss()==0)
                 {
                  //--- пока StopLoss равен 0.0, TrailingStep не учитываем
                  if(m_symbol.Bid()-ExtTrailingStop>m_position.PriceOpen())
                    {
                     //--- модификация позиции
                     m_trade.PositionModify(m_position.Ticket(),m_position.PriceOpen(),0.0);
                    }
                 } 
TrailingStop
TrailingStop
  • www.mql5.com
Пример советника с реализацией Trailing Stop.
 

Un compito semplice: è necessario eliminare tutti gli elementi di ArrayJ che hanno lo stesso indice e valore degli elementi di ArrayI:

int OnInit()
  {
   int CommonArray[]={1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 13, 13, 13, 13, 13, 13, 13};
   int ArrayI[20]=   {0, 0, 0, 0, 0, 0, 0, 8, 9, 10,  0, 12, 13, 13, 13, 13,  0,  0, 13,  0};
   int ArrayJ[];

   for(int j=0; j<ArraySize(ArrayI); j++)
   {
      ArrayResize(ArrayJ,j+1);
      ArrayJ[j]=CommonArray[j];
   }

   ArrayPrint(ArrayI);
   ArrayPrint(ArrayJ);

   for(int i=0; i<ArraySize(ArrayI); i++)
      if(ArrayI[i])
         for(int j=0; j<ArraySize(ArrayJ); j++)
            if(ArrayI[i]==ArrayJ[j])
               ArrayRemove(ArrayJ,j,1);

   ArrayPrint(ArrayJ);
//---
   return(INIT_SUCCEEDED);
  }

La stringa di tasti è evidenziata. Risultato:

2022.02.26 13:56:48.489 test (NZDUSD,H4)         0  0  0  0  0  0  0  8  9 10  0 12 13 13 13 13  0  0 13  0
2022.02.26 13:56:48.489 test (NZDUSD,H4)         1  2  3  4  5  6  7  8  9 10 11 12 13 13 13 13 13 13 13 13
2022.02.26 13:56:48.489 test (NZDUSD,H4)         1  2  3  4  5  6  7 11

Previsto:

2022.02.26 13:56:48.489 test (NZDUSD,H4)         0  0  0  0  0  0  0  8  9 10  0 12 13 13 13 13  0  0 13  0
2022.02.26 13:56:48.489 test (NZDUSD,H4)         1  2  3  4  5  6  7  8  9 10 11 12 13 13 13 13 13 13 13 13
2022.02.26 13:56:48.489 test (NZDUSD,H4)         1  2  3  4  5  6  7          11                13 13    13

ArrayJ è dinamico, sembra che ci sia qualcosa che non va... Ma non ho nemmeno bisogno di uno statico.

Mi ha spezzato il cuore. COSA C'È? O è l'equivalente della vecchia canzone:

https://www.mql5.com/ru/forum/1111/page3141#comment_27152680

и

https://www.mql5.com/ru/forum/1111/page3142#comment_27371998

sulle costanti nominate?

Ошибки, баги, вопросы
Ошибки, баги, вопросы
  • 2022.01.28
  • www.mql5.com
Общее обсуждение: Ошибки, баги, вопросы
 
x572intraday elementi di ArrayI:

La stringa di tasti è evidenziata. Risultato:

Previsto:

ArrayJ è dinamico, sembra che ci sia qualcosa che non va... Ma non ho nemmeno bisogno di uno statico.

1. ArrayResize sarebbe meglio spostato fuori dal ciclo.

ArrayResize(ArrayJ,ArraySize(ArrayI));
for(int j=0; j<ArraySize(ArrayI); j++)
   {
      ArrayJ[j]=CommonArray[j];
   }

2. ArrayRemove non rende un elemento dell'array "vuoto", ma "sposta" gli elementi successivi al suo posto. Quindi la corrispondenza degli elementi negli indici successivi è interrotta.

 
JRandomTrader #:

1. ArrayResize dovrebbe essere spostato fuori dal ciclo

2. ArrayRemove non rende un elemento dell'array "vuoto", ma "sposta" gli elementi successivi al suo posto. Quindi la corrispondenza degli elementi negli indici successivi è interrotta.

Non c'è dubbio sul 2, ho solo messo gli intervalli per renderlo più chiaro. Inoltre, in Help si dice di un array statico:"Se la funzione è usata per un array di dimensione fissa, la dimensione dell'array stesso non cambia: la "coda" rimanente è fisicamente copiata nella posizione iniziale."L'esempio nella Guida usa anche un array di dimensioni fisse, mentre io ne ho uno dinamico.

Re 1. Non possiamo metterlo fuori da un ciclo, poiché in un compito reale non conosciamo in anticipo né la dimensione di ArrayJ né quella di ArrayI, e tanto meno quella di CommonArray, poiché non coincidono tutte.

Ho anche un esempio in cui il rimescolamento degli elementi non rompe a metà, come in questo esempio:

int OBJTFVArray[]={1, 2, 3, 4, 5, 6, 10, 12, 1520, 30, 16385, 16386, 16387, 16388, 16390, 16392, 16396, 16408, 32769, 49153, 49154, 49155, 49156, 49157, 49158, 49159, 49160};
int PArray[20]={0, 0, 0, 0, 0, 00, 16390, 16392, 163960, 32769, 49153, 49153, 49153, 49153, 0, 0, 49153, 0};
int PArray_[];

int OnInit()
  {
   for(int p_=0; p_<ArraySize(PArray); p_++)
   {
      ArrayResize(PArray_,p_+1);
      PArray_[p_]=OBJTFVArray[p_+8];
   }

   ArrayPrint(PArray);
   ArrayPrint(PArray_);

   for(int p=0; p<ArraySize(PArray); p++)
      if(PArray[p])
         for(int p_=0; p_<ArraySize(PArray_); p_++)
            if(PArray[p]==PArray_[p_])
               ArrayRemove(PArray_,p_,1);

   ArrayPrint(PArray_);

   return(INIT_SUCCEEDED);
  }

Il risultato è buono:

 0     0     0     0     0     0     0 16390 16392 16396     0 32769 49153 49153 49153 49153     0     0 49153     0
15    20    30 16385 16386 16387 16388 16390 16392 16396 16408 32769 49153 49154 49155 49156 49157 49158 49159 49160
15    20    30 16385 16386 16387 16388                   16408             49154 49155 49156 49157 49158 49159 49160

Ma è necessario che quella variante funzioni. L'intoppo apparentemente accade se ci sono elementi con lo stesso valore (vedi post precedente) nella coda a destra - che è simile al problema a cui mi riferivo sopra.

 
x572intraday #:

Non ci sono domande sul 2, ho messo gli intervalli per chiarezza. Inoltre, in Help si dice di array statico:"Se la funzione è usata per un array di dimensione fissa, la dimensione dell'array stesso non cambia: copia fisicamente la "coda" rimanente alla posizione iniziale."L'esempio nella Guida usa anche un array di dimensioni fisse, mentre io ne ho uno dinamico.

Re 1. Non possiamo metterlo fuori da un ciclo, poiché in un compito reale non conosciamo in anticipo né la dimensione di ArrayJ né quella di ArrayI, e tanto meno quella di CommonArray, poiché non coincidono tutte.

Ho anche un esempio in cui il rimescolamento degli elementi non rompe a metà, come in questo esempio:

Il risultato è buono:

Ma ho bisogno che quella variante funzioni. L'intoppo apparentemente accade se ci sono elementi con lo stesso valore nella coda a destra (vedi post precedente) - che è simile al problema a cui ho fatto riferimento sopra.

1. Si può e si deve togliere dal loop, nel modo che ho mostrato. A meno che la dimensione di ArrayI non cambi durante il ciclo.

2. Poi qualcosa del genere

int k=0; // объявляем до цикла - чтобы использовать после
for(int i=0; i<ArraySize(ArrayI); i++) // после предыдущего кода (1) размеры ArrayI и ArrayJ равны
  if(ArrayI[i]!=ArrayJ[i])
    {
     ArrayJ[k++]=ArrayI[i];
    }
ArrayResize(ArrayJ,k);
Motivazione: