Domande dai principianti MQL4 MT4 MetaTrader 4 - pagina 247

 
Valeriy Yastremskiy #:

Inserisci il codice correttamente, alt S o per icona, hint code.

Perché avete bisogno di un arraySaveTick?

Si usano solo 2 elementi dell'array. Sostituitele con variabili globali o statiche se le dichiarate in una funzione.

Non ha senso usare un array per 2 variabili.

E sembra che tu chiami gli array prima che venga chiamata la funzioneFindTick(), in cui viene impostata la dimensione dell'array SaveTick. E c'è un superamento dell'array.

Grazie. Capito.
Puoi dirmi qual è l'errore, mi sembra che la funzione non stia contando correttamente


***
 
makssub #:

Grazie. Capito.
Puoi dirmi qual è l'errore, mi sembra che la funzione non stia contando correttamente


Inserite il codice correttamente, è la tredicesima casella in cima alla finestra delle risposte.

E potete scrivere a parole cosa fa la funzione riga per riga.

Certamente non sembra corretto.

Non capisco dove e come la variabile Tick viene assegnata al biglietto d'ordine. E non c'è bisogno di controllare il numero magico e il tipo di ordine con la seguente condizione
_magic < 0 || OrderMagicNumber() == _magic
Se la funzione è chiamata con un numero magico inferiore a zero o il numero magico è uguale all'ordine selezionato, richiederemo la dimensione del punto e se è uguale a zero cercheremo un valore vuoto nel simbolo dell'ordine... e così via.

Oh, e ricordate, l'order select riempie la struttura dei dati dell'ordine e la memorizza. E solo dopo la prossima selezione dell'ordine con un numero d'ordine o un biglietto diverso, i dati in questa struttura cambieranno.

Cioè, OrderSend non riempie la struttura dati dell'ordine, ma restituisce il biglietto dell'ordine o meno 1. E la struttura dell'ordine è riempita solo da OrderSelect. E poi i dati di questo ordine possono essere ottenuti da questa struttura.

 
Valeriy Yastremskiy #:

Inserisci il codice correttamente, è la tredicesima casella nella parte superiore della finestra delle risposte.

E potete scrivere a parole cosa fa la funzione riga per riga.

Sembra essere sbagliato, naturalmente.

E non è chiaro dove e come la variabile Tick sia assegnata al biglietto dell'ordine. E non c'è bisogno di controllare il numero magico e il tipo di ordine con la seguente condizione
_magic < 0 || OrderMagicNumber() == _magic
Se la funzione è chiamata con un numero magico inferiore a zero o il numero magico è uguale all'ordine selezionato, richiederemo la dimensione del punto e se è uguale a zero cercheremo un valore vuoto nel simbolo dell'ordine... e così via.

Oh, e ricordate, l'order select riempie la struttura dei dati dell'ordine e la memorizza. E solo dopo la prossima selezione dell'ordine con un numero d'ordine o un biglietto diverso, i dati in questa struttura cambieranno.

Cioè, OrderSend non riempie la struttura dati dell'ordine, ma restituisce il biglietto dell'ordine o meno 1. E la struttura dell'ordine è riempita solo da OrderSelect. E poi da questa struttura possiamo ottenere i dati di questo ordine.

int FindTicket()
   {
   int oldticket;
   int tick=0;
   ticket=0;
   
   
   for(int cnt = OrdersTotal ()-1; cnt>=0; cnt--)
      {
      if(OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES))
         {
         if (OrderSymbol() == Symbol() && OrderMagicNumber() == Magic)
            {
            oldticket = OrderTicket();
            if (oldticket > ticket)
               {
               ticket = oldticket;
               tick = OrderTicket();
               }
            }
         }
      }
   return(tick); 
   }              
int TickF = FindTicket();
int CalculateProfitHistory() 
{
  double _point;
  int    i, _ototal = OrdersHistoryTotal(), _profit=0;
  for   (i = 0; i < OrdersHistoryTotal(); i++) 
  {
    if (OrderSelect(TickF, SELECT_BY_TICKET, MODE_HISTORY)) 
    {
      if (OrderSymbol() == Symbol())
      {
        if (OrderMagicNumber() == Magic) 
        {
           _point = MarketInfo(OrderSymbol(), MODE_POINT);
           if (_point == 0) 
           {
              if (StringFind(OrderSymbol(), "") < 0) 
                 _point = 0.0001; 
              else _point = 0.01;
           }   
           if (OrderType() == OP_BUY) 
           {
              _profit += int((MarketInfo(OrderSymbol(), MODE_BID) - OrderOpenPrice())/_point);
           }
           if (OrderType()==OP_SELL) 
           {
              _profit += int((OrderOpenPrice() - MarketInfo(OrderSymbol(), MODE_ASK))/_point);
           }
         }
      }
    }
  }
  return(_profit);
}

Nella prima funzione, troviamo il ticket d'ordine richiesto e la seconda funzione dovrebbe calcolare il profitto di tutti gli ordini chiusi dopo quel ticket. Il profitto di quegli ordini che erano prima non mi interessa. Ma il secondo non lo calcola correttamente. Quando un ordine viene aperto queste 2 funzioni vengono chiamate e quindi dovrebbe essere uguale a 0, ma non lo è.
PS ha seguito il tuo consiglio, rinunciando agli array)
12° box sopra)

 
makssub #:

Nella prima funzione, trovo il ticket dell'ordine richiesto, e la seconda funzione dovrebbe calcolare il profitto di tutti gli ordini chiusi dopo questo ticket. Non mi interessa il profitto di quelli precedenti.
PS ha seguito il tuo consiglio, ho rifiutato gli array)
il 12° quadrato dall'alto)

La prima funzione trova il biglietto con il numero più alto, se i biglietti aumentano con i numeri)) All'iterazione successiva del ciclo, il biglietto dell'ordine numerato successivo viene confrontato con il biglietto dell'ordine precedente. La selezione dell'ordine riempie la struttura dell'ordine, e OrderTicket recupera il valore del biglietto da questa struttura.

Scrivi o leggi da solo cosa fa ogni linea di codice.

Nella seconda funzione, OrderSelect riempirà la struttura dell'ordine con gli stessi dati del biglietto)

 
Valeriy Yastremskiy #:

La prima funzione trova il biglietto con il numero più alto, se i biglietti aumentano con i numeri)) All'iterazione successiva del ciclo, il biglietto dell'ordine numerato successivo viene confrontato con il biglietto dell'ordine precedente. La selezione dell'ordine riempie la struttura dell'ordine, e OrderTicket recupera il valore del biglietto da questa struttura.

Scrivi o leggi da solo cosa fa ogni linea di codice.

Nella seconda funzione, OrderSelect riempirà la struttura dell'ordine con gli stessi dati del biglietto)

Spiegato, ma sembra che non sia buono con la logica rispetto a questa lingua. Potete dirmi come determinare il biglietto dell'ultimo ordine aperto?

Come faccio a calcolare il profitto di tutti gli ordini chiusi che lo seguono?

 
makssub #:

Spiegato, ma sembra che sia male con la logica in relazione a questa lingua. Potete dirmi come determinare il biglietto dell'ultimo ordine aperto?

Come faccio a calcolare il profitto di tutti gli ordini chiusi che lo seguono?

Al momento dell'apertura di un ordine. E non dovremmo usare il numero d'ordine. Oppure dobbiamo memorizzare nella nostra base i numeri d'ordine, i biglietti, lo stato degli ordini e il tempo di apertura/chiusura.

 if(OrderSelect(Ticket, SELECT_BY_TICKET)==true) // Если выбор рыночного ордера произошел успешно
        {
         if(OrderCloseTime()==0)              // Если наш рыночный ордер не закрыт           {
            
            //           Alert("Наш рыночный ордер жив, Модифицируем его если нужно ");
            if(Tral_Stop!=0 || Tral_Profit!=0)
          {     ModifyTral(); }
            return;
           }
         if(OrderCloseTime()!=0)              // Если наш рыночный ордер закрылся
         {
Alert("Our market order has closed. The Adviser's work is completed ",
                  " Swap = ", OrderSwap(), " Commission = ", OrderCommission(),"Profit/loss = ",OrderProfit());
         // ..... // получаем профит и считаем общий профит например
         }

Ed è meglio ricordare la logica fino alla fine. Allora è più facile. È meglio iniziare con i dati necessari, e ci dovrebbero essere abbastanza dati per una decisione)

Abbiamo un tempo aperto di ordini (non in sospeso). Abbiamo i loro biglietti. Abbiamo un prezzo aperto, SL e TP di ogni ordine a mercato. E c'è un tempo di chiusura dell'ordine. E dopo la chiusura dell'ordine, il campo Profit viene riempito.

