II Curso de Programación. Sistema Ejercicios 20 al 22

Esta semana publicamos la solución de los ejercicios 20 al 22 de nuestro 2º Curso de Programación para Visual Chart 5. Estos ejercicios giran en torno al uso de la Gestión Monetaria aplicada a sistemas con entradas en stop. Además, añadíamos un método para filtrar señales en base a una media exponencial.

Sistema Ejercicio 20: Sistema entrada con Pivots.
El punto de partida consistía en una estrategia con entradas en stop, cogiendo como precio de referencia el valor dado por los indicadores Pivot Down y Pivot Up. En la siguiente imagen podemos ver una muestra:



Para obtener los precios de entrada, el sistema usa las funciones GetSwingHigh y GetSwingLow, las cuales calculan los valores de los pivots o swings alcistas y bajistas. El sistema opera a favor de tendencia, por lo que las compras están asociadas al swing alcista y las ventas al swing bajista.


Modificación 1 (ejercicio 21). Añadir filtro media exponencial
El siguiente punto del sistema consistía en añadir un filtro basado en una media exponencial. De modo que:

1. Sólo opera a favor de la media. Por lo que sigue las siguiente reglas:
- Lanza orden entrada largos si cierre mayor que la media.
- Lanza orden entrada cortos si cierre menor que la media.

2. Si no pasa el filtro de la media, entonces sustituye la siguiente orden de entrada por una orden de salida en base al nuevo swing.

El resultado sería el siguiente:



Modificación 2 (ejercicio 22). Añadir gestión monetaria tipo Fixed Ratio.
Finalizamos el sistema añadiendo una gestión monetaria al sistema. La cual seguirá las siguientes reglas:

1. Añadimos dos nuevos parámetros a los que llamaremos ContratosInicio y Delta.
2. Los contratos o lotes por negocio irán en base al valor de Delta y siguiendo la siguient fórmula:

Contratos = Ganancia Total / (Delta x Contratos_Previos).

Si el resultado da un valor inferior a ContratosInicio, el sistema opera con ContratosInicio, así evitamos que a la hora de hacer el backtesting, el sistema llegue un momento que pueda dejar de hacer negocios (porque el resultado sea negativo y nos de un número de contratos igual a cero).

El principal problema de ésta gestión surge como consecuencia de que el sistema opera con órdenes en stop. Veamos por qué.

Para calcular la Ganancia Total, el sistema utilizará una función llamada NetProfit, pero si se da el caso de una situación de giro, la función NetProfit no nos sirve para calcular cual sería el número de contratos reales para la siguiente operación, debido a que dicha función no tiene en cuenta cual será el precio de salida del negocio abierto.

Esto se explica mejor en la siguiente imagen:



Teniendo en cuenta esto, en el desarrollo se realiza una gestión especial para los casos de giro.

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 Longitud As Integer '2
Dim PeriodoMedia As Integer '50
Dim ContratosInicio As Long '1
Dim Delta As Double '100
'Parameters !!
Dim avdata As DataIdentifier
Dim contratos As Long
Option Explicit
Public APP As SysUserApp
Implements System
Public Sub System_OnInitCalculate()
With APP
contratos = ContratosInicio
avdata = .GetIndicatorIdentifier(AvExponential, Data, PeriodoMedia, PriceClose)
End With
End Sub
Public Sub System_OnCalculateBar(ByVal Bar As Long)
With APP
Dim medact As Double
Dim pos_abierta As Integer
Dim pentrada As Double
Dim pivotup As Double
Dim pivotdn As Double
Dim gantotal As Double
Dim ganposab As Double
Dim contr_act As Long
Dim salir As Boolean
Dim ganaux As Double
Dim x As Integer
medact = .GetIndicatorValue(avdata)
pivotup = .GetSwingHigh(Data, 1, PriceHigh, Longitud)
pivotdn = .GetSwingLow(Data, 1, PriceLow, Longitud)
pos_abierta = .GetMarketPosition()
pentrada = .GetEntryPrice()
gantotal = .NetProfit()
ganposab = .GetPositionProfit() / .GetSymbolInfo(SbiPointValue)
contr_act = .CurrentContracts()
If (contr_act = 0) Then
contr_act = ContratosInicio
End If

'entrada alcista
If (pos_abierta <> 1 And pivotup > .Close() And pivotup <> NullValue) Then
If (.Close() > medact) Then
'gestion monetaria
If (pos_abierta = -1) Then
gantotal = gantotal - ganposab
gantotal = ((pentrada - pivotup) * contr_act) + gantotal
End If
salir = False
x = contr_act
While Not salir
ganaux = (x + 1) * (Delta * x)
If (ganaux > gantotal) Then
contratos = x
salir = True
Else
x = x + 1
End If
Wend
If contratos < ContratosInicio Then
contratos = ContratosInicio
End If
.Buy AtStop, contratos, pivotup
ElseIf (pos_abierta = -1) Then
.ExitShort AtStop, contr_act, pivotup
End If
End If
'entrada bajista
If (pos_abierta <> -1 And pivotdn < .Close() And pivotdn <> NullValue) Then
If (.Close() < medact) Then
'gestion monetaria
If (pos_abierta = 1) Then
gantotal = gantotal - ganposab
gantotal = ((pivotdn - pentrada) * contr_act) + gantotal
End If
salir = False
x = contr_act
While Not salir
ganaux = (x + 1) * (Delta * x)
If (ganaux > gantotal) Then
contratos = x
salir = True
Else
x = x + 1
End If
Wend
If contratos < ContratosInicio Then
contratos = ContratosInicio
End If
.Sell AtStop, contratos, pivotdn
ElseIf (pos_abierta = 1) Then
.ExitLong AtStop, contr_act, pivotdn
End If
End If
End With
End Sub

Comentarios

Entradas populares de este blog

Como consultar el GAP % de un conjunto de valores

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

Estudio de las divergencias en el RSI