Buenos días,
estoy intentando hacer backetst de un sistema publicado en youtube:
- TEMPORALIDAD: diaria
- COMPRA: LOS LUNES SI el cierre es menor o igual que el cierre más bajo de los últimos 2 días. LA COMPRA SERÍA AL CIERRE (no a la barra siguiente. No sé si prorealtime permite esto)
- VENTA: si el cierre es superior al máximo de ayer, se vende AL CIERRE .
- STOPLOSS: SI HAN PASADO 10 días desde la compra, se vende al cierre
He programado esto pero no funciona y no creo que haga las compras al cierre:
// Condiciones para entrada de posiciones largas
IF NOT LongOnMarket AND DayOfWeek=1 AND Close<Close[1] AND Close<Close[2] THEN
BUY 1 CONTRACTS AT MARKET
ENDIF
// Condiciones de salida de posiciones largas
If LongOnMarket AND Close>High[1] THEN
SELL AT MARKET
ENDIF
Si podéis ayudarme, gracias.
La técnica correcta para ejecutar al cierre de una vela diaria
El sistema debe correr en un gráfico intradiario (por ejemplo 1 minuto o 5 minutos). La idea es la siguiente: los valores diarios (close de ayer, high de ayer, etc.) se obtienen con las funciones DClose(N), DHigh(N), DLow(N), DOpen(N), donde N=1 es ayer, N=0 es el día actual en curso. La condición de “al cierre del día” se simula comparando el TIME de la barra actual con el último minuto del día de mercado, por ejemplo TIME >= 235000, que corresponde a las 23:50:00. Cuando esa condición se cumple en la última barra del día, el precio de esa barra es prácticamente el cierre diario.
Para el día de la semana en un gráfico intradiario, la función correcta es OpenDayOfWeek (que devuelve el día en que abrió la sesión del día actual), no CurrentDayOfWeek ni DayOfWeek.
El stop de 10 días se gestiona guardando la fecha de entrada y comparando con DClose: la forma más limpia es contar los días transcurridos con un contador que se incrementa una vez por día mientras se está en posición.
Aquí está el código completo reescrito:
DEFPARAM CumulateOrders = false
// Precios diarios
dCloseYest = DClose(1) // cierre de ayer
dClose2 = DClose(2) // cierre de hace 2 dias
dHighYest = DHigh(1) // maximo de ayer
// Ultimo minuto del dia (ajusta segun el mercado: forex=235000, acciones=170000, etc.)
isLastBar = TIME >= 215000
// Contar dias en posicion (se incrementa una vez por dia al cierre)
IF LongOnMarket AND isLastBar THEN
daysInTrade = daysInTrade + 1
ENDIF
IF NOT LongOnMarket THEN
daysInTrade = 0
ENDIF
// Condicion de entrada: lunes, cierre <= cierre minimo de los 2 dias anteriores
// En intradiario, OpenDayOfWeek=1 significa que la sesion abrio el lunes
entryOK = OpenDayOfWeek = 1 AND DClose(0) <= dCloseYest AND DClose(0) <= dClose2
// Condicion de salida por precio: cierre > maximo de ayer
exitPrice = DClose(0) > dHighYest
// Condicion de salida por tiempo: 10 dias en posicion
exitTime = daysInTrade >= 10
// ENTRADA al cierre del lunes
IF NOT LongOnMarket AND isLastBar AND entryOK THEN
BUY 1 CONTRACTS AT MARKET
ENDIF
// SALIDA al cierre si se cumple condicion de precio o tiempo
IF LongOnMarket AND isLastBar AND (exitPrice OR exitTime) THEN
SELL AT MARKET
ENDIF
Puntos clave:
- Aplica este código sobre un gráfico intradiario (1min, 5min). En gráfico diario puro las órdenes AT MARKET se ejecutan en la apertura de la barra siguiente, lo que arruina la simulación.
- DClose(0) es el cierre del día actual en construcción (precio actual de la última barra del día). Cuando TIME >= 215000 esa barra es prácticamente el cierre.
- Ajusta el valor 235000 al mercado que uses: para forex/crypto que cierra a medianoche es correcto. Para acciones europeas (cierre 17:30) usa 173000. Para el S&P 500 (cierre 22:00 CET) usa 215500 o similar.
- OpenDayOfWeek = 1 es lunes en cualquier barra intradiaria de esa sesión, lo que es más fiable que DayOfWeek en intradiario.
- El contador daysInTrade se resetea a 0 al salir de la posición y suma 1 cada cierre mientras se está largo.