II Curso de Programación. Sistema Ejercicio 17

Esta semana publicamos la solución del ejercicio 17 de nuestro 2º Curso de Programación para Visual Chart 5. Este sistema estaba basado en el MACD y el ADX.

Sistema Ejercicio 17: Sistema cruce MACD con Media aplicando filtro ADX

El propósito que perseguíamos con este ejercicio era el de repasar el uso de varios indicadores de manera conjunta dentro de un sistema. En concreto, el sistema utiliza como base el cruce del MACD con su media de señal y luego aplica un filtro basado en la posición del ADX con su banda.

En la siguiente imagen podemos ver un ejemplo de cómo funcionaría el sistema:






Lo que hace este sistema es generar un negocio por cada impulso detectado por el ADX, siendo la señal del negocio en función de la dirección del MACD. En el momento en el que se dejan de cumplir alguna de las dos condiciones (el ADX pierde la fuerza o el MACD cambia la dirección), el sistema cierra el negocio abierto.

Resumiendo, las reglas del sistema serían las siguientes:
1. Si el MACD está alcista (mayor que su media) y el ADX cruza su banda (20) al alza, tomar posiciones largas.
2. Si el MACD está bajista (menor que su media) y el ADX cruza su banda (20) al alza, tomar posiciones cortas.
3. No permite realizar un nuevo negocio mientras el ADX no vuelva a cruzar a la banda. Es decir, realiza un único negocio por impulso.
4. Si el MACD pasa a estar bajista o el ADX cae por debajo de su banda, cerrar largos.
5. Si el MACD pasa a estar alcista o el ADX cae por debajo de su banda, cerrar cortos.

Adicionalmente, incluimos dos modificaciones al sistema, que serían las siguientes:

Modificación 1 (ejercicio 18). Aplicar un Trailing Stop.
Añadimos al sistema un stop dinámico que persiga al precio. De modo que:
1. Incluimos un nuevo parámetro que llamamos TrailingStop.
2. Si TrailingStop no vale 0, sustituir órdenes de salida por un stop dinámico.
3. Aplicar un stop inicial (50 puntos) para cubrir pérdidas.
4. Activar el trailing a partir de alcanzar una ganancia igual o superior al valor del parámetro TrailingStop.
5. Desde ese momento, movemos el stop si el precio se mueve a favor de la señal. Si bien sólo nos fijamos en los cierres de la barra (no en los máximos y mínimos).



Modificación 2 (ejercicio 19). Añadir horario de entrada y salida al sistema.
Añadimos un intervalo horario de modo que cerramos las posiciones abiertas si alcanza la hora de salida con un negocio abierto.

El desarrollo del sistema sería el siguiente:

Código PDV:



Código VBA:
(NOTA: Recuerden que el código aquí expuesto sólo incluye los métodos OnCalculateBar() y OnInitCalculate(). Tengan esto en cuenta a la hora de copiar el sistema).

'¡¡ Parameters
Dim Contratos As Long '1
Dim PeriodoADX As Integer '14
Dim BandaADX As Double '20
Dim Periodo1MACD As Integer '12
Dim Periodo2MACD As Integer '26
Dim PeriodoMSIGMACD As Integer '9
Dim StopInicial As Double '50
Dim TrailingStop As Double '40
Dim HoraEntrada As Integer '800
Dim HoraSalida As Integer '2200
'Parameters !!
Dim adxdata As DataIdentifier
Dim macddata As DataIdentifier
Dim cruceadx As Integer
Dim preciots As Double
Dim activarts As Boolean
Option Explicit
Public APP As SysUserApp
Implements System
Public Sub System_OnInitCalculate()
With APP


adxdata = .GetIndicatorIdentifier(ADX, Data, PeriodoADX, BandaADX)
macddata = .GetIndicatorIdentifier(MACD, Data, Periodo1MACD, Periodo2MACD, PeriodoMSIGMACD, PriceClose, 0)
cruceadx = 0
activarts = False
preciots = 0
End With
End Sub
Public Sub System_OnCalculateBar(ByVal Bar As Long)
With APP

Dim macdact As Double
Dim mesigact As Double

macdact = .GetIndicatorValue(macddata)
mesigact = .GetIndicatorValue(macddata, 0, 2)

Dim adxact As Double
Dim adxant As Double

adxact = .GetIndicatorValue(adxdata)
adxant = .GetIndicatorValue(adxdata, 1)

If (adxact > BandaADX And adxant <= BandaADX) Then
cruceadx = 1
ElseIf (adxact < BandaADX) Then
cruceadx = -1
End If

Dim pos_abierta As Integer
Dim pentrada As Double

pos_abierta = .GetMarketPosition()
pentrada = .GetEntryPrice()

If (.Time() >= HoraEntrada And .Time() < HoraSalida) Then
If (cruceadx = 1) Then
If (pos_abierta <> 1 And macdact > mesigact) Then
.Buy AtClose, Contratos
pos_abierta = 1
pentrada = .Close()
activarts = False
cruceadx = 0
ElseIf (pos_abierta <> -1 And macdact < mesigact) Then
.Sell AtClose, Contratos
pos_abierta = -1
pentrada = .Close()
activarts = False
cruceadx = 0

End If
End If

If (pos_abierta = 1) Then
If (TrailingStop = 0) Then
If (cruceadx = -1 Or macdact < mesigact) Then
.ExitLong AtClose, Contratos
End If
Else
If (activarts = False) Then
If (.Close() - pentrada) >= TrailingStop Then
activarts = True
preciots = .Close()
End If
End If
If (activarts) Then
If (.Close() > preciots) Then
preciots = .Close()
End If
.ExitLong AtStop, Contratos, preciots - TrailingStop
Else
.ExitLong AtStop, Contratos, pentrada - StopInicial
End If
End If
ElseIf (pos_abierta = -1) Then
If (TrailingStop = 0) Then
If (cruceadx = -1 Or macdact > mesigact) Then
.ExitShort AtClose, Contratos
End If
Else
If (activarts = False) Then
If (pentrada - .Close()) >= TrailingStop Then
activarts = True
preciots = .Close()
End If
End If
If (activarts) Then
If (.Close() < preciots) Then
preciots = .Close()
End If
.ExitShort AtStop, Contratos, preciots + TrailingStop
Else
.ExitShort AtStop, Contratos, pentrada + StopInicial
End If
End If
End If
Else
If (pos_abierta = 1) Then
.ExitLong AtClose, Contratos
ElseIf (pos_abierta = -1) Then
.ExitShort AtClose, Contratos
End If
End If
End With
End Sub


Comentarios

Entradas populares de este blog

Como consultar el GAP % de un conjunto de valores

Bollinger Volatility Oscillator N

MANEJO DE PLANTILLAS. Eliminar plantilla de un gráfico activa