Aiuto per la codifica - pagina 39

 

Ho scritto questa linea di codice

int TriggerChart = PERIOD_H4;

int FastMACDPeriod = 12;

int SlowMACDPeriod = 26 ;

int SignalPeriod = 9;

MacdCurrent = iMACD(Symbol(), TriggerChart, FastMACDPeriod,SlowMACDPeriod,SignalPeriod, PRICE_CLOSE, MODE_MAIN, 1);

Con queste variabili inserite mi sto chiedendo se l'EA è in grado di identificare che TriggerChart è 'int timeframe', e le altre usate per gli int periods? Potrebbe essere che quando sono tutte insieme guarda TriggerChart e FastMACDPeriod per esempio e pensa che abbiano entrambe a che fare con int timeframe e si confonde? A che punto l'EA riconosce quale variabile si applica a quale parte di iMACD?

 

...

In breve: no, non può confondersi (i computer sono bravi in questo, non pensano ma eseguono le stesse cose più e più volte senza interpretare) Solo i programmatori si confondono di tanto in tanto

Quando chiamate una funzione, essa accetta dei parametri in un certo ordine (per esempio: il primo parametro è il simbolo, il secondo è il lasso di tempo,,,, e così via) È del tutto rilevante come dichiarate (tipi) le variabili quando chiamate una funzione: esse sono strettamente utilizzate a seconda del loro posto nella lista di chiamata dei parametri

crsnape@btinternet.com:
Ho scritto questa linea di codice

int TriggerChart = PERIOD_H4;

int FastMACDPeriod = 12;

int SlowMACDPeriod = 26 ;

int SignalPeriod = 9;

MacdCurrent = iMACD(Symbol(), TriggerChart, FastMACDPeriod,SlowMACDPeriod,SignalPeriod, PRICE_CLOSE, MODE_MAIN, 1);

Con queste variabili inserite mi sto chiedendo se l'EA è in grado di identificare che TriggerChart è 'int timeframe', e le altre usate per gli int periods? Potrebbe essere che quando sono tutte insieme guarda TriggerChart e FastMACDPeriod per esempio e pensa che abbiano entrambi a che fare con int timeframe e si confonde? A che punto l'EA riconosce quale variabile si applica a quale parte di iMACD?
 

Grazie mladen. Sembra logico.

Con questo codice ho dichiarato BarsGV come 0 nella funzione int init(). Ma, come dici giustamente tu, se ottengo un errore continua a restituire false. Stavo pensando che invece di dichiararlo 0 nella funzione int init() potrei resettarlo a 1. Cosa ne pensi? Ho un 200SMA e se Bars è inferiore a 200 mi da comunque un errore.

Quindi invece di questo

int init()

{

//---

GlobalVariableSet (BarsGV, 0);

//---

return(0);

}

QUESTO È SOTTO INT START()

se ((GlobalVariableGet (BarsGV) == 0) || (GlobalVariableGet (BarsGV) < Bars))

{

GlobalVariableSet(HasOrderedGV, false);

GlobalVariableSet(BarsGV, Bars);

}

//--- Controlla la possibilità di posizione lunga (BUY)

if (GlobalVariableGet (HasOrderedGV) == false)

