Buenas tardes,
Tengo el siguiente sistema de trading:
- Opero en Nasdaq y SP500
- En minutos
- Horario ampliado de trading (ETH)
- Realiza una entrada diaria en los primeros minutos de cotización tras la apertura de mercado.
- Para hacer esa entrada el sistema utiliza la media móvil de 200 minutos y la media móvil de 20 minutos
Lo he probado en backtest y funciona perfectamente. Hace lo que quiero que haga
Sin embargo cuando lo opero en ProOrder, el mismo sistema no hace las entradas donde debería.
Tras analizar el problema he visto que lo que hace el sistema en ProOrder es operar en ETH, como debe ser, pero sin embargo la M20 y la M200 no las considera en horario ampliado. Creo que las considera en horario regular. Y claro, en los primeros minutos de cotización la M20 y la M200 son muy distintas si están en ETH o en RTH.
En definitiva, la misma operación en Probacktest o en ProOrder dan resultados diferentes.
Como ejemplo: Unity Software (U), 16 de Febrero de 2023:
- En ProBacktest el sistema da entrada a las 10.05 (bien)(ver adjunto)
- En ProOrder el sistema dio entrada a las 09.40 (mal)(ver adjunto)
En ambos casos la M200 y M20 que se ven en el gráfico son las correspondientes a ETH pero veis que las entradas son diferentes. Y solo se me ocurre que es porque en ProOrder a pesar de pesar de tener en gráfico las medias en ETH, las está considerando en RTH, porque las entradas en ProOrder son coherentes con la M20 y M200 en (RTH).
El sistema es el siguiente:
DEFPARAM FLATAFTER = 160000
//Condición 0: Existencia de gap (con fecha posterior a 1 de Enero de 2016):
//Defino el momento de cierre del día anterior (cierre de la vela de las 15.59 o hasta 5 minutos antes, o cierre de la vela de las 12.59 o hasta 5 minutos antes) y el momento de apertura del día de hoy (comienzo de la vela de las 09.30 o hasta 5 minutos después):
//Cierre de la vela de las 15.59 o hasta 5 minutos antes, o cierre de la vela de las 12.59 o hasta 5 minutos antes:
a0 = (Time = 160000)
a1 = (Time = 155900)
a2 = (Time = 155800)
a3 = (Time = 155700)
a4 = (Time = 155600)
a10 = (Time = 130000)
a11 = (Time = 125900)
a12 = (Time = 125800)
a13 = (Time = 125700)
a14 = (Time = 125600)
//Comienzo de la vela de las 09.30 o hasta 5 minutos después:
b0 = (Time = 93100)
b1 = (Time = 93200)
b2 = (Time = 93300)
b3 = (Time = 93400)
b4 = (Time = 93500)
IF a0 THEN
Cierre = Close
ELSIF a1 THEN
Cierre = Close
ELSIF a2 THEN
Cierre = Close
ELSIF a3 THEN
Cierre = Close
ELSIF a4 THEN
Cierre = Close
ELSIF a10 THEN
Cierre = Close
ELSIF a11 THEN
Cierre = Close
ELSIF a12 THEN
Cierre = Close
ELSIF a13 THEN
Cierre = Close
ELSIF a14 THEN
Cierre = Close
ENDIF
IF b0 THEN
Apertura = Open
ELSIF b1 THEN
Apertura = Open
ELSIF b2 THEN
Apertura = Open
ELSIF b3 THEN
Apertura = Open
ELSIF b4 THEN
Apertura = Open
ENDIF
//Con este contador:
//1. Para cada vela, "Resultado" devuelve 1 cuando se cumplen todas las condiciones (b0, b1, b2, b3 o b4) y devuelve 0 en el caso contrario.
//2. Para cada vela compruebo una por una las 5 velas anteriores a ella.
//3. "Suma" va sumando los resultados uno a uno.
IF b0 OR b1 OR b2 OR b3 OR b4 THEN
Resultado = 1
Suma = 0
FOR z = 5 DOWNTO 0 DO
Suma = Suma + Resultado[z]
NEXT
ELSE
Resultado = 0
Suma = 0
ENDIF
//"C0" devuelve el valor del gap cuando "Suma" = 1, es decir calcula el gap con la primera vela existente en la sesión (b0, b1, b2, b3 o b4). Y a partir de la vela 390 desde las 4.00, devuelve 0:
IF Suma = 1 THEN
IF ABS((Apertura - Cierre) / Cierre) * 100 >= Gap and Date >= 20160101 THEN
C0 = 1
ELSE
C0 = 0
ENDIF
ELSIF IntradayBarIndex > 390 THEN
C0 = 0
ENDIF
//Condición 1: Entrada a partir de la quinta vela y antes de la primera hora:
C1 = Time > InicioHoraEntrada AND Time =< FinHoraEntrada
//Defino las medias: Media larga y media corta:
MediaLarga = Average[MLarga](close)
MediaCorta = Average[MCorta](close)
//Condición 2: Entrada a largo por encima de la media corta, la cual está por encima de la media larga, ambas ascendentes, al final de la primera vela verde después de una o varias rojas (retroceso):
C21 = MediaCorta > MediaLarga
C22 = MediaCorta[1] < MediaCorta
C23 = MediaLarga[1] < MediaLarga
C24 = Close > MediaCorta
C25 = Close[1] < Open[1] AND Close > Open
C2 = C21 and C22 and C23 and C24 and C25
//Condición 3: Entrada a corto por debajo de la media corta, la cual está por debajo de la media larga, ambas descendentes, al final de la primera vela roja después de una o varias verdes (retroceso):
C31 = MediaCorta < MediaLarga
C32 = MediaCorta[1] > MediaCorta
C33 = MediaLarga[1] > MediaLarga
C34 = Close < MediaCorta
C35 = Close[1] > Open[1] AND Close < Open
C3 = C31 and C32 and C33 and C34 and C35
//Condición 4: Una sola operación por día (la primera que dé entrada):
C4 = (BarIndex - TRADEINDEX(1) > IntraDayBarIndex)
//Condiciones de entrada:
EntradaLargo = C0 = 1 AND C1 AND C2 AND C4
EntradaCorto = C0 = 1 AND C1 AND C3 AND C4
//Capital:
CapitalInicial = 14000
Capital = CapitalInicial + STRATEGYPROFIT
// Condiciones para entrada de posiciones largas
IF NOT LongOnMarket AND EntradaLargo THEN
BUY Capital CASH AT MARKET
ENDIF
// Condiciones de entrada de posiciones cortas
IF NOT ShortOnMarket AND EntradaCorto THEN
SELLSHORT Capital CASH AT MARKET
ENDIF
// Condiciones de salida
IF (OnMarket AND Not OnMarket[1]) OR (LongOnMarket AND ShortOnMarket[1]) OR (ShortOnMarket AND LongOnMarket[1]) THEN
If LongOnMarket THEN
Set Stop %loss 1
ELSIF ShortOnMarket THEN
Set Stop %loss 1
ENDIF
ENDIF
// Stop escalonado:
Trailingstart = TradePrice * 0.5/100 //Trailing empezará cuando el beneficio llega a 0.5%
Trailingstep = TradePrice * 0.5/100 //Trailing irá en escalones de 0.5%
//Cuando no haya ninguna operación abierta:
IF NOT OnMarket THEN
NewSL = 0
ENDIF
//Posiciones largas:
IF LongOnMarket THEN
IF NewSL > 0 AND High - NewSL >= 21 * Trailingstart THEN
NewSL = NewSL + 20 * Trailingstart
ELSIF NewSL > 0 AND High - NewSL >= 20 * Trailingstart THEN
NewSL = NewSL + 19 * Trailingstart
ELSIF NewSL > 0 AND High - NewSL >= 19 * Trailingstart THEN
NewSL = NewSL + 18 * Trailingstart
ELSIF NewSL > 0 AND High - NewSL >= 18 * Trailingstart THEN
NewSL = NewSL + 17 * Trailingstart
ELSIF NewSL > 0 AND High - NewSL >= 17 * Trailingstart THEN
NewSL = NewSL + 16 * Trailingstart
ELSIF NewSL > 0 AND High - NewSL >= 16 * Trailingstart THEN
NewSL = NewSL + 15 * Trailingstart
ELSIF NewSL > 0 AND High - NewSL >= 15 * Trailingstart THEN
NewSL = NewSL + 14 * Trailingstart
ELSIF NewSL > 0 AND High - NewSL >= 14 * Trailingstart THEN
NewSL = NewSL + 13 * Trailingstart
ELSIF NewSL > 0 AND High - NewSL >= 13 * Trailingstart THEN
NewSL = NewSL + 12 * Trailingstart
ELSIF NewSL > 0 AND High - NewSL >= 12 * Trailingstart THEN
NewSL = NewSL + 11 * Trailingstart
ELSIF NewSL > 0 AND High - NewSL >= 11 * Trailingstart THEN
NewSL = NewSL + 10 * Trailingstart
ELSIF NewSL > 0 AND High - NewSL >= 10 * Trailingstart THEN
NewSL = NewSL + 9 * Trailingstart
ELSIF NewSL > 0 AND High - NewSL >= 9 * Trailingstart THEN
NewSL = NewSL + 8 * Trailingstart
ELSIF NewSL > 0 AND High - NewSL >= 8 * Trailingstart THEN
NewSL = NewSL + 7 * Trailingstart
ELSIF NewSL > 0 AND High - NewSL >= 7 * Trailingstart THEN
NewSL = NewSL + 6 * Trailingstart
ELSIF NewSL > 0 AND High - NewSL >= 6 * Trailingstart THEN
NewSL = NewSL + 5 * Trailingstart
ELSIF NewSL > 0 AND High - NewSL >= 5 * Trailingstart THEN
NewSL = NewSL + 4 * Trailingstart
ELSIF NewSL > 0 AND High - NewSL >= 4 * Trailingstart THEN
NewSL = NewSL + 3 * Trailingstart
ELSIF NewSL > 0 AND High - NewSL >= 3 * Trailingstart THEN
NewSL = NewSL + 2 * Trailingstart
ELSIF NewSL > 0 AND High - NewSL >= 2 * Trailingstart THEN
NewSL = NewSL + Trailingstart
ELSIF NewSL = 0 AND High - TradePrice >= Trailingstart THEN
NewSL = TradePrice
ENDIF
ENDIF
//Posiciones cortas:
IF ShortOnMarket THEN
IF NewSL > 0 AND NewSL - Low >= 21 * Trailingstart THEN
NewSL = NewSL - 20 * Trailingstart
ELSIF NewSL > 0 AND NewSL - Low >= 20 * Trailingstart THEN
NewSL = NewSL - 19 * Trailingstart
ELSIF NewSL > 0 AND NewSL - Low >= 19 * Trailingstart THEN
NewSL = NewSL - 18 * Trailingstart
ELSIF NewSL > 0 AND NewSL - Low >= 18 * Trailingstart THEN
NewSL = NewSL - 17 * Trailingstart
ELSIF NewSL > 0 AND NewSL - Low >= 17 * Trailingstart THEN
NewSL = NewSL - 16 * Trailingstart
ELSIF NewSL > 0 AND NewSL - Low >= 16 * Trailingstart THEN
NewSL = NewSL - 15 * Trailingstart
ELSIF NewSL > 0 AND NewSL - Low >= 15 * Trailingstart THEN
NewSL = NewSL - 14 * Trailingstart
ELSIF NewSL > 0 AND NewSL - Low >= 14 * Trailingstart THEN
NewSL = NewSL - 13 * Trailingstart
ELSIF NewSL > 0 AND NewSL - Low >= 13 * Trailingstart THEN
NewSL = NewSL - 12 * Trailingstart
ELSIF NewSL > 0 AND NewSL - Low >= 12 * Trailingstart THEN
NewSL = NewSL - 11 * Trailingstart
ELSIF NewSL > 0 AND NewSL - Low >= 11 * Trailingstart THEN
NewSL = NewSL - 10 * Trailingstart
ELSIF NewSL > 0 AND NewSL - Low >= 10 * Trailingstart THEN
NewSL = NewSL - 9 * Trailingstart
ELSIF NewSL > 0 AND NewSL - Low >= 9 * Trailingstart THEN
NewSL = NewSL - 8 * Trailingstart
ELSIF NewSL > 0 AND NewSL - Low >= 8 * Trailingstart THEN
NewSL = NewSL - 7 * Trailingstart
ELSIF NewSL > 0 AND NewSL - Low >= 7 * Trailingstart THEN
NewSL = NewSL - 6 * Trailingstart
ELSIF NewSL > 0 AND NewSL - Low >= 6 * Trailingstart THEN
NewSL = NewSL - 5 * Trailingstart
ELSIF NewSL > 0 AND NewSL - Low >= 5 * Trailingstart THEN
NewSL = NewSL - 4 * Trailingstart
ELSIF NewSL > 0 AND NewSL - Low >= 4 * Trailingstart THEN
NewSL = NewSL - 3 * Trailingstart
ELSIF NewSL > 0 AND NewSL - Low >= 3 * Trailingstart THEN
NewSL = NewSL - 2 * Trailingstart
ELSIF NewSL > 0 AND NewSL - Low >= 2 * Trailingstart THEN
NewSL = NewSL - Trailingstart
ELSIF NewSL = 0 AND TradePrice - Low >= Trailingstart THEN
NewSL = TradePrice
ENDIF
ENDIF
//Orden de salida, tanto para posiciones largas como para posiciones cortas:
IF newSL>0 THEN
SELL AT NewSL STOP
EXITSHORT AT NewSL STOP
ENDIF
En definitiva ¿me podéis ayudar para que el sistema en ProOrder se comporte igual que en ProBacktest? No sé si es un sistema de código o de configurar algo que se me escapa.
Yo lo que quiero es que tanto en backtest como en ProOrder me considere la M200 y la M20 en ETH, no en RTH.
Gracias anticipadas y un saludo,
Carlos