Discussione sull’articolo "Scrivere un Expert Advisor Utilizzando l'Approccio di Programmazione Orientato agli Oggetti MQL5" - pagina 2

[Eliminato]  
Yedelkin:
Se il Bid all'apertura sarà a 1,2695, abbiamo già 5 pip di perdita automatica. Se allo stesso tempo lo SL è di 50 pips secondo l'idea dello sviluppatore, allora devono passare altri 45 pips nella direzione sfavorevole prima che si attivi. Cioè, quando scatta lo stoploss, il Bid non dovrebbe essere a 1,2645, ma a 1,2650; e l'Ask, rispettivamente, a 1,2655.

1. Riguardo alla perdita di 5 pips all'apertura.

Hai ragione sulla perdita, se chiudiamo la posizione nello stesso momento (condizionatamente) otterremo una perdita pari allo spread, proprio 5 pips.

Poiché i long vengono chiusi al prezzo Bid (contro).

Almeno logicamente in questo caso dovremmo ottenere questa perdita (ed è corretto).

Questo vale anche per la chiusura con un ordine counter. Quale risultato pensate che otterremo quando il contro-ordine viene attivato al prezzo di 1,2695 (che è dove si trova il Bid al momento)?

Non sosterrete che il prezzo di apertura delle posizioni SHORT è Ask?

2. Occupiamoci della chiusura del BU

Ricordiamo che abbiamo aperto in Buy a 1,27 (questo prezzo è ora un livello BU per noi).

È ragionevole supporre che la chiusura BU si verificherà se il prezzo Bid raggiungerà 1,27 (cioè salirà esattamente di 5 pip).

Verifichiamo la nostra affermazione chiudendo il CU con l'aiuto di un contro-ordine. Il prezzo di apertura di una posizione di questo tipo dovrebbe essere a 1,27 e, come sappiamo, gli ordini di vendita vengono piazzati al Bid. Attualmente il Bid è a 1,2695. Pertanto, per chiudere nella BU è necessario superare 5 pips, quindi non c'è alcun errore nei calcoli e l'affermazione è corretta.

3. riguardo a SL e TP

Qui valgono due affermazioni:

а. I long aprono all'Ask e chiudono al Bid; gli short aprono al Bid e chiudono all'Ask.

б. La distanza dal TP e dallo SL viene calcolata a partire dal prezzo di apertura; il calcolo tiene conto della direzione della posizione.


In accordo con la seconda affermazione, determineremo i prezzi SL e TP per il nostro esempio. Al prezzo di apertura 1,27 SL = 1,2650 e TP = 1,28 (secondo le condizioni descritte sopra).

In base alla prima affermazione, il LONG (e nell'esempio è il LONG) si aprirà a condizione che l'Ask sia pari a 1,27 (e il Bid sia pari a 1,2695, in base allo spread di 5 pips). 4. Ora determiniamo in base alla prima affermazione lo SL e il TP per il nostro esempio.

4. Ora determiniamo in quali condizioni si attiveranno i nostri SL e TP.

La nostra posizione sarà chiusa quando una delle condizioni sarà soddisfatta (se non ci sono altri fattori):

Sul TP - Se il Bid raggiunge 1,28 (100 pips da 1,27), l'Ask in questo momento sarà a 1,2805 (la prima affermazione e la dimensione della regola dello spread qui).

Verifichiamo la nostra affermazione chiudendo sul TP utilizzando una posizione contraria. Il prezzo di apertura di tale posizione dovrebbe essere a 1,28 e, come sappiamo, gli ordini di vendita vengono piazzati al Bid. Attualmente il Bid è a 1,2695. Pertanto, per chiudere il TP è necessario passare 5 pip (per coprire le perdite sullo spread) + 100 pip per fissare il profitto.

Su SL - Se il prezzo raggiunge il livello SL, pari a 1,2650 come ricordiamo.


Ora cerchiamo di capire quale sarà il prezzo. Logicamente, dovrebbe essere il prezzo Bid (che corrisponde al prezzo di apertura del contro-ordine).

Ricordiamo che attualmente (secondo la condizione di apertura della posizione) il Bid è a 1,2695. Pertanto, il prezzo deve superare i 45 pip prima che scatti lo SL.

Pertanto, registreremo una perdita pari allo spread (5 pips) + 45 pips che il prezzo ha avuto il tempo di superare prima che scattasse lo SL.

Da questo punto di vista avete ragione

Verifichiamo la nostra affermazione chiudendo lo SL con una posizione contraria. Il prezzo di apertura di tale posizione dovrebbe essere a 1,2650 e, come sappiamo, gli ordini di vendita si aprono al Bid. Attualmente il Bid è a 1,2695. Pertanto, per chiudere lo SL è necessario passare 45 pips. Quando lo SL viene attivato, si registrerà una perdita di 50 pips (5 pips sullo spread + 45 pips sul movimento contro di noi).

PS

Ma da questo punto di vista, questo esempio per MQL4 non mi è molto chiaro.

int ticket;

  if(iRSI(NULL,0,14,PRICE_CLOSE,0)<25)
    {
     ticket=OrderSend(Symbol(),OP_BUY,1,Ask,3,Bid-25*Point,Ask+25*Point,"My order #"+counter,16384,0,Green);
     if(ticket<0)
       {
        Print("OrderSend failed with error #",GetLastError());
        return(0);
       }
    }

Più precisamente, non mi è molto chiaro sulla base di quale logica e di quali affermazioni viene considerato lo SL e solo esso.

Ma basandomi su questo esempio (e solo su di esso) ottengo quanto segue

/Esempio di base
ticket=OrderSend(Symbol(),OP_BUY,1,Ask,3,SL = Bid-Loss*Point,TP = Ask+Profit*Point,"My order #"+counter,16384,0,Green);
//Ordine di apertura di una posizione di mercato
ticket=OrderSend(Symbol(),OP_BUY,1,1.27,3,1.2645 = 1.2695-50*Point,1.28 = 1.27+100*Point);

Sulla base dei valori Open = 1,27, SL = 1,2645 e TP = 1,28 capisco quanto segue:

1. La posizione viene aperta quando Ask raggiunge il prezzo di 1,27 (nel nostro caso è già lì);

2. Il livello BU si trova al prezzo di 1,27 e per chiudere su di esso il tasso del simbolo (nel nostro caso EUR) deve crescere della dimensione dello spread (nel nostro caso 5 pip);

3. Al momento dell'apertura, si ottiene immediatamente una perdita pari all'importo dello spread (nel caso in cui si chiuda la posizione IMMEDIATAMENTE), perché la posizione aperta, sulla base di affermazioni logiche, dovrebbe essere chiusa con un contro-ordine. Nel codice MQL4, un'operazione di questo tipo si presenterà come segue

/Esempio di base
ticket=OrderSend(Symbol(),OP_SELL,1,Bid,3,0,0);
//Chiusura di una posizione sul mercato con un ordine di contropartita
ticket=OrderSend(Symbol(),OP_SELL,1,1.2695,3,0,0);

4. Il TP viene attivato dopo che il prezzo ha raggiunto il livello di 1,28. Logicamente, questo dovrebbe essere il prezzo Bid, poiché l'ordine contatore è stato aperto a questo prezzo (l'operazione viene eseguita quando il prezzo Bid raggiunge il valore di 1,28). Su questa base, la chiusura nel codice MQL4 dovrebbe apparire come segue

//Chiusura di una posizione TP con un ordine di mercato (contro-ordine)
ticket=OrderSend(Symbol(),OP_SELL,1,1.28,3,0,0);
/Chiusura di una posizione con un ordine in attesa di contatore (limitatore)
ticket=OrderSend(Symbol(),OP_SELLLIMIT,1,1.28,3,0,0);

5. Lo SL verrà attivato dopo che il tasso del simbolo negoziato (nel nostro caso EUR) scenderà di 50 pip dal momento dell'apertura.


Ora la cosa più interessante

Verifichiamo l'apertura di una posizione di mercato sulla base dello stesso esempio riportato nella Guida di MQL4 (un esempio classico, che probabilmente è stato utilizzato da migliaia di persone).

Utilizzeremo questo codice per verificarlo

//+------------------------------------------------------------------+
double PriceOpen,PriceSL,PriceTP;
int ticket;
//+------------------------------------------------------------------+
//Formulare i prezzi per l'ordine
PriceOpen = Ask;
PriceSL   = Bid-500*Point;
PriceTP   = PriceOpen+1000*Point;
//Ordine di apertura di una posizione di mercato
ticket = OrderSend(Symbol(),OP_BUY,0.10,PriceOpen,5,PriceSL,PriceTP);
//+------------------------------------------------------------------+

Eseguendo questo codice sul server di Alpari (utilizzando quotazioni reali) si ottiene il seguente risultato

2010.08.24 09:12:47 '******': instant order buy 0.10 EURUSD at 1.26292 sl: 1.25776 tp: 1.27292

È facile intuire che in questo caso otterremo le seguenti grandezze SL = 516 (ovvero 51 pip per 4 cifre) TP = 1000 (ovvero 100 pip per 4 cifre)

PPS

Diamo un'occhiata alla guida di MQL4:

Parametri:
simbolo - Nome dello strumento finanziario con cui viene eseguita l'operazione di compravendita.
cmd - Operazione di compravendita. Può essere uno qualsiasi dei valori dell'operazione di compravendita.
volume - Numero di lotti.
prezzo - Prezzo di apertura.
slittamento - Deviazione massima consentita del prezzo per gli ordini di mercato (ordini di acquisto o di vendita).
stoploss - Prezzo di chiusura della posizione al raggiungimento del livello di perdita (0 in caso di assenza di livello di perdita).
takeprofit - Prezzo di chiusura della posizione al raggiungimento del livello di redditività (0 in caso di assenza di livello di redditività).
commento - Testo del commento dell'ordine. L'ultima parte del commento può essere modificata dal server commerciale.
magia - Numero magico dell'ordine. Può essere utilizzato come identificatore definito dall'utente.
scadenza - Periodo di scadenza dell'ordine pendente.
colore_freccia - Colore della freccia di apertura sul grafico. Se il parametro è assente o il suo valore è CLR_NONE, la freccia di apertura non viene visualizzata sul grafico.
Esempio:
  int ticket; if(iRSI(NULL,0,14,PRICE_CLOSE,0)<25) { ticket=OrderSend(Symbol(),OP_BUY,1,Ask,3,Bid-25*Point,Ask+25*Point, "My order #"+counter,16384,0,Green); if(ticket<0) { Print("OrderSend failed with error #",GetLastError()); return(0); } } }

"Dimmi dov'è la verità fratello?"...?

OrderSend - Документация на MQL4
  • docs.mql4.com
OrderSend - Документация на MQL4
[Eliminato]  
Yedelkin:

Non capisco la seguente parte del codice:

// Copia il prezzo di chiusura della barra precedente (barra 1) nella variabile Expert Advisor corrispondente
   Cexpert.setCloseprice(mrate[1].close);  // prezzo di chiusura della barra 1
//--- Controllare se c'è una posizione di acquisto
   if (Cexpert.checkBuy()==true)
   {
      if (Buy_opened) 
         {
            Alert("Abbiamo già una posizione da acquistare!!!".); 
            return;    // Non aggiungere alla posizione lunga
         }
      double aprice = NormalizeDouble(latest_price.ask,_Digits);
      double stl    = NormalizeDouble(latest_price.ask - STP*_Point,_Digits);
      double tkp    = NormalizeDouble(latest_price.ask + TKP*_Point,_Digits);
      int    mdev   = 100;
      // effettuare l'ordine
      Cexpert.openBuy(ORDER_TYPE_BUY,Lot,aprice,stl,tkp,mdev);
   }