{

Cambiare in questo modo:

int init()

{

//---

GlobalVariableSet (BarsGV, 1);

//---

return(0);

}

QUESTO È SOTTO INT START()

se (GlobalVariableGet (BarsGV) == 0);

{

Print("Errore con la variabile globale BarsGV", GetLastError());

return(0);

}

se (GlobalVariableGet (BarsGV) < Bars)

{

GlobalVariableSet(HasOrderedGV, false);

GlobalVariableSet(BarsGV, Bars);

}

//--- Controlla la possibilità di posizione lunga (BUY)

if (GlobalVariableGet (HasOrderedGV) == false)

{

Cosa ne pensate?

 

...

Cambiatelo in questo modo:

int BarsGV;

bool HasOrderedGV;

int init()

{

//---

BarsGV=0;

HasOrderedGV=false;

//---

return(0);

}

THIS IS UNDER INT START()

if (BarsGV < Bars)

{

HasOrderedGV=false;

BarsGV=Bars;

}

//--- Check for long position (BUY) possibility

if (HasOrderedGV == false)

{[/PHP]

That way you are going to avoid other EA interference and you will keep the variables to only one instance of Ea (they can not mix at all). Much better to do it that way (even from the speed of execution point of view). But you still risk of opening a new order on a same bar this way. The best way is to use a function to count orders opened at the current bar and then allow or disallow ner order opening

Here is a function that can do that (it will check currently opened as well as already closed orders if they have been opened on a current bar) :

bool uniqueOnBar(int MagicNumber)

{

datetime startTime = Time[0];

datetime endTime = startTime+60*Period();

for (int i=OrdersTotal()-1; i>=0; i--)

{

if (!OrderSelect(i,SELECT_BY_POS,MODE_TRADES)) continue;

if (OrderSymbol() != Symbol()) continue;

if (OrderMagicNumber() != MagicNumber) continue;

if (OrderOpenTime()endTime) continue;

return(false);

}

for (i=OrdersHistoryTotal()-1; i>=0; i--)

{

if (!OrderSelect(i,SELECT_BY_POS,MODE_HISTORY)) continue;

if (OrderSymbol() != Symbol()) continue;

if (OrderMagicNumber() != MagicNumber) continue;

if (OrderOpenTime()endTime) continue;

return(false);

}

return(true);

}

Checking would be very simple :

[PHP]if (uniqueOnBar(MagicNumber)) .... you can open an a new order

In questo modo non dipendereste da nessuna variabile ma solo dagli ordini e questo è l'unico modo affidabile al 100%.

crsnape@btinternet.com:
Grazie mladen. Sembra logico.

Con questo codice ho dichiarato BarsGV come 0 nella funzione int init(). Ma, come dici giustamente tu, se ottengo un errore continua a restituire false. Stavo pensando che invece di dichiararlo 0 nella funzione int init() potrei resettarlo a 1. Cosa ne pensi? Ho un 200SMA e se Bars è inferiore a 200 mi da comunque un errore.

Quindi invece di questo

int init()

{

//---

GlobalVariableSet (BarsGV, 0);

//---

return(0);

}

QUESTO È SOTTO INT START()

se ((GlobalVariableGet (BarsGV) == 0) || (GlobalVariableGet (BarsGV) < Bars))

{

GlobalVariableSet(HasOrderedGV, false);

GlobalVariableSet(BarsGV, Bars);

}

//--- Controlla la possibilità di posizione lunga (BUY)

if (GlobalVariableGet (HasOrderedGV) == false)

{

Cambiare in questo modo:

int init()

{

//---

GlobalVariableSet (BarsGV, 1);

//---

return(0);

}

QUESTO È SOTTO INT START()

se (GlobalVariableGet (BarsGV) == 0);

{

Print("Errore con la variabile globale BarsGV", GetLastError());

return(0);

}

se (GlobalVariableGet (BarsGV) < Bars)

{

GlobalVariableSet(HasOrderedGV, false);

GlobalVariableSet(BarsGV, Bars);

}

//--- Controlla la possibilità di posizione lunga (BUY)

if (GlobalVariableGet (HasOrderedGV) == false)

{

Cosa ne pensate?
 

Superstar. Grazie.

 

Ciao mladen,

Questa parte:

datetime EndTime = StartTime + 60 * Period();

Period() è questa istanza il timeframe del grafico. Quindi diciamo H4 (240) * 60 perché EndTime è registrato in secondi, quindi la conversione di 240minuti in secondi per corrispondere ai minuti di Periodo (240)?

Ho letto bene?

Potrebbe anche essere scritto

datetime EndTime = (StartTime / 60) + Period();?

 

...

Sì, stai leggendo bene

Per quanto riguarda l'altra forma: non puoi usarla poiché OrderOpenTime() è in un formato datetime standard che significa che in EndTime devi avere il numero di secondi trascorsi dal 1 gennaio 1970 e il modo in cui l'hai scritto conterrebbe minuti - metatrader assumerebbe che quelli siano secondi e darebbe tutti risultati sbagliati

crsnape@btinternet.com:
Ciao mladen,

Questa parte:

datetime EndTime = StartTime + 60 * Period();

Period() è in questo caso il timeframe del grafico. Quindi diciamo H4 (240) * 60 perché EndTime è registrato in secondi, quindi la conversione di 240minuti in secondi per corrispondere ai minuti di Periodo (240)?

Ho letto bene?

Potrebbe anche essere scritto:

datetime EndTime = (StartTime / 60) + Period();?
 

Ciao mladen, il ciclo for qui seleziona l'ultimo ordine aperto o in sospeso?

bool UniqueOnBar (int MagicNumber)

{

datetime StartTime = Time[0];

datetime EndTime = StartTime + 60 * Periodo (TriggerChart);

for (int i = OrdersTotal() - 1; i >= 0; i--)

{

if (!OrderSelect (i, SELECT_BY_POS, MODE_TRADES)) continua;

se (OrderSymbol() != Symbol()) continua;

se (OrderMagicNumber() != MagicNumber) continua;

se (OrderOpenTime() endTime) continua;

return(false);

}

Quindi, dove il punto esclamativo è interpretato come 'non', penso che questo non sia giusto nella mia istanza perché voglio:

- Selezionare l'ultimo ordine aperto o in sospeso quindi rimuovere ! per lasciare OrderSelect?

- OrderSymbol() sia lo stesso di Symbol()

- OrderMagicNumber() sia uguale a MagicNumber, quindi

intTriggerChart= PERIOD_H4;

int MagicNumber = 42;

bool UniqueOnBar (int MagicNumber)

{

datetime StartTime = Time[0];

datetime EndTime = StartTime + 60 * Periodo(TriggerChart);

for (int i = OrdersTotal() - 1; i >= 0; i--)

{

se (OrderSelect (i, SELECT_BY_POS, MODE_TRADES)) continua;

se (OrderSymbol() == Symbol()) continua;

se (OrderMagicNumber() == MagicNumber) continua;

se (OrderOpenTime() endTime) continua;

return(false);

}

 

La mia svista è che ora mi rendo conto che è quando l'espressione restituisce true che nessun ordine aperto è raccolto sulla barra corrente

 

...

Sì, è così. Quindi se restituisce tru, puoi aprire un nuovo ordine

Inoltre, se vuoi testare un time frame diverso da quello corrente se un ordine è stato aperto sulla barra corrente del time frame di destinazione, allora la funzione può essere cambiata in qualcosa del genere:

bool UniqueOnBar (int MagicNumber, int timeFrame=0)

{

if (timeFrame==0) timeFrame=Period();

datetime StartTime = iTime(NULL,timeFrame,0);

datetime EndTime = StartTime + 60*timeFrame;

for (int i=OrdersTotal()-1; i>=0; i--)

{

if (OrderSelect(i,SELECT_BY_POS,MODE_TRADES)) continue;

if (OrderSymbol() == Symbol()) continue;

if (OrderMagicNumber() == MagicNumber) continue;

if (OrderOpenTime() EndTime) continue;

return(false);

}

return(true);

}

[/PHP]

And then the call to it would be for your example 2 posts ago

[PHP]if (UniqueOnBar(MagicNumber,TriggerChart) ... open an order

PS: hai rimosso il controllo degli ordini chiusi dall'esempio. Se vuoi controllare anche gli ordini chiusi, allora usa anche la seconda parte della forma originale della funzione

crsnape@btinternet.com:
La mia svista mi ha fatto capire che è quando l'espressione restituisce true che nessun ordine aperto viene raccolto sulla barra corrente
Motivazione: