Ayuda a la codificación - página 39

 

He escrito esta línea de código.

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 estas variables insertadas me pregunto si el EA es capaz de identificar que TriggerChart es 'int timeframe', y las otras usadas para los int periods? ¿Podría ser que cuando están todos juntos, mira a TriggerChart y FastMACDPeriod por ejemplo y piensa que ambos tienen que ver con int timeframe y se confunde? ¿En qué momento el EA reconoce qué variable se aplica a qué parte de iMACD?

 

...

En resumen : no, no puede confundirse (los ordenadores son buenos en eso, no piensan sino que ejecutan las mismas cosas una y otra vez sin interpretar) Sólo los codificadores se confunden de vez en cuando

Cuando se llama a una función, ésta acepta parámetros en cierto orden (lugares) (por ejemplo: el primer parámetro es el símbolo, el segundo es el marco de tiempo,, y así sucesivamente) Es completamente relevante cómo se declaran (tipos) las variables cuando se llama a una función: se utilizan estrictamente dependiendo de su lugar en la lista de llamada de parámetros

crsnape@btinternet.com:
He escrito esta línea de código.

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 estas variables insertadas me pregunto si el EA es capaz de identificar que TriggerChart es 'int timeframe', y las otras usadas para los int periods? ¿Podría ser que cuando están todas juntas se fijan en TriggerChart y FastMACDPeriod, por ejemplo, y piensan que ambas tienen que ver con el marco temporal int y se confunden? ¿En qué momento el EA reconoce qué variable se aplica a qué parte de iMACD?
 

Gracias mladen. Suena lógico.

Con este código he declarado BarsGV como 0 en la función int init(). Pero, como bien dices si me da error sigue devolviendo false. Sólo pensaba que en lugar de declararlo 0 en la función int init() podría restablecerlo a 1 en su lugar. ¿Qué opinas? Tengo una 200SMA y si Bars es menor de 200 igual recoge un error aquí.

Así que en lugar de esto:

int init()

{

//---

GlobalVariableSet (BarsGV, 0);

//---

return(0);

}

ESTO ES BAJO INT START()

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

{

GlobalVariableSet(HasOrderedGV, false);

GlobalVariableSet(BarsGV, Bars);

}

//--- Comprobar la posibilidad de posición larga (BUY)

if (GlobalVariableGet (HasOrderedGV) == false)

{

Cambia a esto:

int init()

{

//---

GlobalVariableSet (BarsGV, 1);

//---

return(0);

}

ESTO ES BAJO INT START()

if (GlobalVariableGet (BarsGV) == 0);

{

Print("Error con la variable global BarsGV", GetLastError());

return(0);

}

if (GlobalVariableGet (BarsGV) < Bars)

{

GlobalVariableSet(HasOrderedGV, false);

GlobalVariableSet(BarsGV, Bars);

}

//--- Comprobar la posibilidad de posición larga (BUY)

if (GlobalVariableGet (HasOrderedGV) == false)

{

¿Qué le parece?

 

...

Cámbialo por esto:

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

De esta forma no dependerías de ninguna variable sino sólo de las órdenes y es la única forma 100% fiable

crsnape@btinternet.com:
Gracias mladen. Suena lógico.

Con este código he declarado BarsGV como 0 en la función int init(). Pero, como bien dices si me da error sigue devolviendo false. Sólo pensaba que en lugar de declararlo como 0 en la función int init() podría ponerlo como 1 en su lugar. ¿Qué opinas? Tengo una 200SMA y si Bars es menor de 200 igual recoge un error aquí.

Así que en lugar de esto:

int init()

{

//---

GlobalVariableSet (BarsGV, 0);

//---

return(0);

}

ESTO ES BAJO INT START()

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

{

GlobalVariableSet(HasOrderedGV, false);

GlobalVariableSet(BarsGV, Bars);

}

//--- Comprobar la posibilidad de posición larga (BUY)

if (GlobalVariableGet (HasOrderedGV) == false)

{

Cambia a esto:

int init()

{

//---

GlobalVariableSet (BarsGV, 1);

//---

return(0);

}

ESTO ES BAJO INT START()

if (GlobalVariableGet (BarsGV) == 0);

{

Print("Error con la variable global BarsGV", GetLastError());

return(0);

}

if (GlobalVariableGet (BarsGV) < Bars)

{

GlobalVariableSet(HasOrderedGV, false);

GlobalVariableSet(BarsGV, Bars);

}

//--- Comprobar la posibilidad de posición larga (BUY)

if (GlobalVariableGet (HasOrderedGV) == false)

{

¿Qué te parece?
 

Superestrella. Gracias.

 

Hola mladen,

Esta parte:

datetime EndTime = StartTime + 60 * Period();

Es Period() es esta instancia el marco de tiempo del gráfico. Así que digamos H4 (240) * 60 porque EndTime se registra en segundos, por lo que la conversión de 240minutos en segundos para corresponder con los minutos de Period (240)?

¿Estoy leyendo bien?

¿Podría también ser escrito:

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

 

...

Sí, estás leyendo bien

En cuanto a la otra forma : no se puede utilizar ya que el OrderOpenTime() está en un formato estándar de fecha y hora lo que significa que en EndTime debe tener el número de segundos transcurridos desde el 1 de enero de 1970 y la forma en que lo escribió contendría minutos - metatrader asumiría que son segundos y daría todos los resultados erróneos

crsnape@btinternet.com:
Hola mladen,

Esta parte:

datetime EndTime = StartTime + 60 * Period();

Es Period() es esta instancia el marco de tiempo del gráfico. Así que digamos H4 (240) * 60 porque EndTime se registra en segundos, por lo que la conversión de 240minutos en segundos para corresponder con los minutos de Period (240)?

¿Estoy leyendo bien?

También se podría escribir:

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

Hola mladen, ¿el bucle for aquí selecciona la última orden abierta o pendiente?

bool UniqueOnBar (int MagicNumber)

{

datetime StartTime = Time[0];

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

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);

}

Así que donde el signo de exclamación es intepreted como 'no', Im pensar esto isnt derecho im mi instancia porque quiero:

- Seleccionar la última orden abierta o pendiente, así que quita el signo de exclamación para dejar que OrderSelect?

- Que OrderSymbol() sea lo mismo que Symbol()

- OrderMagicNumber() para que sea igual a MagicNumber, así que... queda esto:

intTriggerChart= PERIOD_H4;

int MagicNumber = 42;

bool UniqueOnBar (int MagicNumber)

{

datetime StartTime = Time[0];

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

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);

}

 

Ahora me doy cuenta de que cuando la expresión devuelve true no se recogen las órdenes abiertas en la barra actual

 

...

Sí, lo hace. Así que si devuelve tru, puede abrir una nueva orden

Además, si usted quiere probar el marco de tiempo diferente al marco de tiempo actual si una orden ha sido abierta en el marco de tiempo objetivo de la barra actual, entonces la función puede ser cambiada a algo como esto:

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

P.D.: ha eliminado la comprobación de órdenes cerradas del ejemplo. Si desea comprobar las órdenes cerradas también, utilice la segunda parte de la forma original de la función también

crsnape@btinternet.com:
Ahora me doy cuenta de que cuando la expresión devuelve true no se recogen órdenes abiertas en la barra actual