Problemi di chiusura, per favore aiutatemi - pagina 8

 
Ais:

Ciao Cameofx,
Grazie per la gentile risposta.
Questo sistema di codifica è molto semplice e facile.
Tutto fatto manualmente in MetaEditor.
Infatti, il sistema è stato progettato per sviluppare grandi programmi facilmente e con alta velocità.
Il sistema dovrebbe essere anche flessibile e affidabile.
Cordiali saluti!

Ais, grazie per la tua risposta. Ho imparato molto dai tuoi post :)

Cameo

 

Ciao Amici!

Una cosa del passato mi assilla giorno dopo giorno.
Questa è la documentazione per AIS5 Trade Machine.
Tornerò appena Dio lo deciderà.

Ciao per ora!

 

Ciao Ais
La tua assenza ci mancherà molto. Abbi cura di te.
Diamo il benvenuto al tuo ritorno.
Il tuo amico, Salute

 

Ciao Ais
Al tuo ritorno, mi dispiace caricarti subito di altre domande. Non è il tuo sistema in particolare, ho questo problema con quasi tutti i programmi. Ha a che fare con le funzioni definite dall'utente. Come fa la funzione definita dall'utente a ottenere la sua definizione.
Per esempio:

int       iSignalOpen ()     //       - i      17 l       1 o     //< This is what iSignalOpen function will do.....
{                                                                 //< When the chart is opened, first pass..
if    ( ( iTradeBarTime    == iTime   ( 0 , 0 , 0 ) )   //< false input, EMPTY == (0,0,0)------|
      &&         //                                         &&                                 |--(return)EMPTY
      ( iTradeBarOnce    == 1 ))                        //< true  input, 1 == 1 ---------------|
      return ( EMPTY);
      
// This proves, 'EMPTY' will always be returned when the chart first opens. At the next tick...       
// ... 'iTime' will have parameters, example: (EUR/USD,HOUR_1,1) it is a predefined function so that...
// ... these parameters will be collected so that an expression can be calculated. Where as the... 
// ... 'iTradeBarTime' is not predefined. 'iTradeBarTime' was assigned 'EMPTY' at declaration earlier in the program.
// 'iTradeBarTime' knows that it is 'EMPTY'and nothing else. 
// When and how did 'iTradeBarTime' get deifined to collect data so that it's value can be other than 'EMPTY'? 
// The 'iTradeBarTime' has to have the same values as the 'iTime', or the input will never be 'true'?
// If it is never 'true', the return is always 'EMPTY'? 
Non riesco a trovare nessuna risposta definitiva nel libro o nel forum. In uno schema logico a relè, una porta AND funzionerebbe come l'esempio precedente. Solo quando ci sono due ingressi 'veri', ci sarà un'uscita 'vera'. Solo allora, il controllo continuerà.
Aspettando la vostra risposta. Grazie in anticipo.
Saluti
 

Ciao Huckleberry

Chiariamo questa parte di codice.

1. Probabilmente le difficoltà maggiori:
1.1. tutti gli umani pensano e agiscono in modo diverso;
1.2. Mi piace usare un numero strettamente limitato di tipi di dati;
1.3. Mi piace usare solo tipi di dati "standard":
1.3.1. "int",
1.3.2. "double",
1.3.3. "string";
1.4. Uso altri tipi di dati solo in casi speciali;
1.5. Denoto il tipo degli elementi del mio programma con una piccola lettera nella prima posizione dei nomi:
1.5.1. "i" per il tipo di dati "int",
1.5.2. "d" per il tipo di dati "double",
1.5.3. "s" per il tipo di dati "string",
1.5.4. "r" per il tipo di dati "undefined";
1.6. questa tecnica di programmazione mi aiuta a controllare il casting dei tipi;
1.7. funzioni e costanti predefinite possono avere anche i seguenti tipi di dati:
1.7.1. "bool",
1.7.2. "color",
1.7.3. "datetime";
1.8. Cerco sempre di fare il casting di questi tipi al tipo "int";
1.9. per oggi il mio casting dei dati di solito è implicito;
1.10. alcuni elementi essenziali delle mie tecniche di programmazione:
1.10.1. Mi piaceva usare la coppia di costanti "TRUE" e "EMPTY" invece della coppia di costanti "TRUE" e "FALSE";
1.10.2. Nelle dichiarazioni "if" a volte ho usato "1" e "0" invece di "TRUE" e "FALSE";
1.10.3. Ho usato la costante "EMPTY" con il valore negativo "-1" per indicare risultati non validi per elementi di dati senza segno;
1.10.4. in futuro userò il tipo "bool" con il prefisso "b" nei nomi.

2. Dobbiamo conoscere i seguenti tipi di dati MQL4:
2.1. "int" è un <!>signed</!> numero intero lungo a 4 byte con valori da -2147483648 a 2147483647;
2.2. "datetime" è un <!>unsigned</!> long 4-byte integer number con valori da 0 a 4294967295;
2.3. assegnando valori "datetime" a variabili "int", otteniamo risultati corretti fino a circa 2038.01.01.

3. Dobbiamo conoscere la funzione "iTime ( symbol, timeframe, shift )" come segue:
3.1. questa funzione restituisce sempre un valore di tipo "datetime";
3.2. ci sono 2 casi diversi di ritorno:
3.2.1. "0" se lo storico locale è vuoto;
3.2.2. tempo aperto per la barra indicato con "shift" in tutti gli altri casi;
3.3. "iTime ( 0, 0, 0 )" restituisce il tempo aperto per la barra zero del grafico corrente;
3.4. se la barra zero è la stessa, "iTime ( 0, 0, 0 )" restituisce lo stesso valore;
3.5. quando la barra zero corrente è completata, questa barra è diventata la barra numero 1 e inizia la formazione della nuova barra zero;
3.6. "iTime ( 0, 0, 0 )" restituisce il nuovo valore;
3.7. quindi, il valore di "iTime ( 0, 0, 0 )" cambia quando cambia la barra zero.

4. Abbiamo evitato di lavorare con la storia vuota nel blocco di programma "2.2.3.1. History data inspection".

5. Quando l'ordine viene chiuso con successo nella funzione "iTryClose" assegniamo "iTradeBarTime = iTime ( 0, 0, 0 ) ;".

6. Nella funzione "iSignalOpen" controlliamo se "iTradeBarTime == iTime ( 0, 0, 0 ) )".

7. Se è vero e il trade ripetuto è vietato da "iTradeBarOnce = 1 ;" allora vietiamo l'apertura del segnale dal valore "EMPTY".

Saluti

 

Ciao Ais
Grazie per la tua risposta. Studierò su questo e tornerò presto.
Saluti

 

Ciao Ais,
Scusa per la mia lentezza nella risposta. Ho ricominciato a lavorare nella mia occupazione abituale lunedì. Il tempo è un po' più breve in questi giorni. Il tempo di studio è più breve.
Come avevo accennato prima in questo thread, mi piace rompere le cose fino ai dadi e bulloni. Come fa un pignone a fornire potenza ad un altro e così via. Così ho trovato che il controllo all'interno del programma è affascinante. Vi prego di capire che vi do tutto il rispetto per la pazienza e la conoscenza che avete fornito, ma ho domande sul perché il blocco 2.2.3.1 è necessario.
Come può l'iBaseLag + iBaseBar essere un'espressione?
Ho capito che iBaseLag e iBaseBar sono all'interno del parametro per iHighest e iLowest. A meno che non siano numeri espliciti,
come si può determinare quale numero esatto sarà. iBaseLag è 20, che rappresenta 20 barre utilizzate per calcolare la media.
iBaseBar rappresenta a quale barra dovrebbe iniziare la media. Le barre da 1 a 20, in questo caso, la barra zero non è considerata.
Mi sono preso la libertà di accorciare il programma di /* 2.2.3.1*/. Ho testato il programma e ho trovato gli stessi risultati. Quando si esegue il programma in condizioni reali di trading, questa potrebbe non essere una buona idea.
Qual è la vostra opinione, per favore?
Inoltre, la tua spiegazione al blocco 2.1.2 ha chiarito la mia confusione. iTime restituisce il tempo di apertura della barra zero.
Anche iTradeBarTime è un tipo cast datetime. Il programma sa in quale barra ha avuto luogo lo scambio, quindi solo uno scambio per barra. . iTradeBarOnce == 1
Grazie per l'aiuto
Studierò di più nei prossimi giorni. Ma il blocco reservered 2.1.1 può essere utilizzato per una funzione che fornirebbe posizioni aggiuntive a quelle esistenti. Esempio: un long esistente, poi l'aggiunta di tre o più long?
Con le funzioni che sono già nel programma, ci sarebbero conflitti con le posizioni aggiuntive?
Grazie ancora per tutto. State bene
Saluti

 

Ciao Huckleberry,

Diamo un'occhiata attenta alla parte principale del programma, incluso il blocco 2.2.3.1.:

////////////////////////////////////////////////////////////////////<        14>
// < 2.2.3. Code : Special : Start >                              //<          >
int       start   ()         //       - i       9 l       - o     //<          >
{                                                                 //<          >
// < 2.2.3.1. History data inspection 4 >`````````````````````````//<          >
static    int       iTrigger   = 0       ; if ( iTrigger == 0 ) { //<          >
  if  ( ( iTime ( 0 , 0 , 0 ) == 0                          )     //<          >
  ||    ( iBars ( 0 , 0     )  < iBaseLag     + iBaseBar    ) )   //<          >
          return                         ; else iTrigger  = 1 ; } //<          >
// </2.2.3.1. History data inspection 4 >`````````````````````````//<          >
//                                                                //<          >
// < 2.2.3.2. Main routine 3 >````````````````````````````````````//<          >
int       iTicket           = iGetTicket ()                     ; //<          >
//                                                                //<          >
if      ( iTicket < 0 )       iTryOpen   ()                     ; //<          >
else                          iTryClose  ()                     ; //<          >
// </2.2.3.2. Main routine 3 >````````````````````````````````````//<          >
//                                                                //<          >
// < 2.2.3.3. Exception handler 2 >```````````````````````````````//<          >
int       iTrap   =           GetLastError ()                   ; //<          >
if      ( iTrap   > 0 )       Alert  ( "Exception " , iTrap   ) ; //<          >
// </2.2.3.3. Exception handler 2 >```````````````````````````````//<          >
}                                                                 //<          >
// </2.2.3. Code : Special : Start >                              //<          >
////////////////////////////////////////////////////////////////////<         0>

Questo codice funziona nel seguente modo:

1. il blocco 2.2.3.1., il primissimo blocco del programma, è un semplice trigger:
1.1. "static int iTrigger" memorizza il proprio valore per tutta la durata del programma, tale è "static";
1.2. inizialmente "iTrigger == 0";
1.3. l'istruzione "if ( iTrigger == 0 )" viene eseguita ad ogni tick;
1.4. la prima volta, quando "iTrigger == 0", viene eseguita l'ispezione dei dati storici all'interno del blocco {..};
1.5. se i dati storici non sono corretti, viene eseguita l'istruzione "return;";
1.6. significa che l'esecuzione della funzione principale "start ()" è finita;
1.7. al prossimo tick viene eseguita nuovamente l'istruzione "if ( iTrigger == 0 )";
1.8. se i dati storici sono corretti, viene eseguita l'istruzione "iTrigger = 1 ;";
1.9. allora l'esecuzione della funzione principale "start ()" continua;
1.10. al prossimo tick viene eseguita nuovamente l'istruzione "if ( iTrigger == 0 )";
1.11. il valore di "iTrigger" ora e in futuro sarà sempre "== 1" perché è statico;
1.12. quindi in futuro l'ispezione dei dati storici sarà sempre saltata;
1.13. questo è il trigger semplice
;

2. l'ispezione dei dati storici consiste di due parti:
2.1. controlla se la storia locale è vuota "iTime ( 0, 0, 0 ) == 0";
2.2. controlla se la dimensione della storia locale è sufficiente per il calcolo di "iATR ( 0, 0, iBaseLag, iBaseBar )", dove:
2.2.1. "iBaseBar" è la barra iniziale per "iATR";
2.2.2. "iBaseLag" è il numero di barre di media per "iATR";
2.2.3. "iBaseLag + iBaseBar" è un'espressione usuale, il risultato è sempre una somma di "iBaseLag" e "iBaseBar";
2.2.4. in altre parole l'espressione "iBaseLag + iBaseBar" è equivalente alla somma di "iBaseLag" e "iBaseBar";
2.2.5. possiamo assegnare qualsiasi valore per "iBaseLag" e "iBaseBar" nell'input del programma nel blocco 1.1.1.;
2.2.6. assegniamo "iBaseLag = 100 ;" e "iBaseBar = 7 ;";
2.2.7. allora il calcolo corretto di "iATR ( 0, 0, iBaseLag, iBaseBar )" sarà possibile, se la dimensione della storia locale è uguale o superiore a 107, perché l'ultimo numero di barra per il calcolo è
#106 e la barra numero zero è sempre considerata.

È possibile aggiungere qualsiasi numero di funzioni in qualsiasi programma, il blocco 2.1.1 dimostra solo un esempio di possibile implementazione.
Fornire posizioni aggiuntive richiederà un codice di analisi e gestione delle posizioni molto più complesso della funzione 2.1.4.
Ma tutto è possibile.

Saluti

 

Ciao Ais
Grazie per la tua rapida risposta. Posso seguire molto di quello che dici. Specialmente riguardo alla funzione iATR. Stai dicendo che l'utilizzo dell'espressione iBaseLag + iBasebar, di per sé, è una parte accettabile della formula. Avevo l'impressione che dovevano essere nei parametri di una funzione definita o non erano ammessi. Questo serve a controllare la dimensione della cronologia locale, se ci sono effettivamente abbastanza barre per procedere. È questo che state indicando? Tanti altri passi, ma passi necessari per raggiungere l'obiettivo. Passi che verrebbero trascurati, o dati per scontati.
Masticare così più sul resto. Grazie per il suo tempo.
Saluti

 

Ciao Huckleberry
MQL4 è un ambiente molto amichevole, specialmente in confronto, per esempio, al C o agli assemblatori.
I requisiti per vari controlli e altri trucchi sono significativamente ridotti.
Ma l'implementazione dei massimi controlli possibili nell'ambiente di sviluppo riduce sempre le prestazioni.
In ogni modo il programmatore è sempre responsabile del cattivo comportamento del programma.
Quindi per me un controllo ridondante è meglio che, per esempio, una corruzione elementare dei confini.
Saluti