Se stiamo per aprire una posizione di acquisto, dovremmo concentrarci sul prezzo latest_price.ask, ma quando impostiamo uno Stop Loss e un Take Profit per tale posizione - sul prezzo latest_price.bid. È corretto? Perché nel testo del codice lo Stop Loss e il Take Profit vengono impostati sulla base del prezzo ask? Si tratta di un refuso o di una peculiarità di una particolare strategia (il codice ha una costruzione simile per l'apertura di una posizione Sell)?

Questa parte del codice deve essere compresa sulla base delle seguenti affermazioni:

а. Long - aprire a Ask e chiudere a Bid; Short - aprire a Bid e chiudere a Ask;

б. Le posizioni sono chiuse da ordini contrari;

в. Il livello di BU è al prezzo di apertura;

г. La distanza da TP e SL viene calcolata a partire dal prezzo di apertura (livello CU);

д. Il TP si attiverà quando il prezzo Bid raggiungerà un livello pari al prezzo di apertura + la dimensione del profitto;

e. SL si attiverà quando il titolo raggiungerà il livello Bid pari a Open Price - Loss size.

L'autore dell'Expert Advisor è stato probabilmente guidato da affermazioni simili nel suo lavoro. Per rendere tutto il più chiaro possibile, vi propongo un'illustrazione di quanto sopra con l'aiuto della seguente schermata (ci interessa il rettangolo rosso).


 
Interesting:

e. Lo SL verrà attivato quando il prezzo Bid raggiungerà un livello pari al prezzo di apertura - dimensione della perdita.

Grazie, capisco la logica. Tuttavia, in base al punto "e" risulta che quando si attiva lo stoploss, il Bid non dovrebbe essere a 1,2645, ma a 1,2650; e l'Ask, rispettivamente, a 1,2655.

[Eliminato]  
Yedelkin:

Grazie, capisco la logica. Ma comunque, secondo il punto "e" risulta che quando viene attivato uno stop-loss, il Bid non dovrebbe essere a 1.2645, ma a 1.2650; e l'Ask, rispettivamente, a 1.2655.

Potrebbe essere così, è necessario verificare cosa succede esattamente quando il mercato attiva uno stop-loss (o aggiustare il modello della matrice tenendo conto di tutte le possibilità di chiusura disponibili)....


Per quanto riguarda il punto "e" (a mio avviso)

In caso di conteggio dall'Open (Ask) sarà 1.27-50 = 1.2650 (il prezzo passerà 45 pips e la posa si chiuderà), se ho capito bene. In questo caso penso che lo SL dovrebbe funzionare a Bid 1.2650 e Ask 1.2655.

Un'altra cosa, se contiamo dal Bid, allora otterremo il prezzo 1,2695-50 - 1,2645 (non si può discutere con la matematica). Se calcoliamo lo SL dal Bid, otterremo 1.27-1.2645 = 55 pips (che, a quanto ho capito, non faceva parte dei nostri piani).

PS

Per lo meno, questo modello ci permette di rompere correttamente i livelli di SL e TP dal prezzo di apertura (a mio parere correttamente)...

Naturalmente, sarebbe interessante sentire l'opinione ufficiale degli sviluppatori su come i prezzi dovrebbero essere calcolati in realtà (non solo SL e TP).

 

Domanda.


100 verdoni - sono in rubli o in valuta estera? ;)

 
che era stato promesso di sparire.
 
Jager:

Domanda.


100 verdoni - sono in rubli o in valuta estera? ;)

Questo è il valore di timeout in millisecondi. Questo parametro è già stato rimosso da tutte le funzioni di trading.
 

Ciao, grazie per l'esempio ben esposto.

Ma devo chiederti se è giusto?

L'EA verifica la presenza di un'opportunità di trading all'inizio di ogni nuova barra.

Nella funzione getbuffers() della classe recupera i dati delle ultime 3 barre partendo dalla barra 0 che si è appena formata e quindi il valore è errato.

void MyExpert::getBuffers()
{
if(CopyBuffer(ADX_handle,0,0,3,ADX_val)<0 || CopyBuffer(ADX_handle,1,0,3,plus_DI)<0
|| CopyBuffer(ADX_handle,2,0,3,minus_DI)<0 || CopyBuffer(MA_handle,0,0,3,MA_val)<0)

Non dovrebbe recuperare i dati dell'indicatore delle ultime 3 barre a partire dalla posizione 1?

Grazie

 

Grande articolo Samuel

Grazie in anticipo per questo inestimabile articolo,

Quindi, sulla base di questo articolo, potremmo includere funzioni come IsNewBar o Buy_opened nella classe e chiamarle semplicemente da EA.

Grazie ancora,

Spero di vedere altri articoli da te,

Hamed,

 

Per favore aiutatemi a capire qualcosa che non capisco:

All'inizio dell'EA la funzione è chiamata:

  Cexpert.doInit(ADX_Period,MA_Period);
при этом для ее корректного выполнения требуются уже установленные параметры symbol  и period :
//+-----------------------------------------------------------------------+
// FUNZIONI PUBBLICHE DELLA NOSTRA CLASSE 
//+-----------------------------------------------------------------------+
/*
 Inizializzazione di 
*/
void MyExpert::doInit(int adx_period,int ma_period)
{
   //--- Ottenere l'handle dell'indicatore ADX
   ADX_handle=iADX(symbol,period,adx_period);
  //--- Ottenere l'indicatore della media mobile
   MA_handle=iMA(symbol,period,ma_period,0,MODE_EMA,PRICE_CLOSE);
однако, заполнение этих параметров конкретными значениями происходит позже, уже после Cexpert.doInit :
//--- avviare la funzione di inizializzazione
   Cexpert.doInit(ADX_Period,MA_Period);
//--- impostazione di tutte le variabili necessarie per il nostro oggetto di classe
   Cexpert.setPeriod(_Period);     // imposta il periodo
   Cexpert.setSymbol(_Symbol);     // specifica il simbolo (coppia di valute)
   
   Никак не пойму, как может правильно выполниться Cexpert.doInit, если переменной symbol пока не присвоено
значение (или как-то присвоено ?) Застрял тут и дальше никак . Спасибо.