Acumular posiciones desde un sistema
En numerosas ocasiones, nuestros sistemas se basan en operaciones escalonadas, es decir, que deseamos acumular contratos, o bien porque queremos recuperar las pérdidas cuando el mercado va en contra, o al revés, porque queremos aumentar las ganancias antes un rally a favor nuestro.
Cuando pasa esto, si no cambiamos nada en los ajustes del sistema, Visual Chart no nos va a permitir realizar reentradas mientras la primera entrada permanezca vigente.
Por tanto, lo primero que hay que hacer es modificar el modo de entrar a través de los ajustes de los sistemas.
En el manual de Visual Chart podremos ver cómo hacer esto. Pueden descargar el manual pulsando aquí.
Una vez accedan al manual, accedan al menú de Contenido y pulsen sobre:
SISTEMAS DE TRADING\Propiedades de Configuración
En Ajustes\Métodos de entrada, verán que tenemos varias opciones. La ideal para nuestro caso será
Lógicamente, para que tenga efecto el uso de Acumular por Etiquetas, es necesario que cada orden lleve asociada una.
Para asignar etiquetas desde el código de programación, hacemos lo siguiente:
En caso de venta:
Donde NomEtiqueta será una variable que cambiaremos a nuestro antojo.
Problemas en el uso de Etiquetas desde Sistemas
Uno de los principales inconvenientes de usar etiquetas y acumular posiciones, es que no hay ninguna función que nos avise de cuando se ha ejecutado un nuevo negocio en concreto.
Es decir, tenemos la función APP.GetMarketPosition, pero esta función nos habla en términos generales y no nos sirve para saber si hemos pasado de tener tres negocios abiertos a cuatro.
No obstante, podemos hacer uso de otra función que nos ayudará a controlar los negocios que se van ejecutando. esta función es FilledOrders
Donde:
Código de ejemplo: Sistema que acumula posiciones usando etiquetas
Una forma de trabajar con posiciones acumuladas, es controlar internamente cuantos negocios se van colocando en el mercado, y luego gestionarlos por separado.
Primero, creamos un estructura de datos que se usa para controlar los distintos negocios:
Luego crearemos dos arrays que sean de este tipo:
Y además dos variables para controlar la cantidad de negocios que hay de cada tipo:
En el método de inicio, reiniciamos las dos variables:
Luego, en el método de cálculo, trabajamos con los negocios del siguiente modo:
1) Cada vez que se cumple la condición de una nueva compra:
2) Una vez que hemos enviado la orden de entrada, comprobar a partir de la siguiente barra si se ha ejecutado
3) Si el negocio está abierto, podemos enviar órdenes de salida a distinto precio para cada una de los negocios acumulados:
4) Por último, pasamos a controlar si se han ejecutado las salidas del negocio para no enviar más dichas órdenes. Esta parte en realidad es por ser correctos, puesto que si lanzamos órdenes de salida con una etiqueta concreta y no existe ningún contrato abierto con dicha etiqueta, Visual Chart directamente cancela esas órdenes de salida y no las envía al mercado. Como dijimos, tendríamos que gestionar las salidas usando otros métodos:
Repetiríamos todos los pasos dados para el caso de las ventas.
Cuando pasa esto, si no cambiamos nada en los ajustes del sistema, Visual Chart no nos va a permitir realizar reentradas mientras la primera entrada permanezca vigente.
Por tanto, lo primero que hay que hacer es modificar el modo de entrar a través de los ajustes de los sistemas.
En el manual de Visual Chart podremos ver cómo hacer esto. Pueden descargar el manual pulsando aquí.
Una vez accedan al manual, accedan al menú de Contenido y pulsen sobre:
En Ajustes\Métodos de entrada, verán que tenemos varias opciones. La ideal para nuestro caso será
- Acumular por Etiquetas
Lógicamente, para que tenga efecto el uso de Acumular por Etiquetas, es necesario que cada orden lleve asociada una.
Para asignar etiquetas desde el código de programación, hacemos lo siguiente:
APP.Buy AtClose, Contratos, , NomEtiqueta
En caso de venta:
APP.Sell AtClose, Contratos, , NomEtiqueta
Donde NomEtiqueta será una variable que cambiaremos a nuestro antojo.
Uno de los principales inconvenientes de usar etiquetas y acumular posiciones, es que no hay ninguna función que nos avise de cuando se ha ejecutado un nuevo negocio en concreto.
Es decir, tenemos la función APP.GetMarketPosition, pero esta función nos habla en términos generales y no nos sirve para saber si hemos pasado de tener tres negocios abiertos a cuatro.
No obstante, podemos hacer uso de otra función que nos ayudará a controlar los negocios que se van ejecutando. esta función es FilledOrders
APP.FilledOrders(NomEtiqueta, Side, BarsAgo)
Donde:
- NomEtiqueta hace referencia a la etiqueta de un negocio en concreto.
- Side indica si queremos saber si el negocio ha sido de compra (ponemos 0) o venta (ponemos 1).
- BarsAgo indica sobre qué barra queremos hacer la consulta.
Código de ejemplo: Sistema que acumula posiciones usando etiquetas
Una forma de trabajar con posiciones acumuladas, es controlar internamente cuantos negocios se van colocando en el mercado, y luego gestionarlos por separado.
Primero, creamos un estructura de datos que se usa para controlar los distintos negocios:
Private Type TipoNegocio
Name As String
Abierta As Boolean
PDisparo As Double
PIn As Double
PLimit As Double
PStop As Double
End Type
Name As String
Abierta As Boolean
PDisparo As Double
PIn As Double
PLimit As Double
PStop As Double
End Type
Luego crearemos dos arrays que sean de este tipo:
Dim Alza() As TipoNegocio
Dim Baja() As TipoNegocio
Dim Baja() As TipoNegocio
Y además dos variables para controlar la cantidad de negocios que hay de cada tipo:
Dim ContAlza as Integer
Dim ContBaja as Integer
Dim ContBaja as Integer
En el método de inicio, reiniciamos las dos variables:
Public Sub System_OnInitCalculate()
With APP
ReDim Alza(0): ReDim Baja(0)
ContAlza = 0:ContBaja = 0
With APP
ReDim Alza(0): ReDim Baja(0)
ContAlza = 0:ContBaja = 0
Luego, en el método de cálculo, trabajamos con los negocios del siguiente modo:
1) Cada vez que se cumple la condición de una nueva compra:
If NuevaCompra then
With Alza(ContAlza)
.PDisparo = NuevoPrecio
.Name = "Compra Num " & ContAlza
End With
.Buy AtStop, Contratos, Alza(ContAlza).PDisparo, Alza(ContAlza).Name
ContAlza = ContAlza + 1
End If
With Alza(ContAlza)
.PDisparo = NuevoPrecio
.Name = "Compra Num " & ContAlza
End With
.Buy AtStop, Contratos, Alza(ContAlza).PDisparo, Alza(ContAlza).Name
ContAlza = ContAlza + 1
End If
2) Una vez que hemos enviado la orden de entrada, comprobar a partir de la siguiente barra si se ha ejecutado
For i=0 to ContAlza
If Alza(i).Abierta= False And Alza(i).PDisparo <> 0 then
If APP.FilledOrders(Alza(i).Name, 0, 0) = 1 then
Alza(i).Abierta = True
Alza(i).PIn = Alza(i).PDisparo
If App.Open > Alza(i).PDisparo then Alza(i).PIn = App.Open
Alza(i).PLimit = Alza(i).PIn + Objetivo
Alza(i).PStop = Alza(i).PIn - StopLoss
End If
End If
Alza(i).PDisparo = 0
Next i
If Alza(i).Abierta= False And Alza(i).PDisparo <> 0 then
If APP.FilledOrders(Alza(i).Name, 0, 0) = 1 then
Alza(i).Abierta = True
Alza(i).PIn = Alza(i).PDisparo
If App.Open > Alza(i).PDisparo then Alza(i).PIn = App.Open
Alza(i).PLimit = Alza(i).PIn + Objetivo
Alza(i).PStop = Alza(i).PIn - StopLoss
End If
End If
Alza(i).PDisparo = 0
Next i
3) Si el negocio está abierto, podemos enviar órdenes de salida a distinto precio para cada una de los negocios acumulados:
For i=0 to ContAlza
With Alza(i)
If .Abierta then
APP.ExitLong AtStop, Contratos, .PStop, .Name
APP.ExitLong AtLimit, Contratos, .PLimit, .Name
End If
End With
Next i
With Alza(i)
If .Abierta then
APP.ExitLong AtStop, Contratos, .PStop, .Name
APP.ExitLong AtLimit, Contratos, .PLimit, .Name
End If
End With
Next i
4) Por último, pasamos a controlar si se han ejecutado las salidas del negocio para no enviar más dichas órdenes. Esta parte en realidad es por ser correctos, puesto que si lanzamos órdenes de salida con una etiqueta concreta y no existe ningún contrato abierto con dicha etiqueta, Visual Chart directamente cancela esas órdenes de salida y no las envía al mercado. Como dijimos, tendríamos que gestionar las salidas usando otros métodos:
For i = 0 To ContAlza
With Alza(i)
If .Abierta Then
If (.PStop <> 0 And APP.Low <= .PStop) Then
.Abierta = False
ElseIf (.PLimit <> 0 And APP.High >= .PLimit) Then
.Abierta = False
End If
End If
End With
Next i
Repetiríamos todos los pasos dados para el caso de las ventas.
Comentarios
Publicar un comentario
¡Gracias!