Questi sono i dati di cui abbiamo bisogno per creare la logica di questi campi.

La frase "ordini chiusi dopo l'ultimo ordine aperto" non è definita affatto. Possono andare per numero, per biglietto e per tempo.

 
Valeriy Yastremskiy #:

Entro l'orario di apertura dell'ordine. Dovrebbe essere il più grande)

Lo scrivi correttamente, ma il codice sembra un po' complicato )))))

Io lo farei nel modo in cui lo metti tu:

int GetTicketLastOpenOrder()
{
   int ticket = -1;
   datetime t = 0;
   for(int i = OrdersTotal() - 1; i >= 0; i--)
   {
      if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES) && OrderType() <= OP_SELL && OrderOpenTime() > t)
      {
         ticket = OrderTicket();
         t = OrderOpenTime();
      }
   }
   return(ticket);
}


ZS: OrderSelect() per numero di ticket impiegherà molto più tempo per essere eseguito rispetto a una semplice ricerca per ordini aperti

 
Igor Makanu #:

Lo scrivi correttamente, ma il codice è un po' contorto ))))

Basta seguire le sue istruzioni:


S : OrderSelect() per numero di ticket richiederà molto più tempo per l'esecuzione rispetto a una semplice enumerazione degli ordini aperti

Grazie Igor, è solo quando non capiscono l'essenza, il codice giusto per qualcosa non trasmette l'essenza, quindi chiedo di mettere algoritmi non complicati in parole))))

 
Valeriy Yastremskiy #:

Entro l'orario di apertura dell'ordine. Dovrebbe essere il più grande) E solo non per numero d'ordine, e spesso anche il ticketing non è utile. Oppure memorizza i numeri d'ordine, i biglietti, lo stato dell'ordine e i tempi di apertura/chiusura nel tuo database.

Ed è meglio ricordare la logica fino alla fine. Allora è più facile. È meglio iniziare con i dati necessari, e ci dovrebbero essere abbastanza dati per una decisione)

Abbiamo un tempo aperto di ordini (non in sospeso). Abbiamo i loro biglietti. Abbiamo un prezzo aperto, SL e TP di ogni ordine a mercato. E c'è un tempo di chiusura dell'ordine. E dopo la chiusura dell'ordine, il campo Profit viene riempito.

Questi sono i dati di cui abbiamo bisogno per creare la logica di questi campi.

La frase "ordini chiusi dopo l'ultimo ordine aperto" non è definita affatto. Possono andare per numero, per biglietto e per tempo.

Grazie mille per le vostre risposte. Ho implementato alcuni dei vostri suggerimenti.
Ho scritto una funzione che trova la spunta giusta.
Scritto una funzione che conta il profitto di tutti gli ordini chiusi dopo il tick d'ordine desiderato della funzione selezionata. Ora non mi resta che correggerlo secondo le vostre raccomandazioni e aggiungere un controllo per tempo ecc.

tpl = NormalizeDouble(Bid - ProfitLock*Point, Digits);
            ticket = OrderSend (Symbol(), OP_SELL, lastlot, Bid, Slippage, 0, tpl, "",Magic, 0, Red);


double CalculateProfitHistory()
{
double order=0,op=0;
int cnt=0;
datetime time=0;
for(int i=OrdersHistoryTotal()-1; i>=0; i--)
      {
      if(OrderSelect(Tick,SELECT_BY_TICKET,MODE_HISTORY))
      {
         if(OrderSymbol()==_Symbol && OrderMagicNumber()==Magic)
         {
            
            
            op += OrderProfit();
            order +=op;
            cnt++;
            
         }
      }
      }
   return(order);
  }

L'unica cosa che mi confonde ora è che non lo calcola correttamente. Se TP esce 0,02 come risultato del test, calcola e scrive 0,1300 in Comment. Può dirmi cosa c'è che non va?

 
Любые вопросы новичков по MQL4 и MQL5, помощь и обсуждение по алгоритмам и кодам
Любые вопросы новичков по MQL4 и MQL5, помощь и обсуждение по алгоритмам и кодам
  • 2021.09.02
  • www.mql5.com
В этой ветке я хочу начать свою помощь тем, кто действительно хочет разобраться и научиться программированию на новом MQL4 и желает легко перейти н...