Introducción
TradingMotion SDK Toolkit v2 es una nueva versión de la aplicación de Windows Toolkit v1 para realizar backtest y optimizaciones de estrategias. Hemos rediseñado completamente la interfaz de usuario y añadido nuevas características y mejoras.
Tenga en cuenta que la nueva API v2 no es compatible con las estrategias creadas para la primera versión del Toolkit v1. Lea el apartado Importar estrategias de v1 a v2 para aprender a migrar sus estrategias actuales a la nueva versión de la API v2.
Algunas de las nuevas características más significativas de esta versión:
- El usuario trabajará con dos tipos de proyectos: backtest y optimización.
- Los proyectos se pueden guardar en el ordenador en formato *.tmproj, de esta forma no será necesario volver a crear el proyecto cada vez que abra el Toolkit v2.
Proyecto Backtest
Proyecto para probar una estrategia en períodos históricos, que nos indicará cómo se comporta nuestra estrategia en el pasado.
Proyecto Optimizador
Proyecto para optimizar los parámetros de una estrategia.
Una estrategia que utiliza parámetros es susceptible de ser optimizada (solo es posible optimizar estrategias que tiene, parámetros expuestos). Este proceso permite realizar la búsqueda y selección de los mejores valores para los parámetros que utiliza la estrategia en un histórico concreto, y de esta forma, obtener el máximo rendimiento.
Instalación
Ejecutamos el instalador TradingMotionSDKv2Installer.msi
Hacemos click en Next, se nos mostrarán en pantalla los Términos de Licencia del Software TradingMotion SDK Toolkit v2. Estos términos suponen un contrato entre TradingMotion y el usuario. Se recomienda leer atentamente dicho contrato y, si queremos continuar con la instalación, aceptar los términos marcando la casilla correspondiente y Next.
Tras aceptar el acuerdo anterior elegiremos el directorio donde instalar el programa.
Una vez elegido el directorio de instalación hacemos clic en Install.
Comienza la instalación del Toolkit v2. Este proceso puede tardar varios minutos dependiendo del ordenador.
Con esto finaliza el proceso de instalación y el Toolkit v2 está listo para usarse.
Una vez finalizada la instalación nos aparece la siguiente ventana para incluir las plantillas en el Visual Studio. Seleccionamos los Visual Studio a los que queramos añadir las plantillas y le damos a Install.
Ahora ya tenemos las plantillas instaladas en los Visual Studio seleccionados anteriormente.
Si abrimos el Visual Studio → Nuevo Proyecto podemos ver que ya aparecen las plantillas para programar estrategias con el SDKv2 de TradingMotion.
Primeros pasos
La primera vez que abrimos el toolkit nos pedirá el usuario y contraseña que previamente hemos obtenido mediante el registro, rellenamos los campos nombre de usuario y contraseña y le damos a Login.
Si aún no dispones de un usuario desarrollador de TradingMotion, haz clic abajo a la derecha en “Crear nueva cuenta”. Se abrirá una ventana con el formulario de registro. Rellena los campos obligatorios y haz clic en “Enviar”. Una vez enviado el formulario de registro, recibirás un correo con el usuario y la contraseña.
Una vez realizado el login se abre el toolkit y se muestra el diálogo de “Crear nuevo proyecto”, este diálogo es un asistente que nos ayudará a crear proyectos de Backtest/Optimizador de forma rápida y sencilla. Para crear un nuevo proyecto consulte el apartado Proyecto Backtest/Optimizador.
Proyecto Backtest
Para crear un proyecto de Backtest iniciamos el Toolkit v2, una vez abierto nos aparece el diálogo de “Crear nuevo proyecto” (si no aparece el diálogo ir al menú superior Archivo → Nuevo → Proyecto) le damos a Siguiente.
Tras darle a Siguiente se nos presentarán dos opciones para crear un proyecto:
- Backtest
- Optimizador
Seleccionamos la opción Backtest y le damos a Siguiente.
Una vez elegido el proyecto Backtest tenemos que cargar el assembly que hemos generado previamente con el SDKv2 de TradingMotion (podemos ver que por defecto el Toolkit v2 lleva un assembly de ejemplo). Le damos a cargar y buscamos el assembly de la estrategia para la que queramos crear el proyecto de Backtest, y una vez seleccionado le damos a Finalizar.
Se crea el proyecto de Backtest y ya podemos empezar a trabajar con él.
Pestañas proyecto Backtest
A continuación se describen las diferentes partes de la interfície de un proyecto Backtest.
Backtest
- Archivo cargado: Assembly que contiene la estrategia programada con el SDKv2 de TradingMotion.
- Estrategia: Estrategias incluidas en el binario.
- Gráfico Principal: Producto sobre el que se realizará el backtest, tamaño de las barras y la unidad de tiempo (minutos o días).
- Gráficos Secundarios: Gráficos secundarios que puede usar la estrategia.
- Fecha de Inicio: Fecha de inicio del backtest.
- Fecha de Fin: Fecha de fin del backtest.
- Slippage: El deslizamiento o slippage es la diferencia existente entre el precio al que teóricamente tendría que haberse ejecutado un sistema y el precio al que realmente se ha ejecutado en mercado. Por defecto se utiliza el deslizamiento promedio para cada combinación de símbolos/día que estamos simulando.
- Comisión: Podemos especificar una comisión fija para cada contrato de la estrategia. Por defecto se utiliza la comisión real del símbolo que marca el FCM.
- Coste de Licencia: Precio mensual de la licencia que el desarrollador cobra a los clientes. Por defecto es 0 (gratis).
- Zona horaria: Las fechas de inicio y fin del backtest se encuentran en la zona horaria especificada por el usuario. Las barras llegan a la estrategia en la misma zona horaria.
Para añadir gráficos secundarios hacemos clic en el botón Editar y nos aparecerá la siguiente pantalla:
Elegimos el símbolo, la compresión y la unidad de tiempo (minutos o días), le damos a Añadir y aparecerá en la lista de Gráficos secundarios añadidos. Podemos añadir los gráficos que queramos, una vez añadidos le damos a guardar.
Parámetros de Entrada
Aquí aparecen los parámetros que hemos expuesto cuando hemos programado nuestra estrategia, podemos modificar su valor si es necesario.
Resultados
Como podemos ver el primer bloque de resultados es un resumen de la configuración que hemos indicado en la pestaña backtest. El segundo bloque nos da información más detallada sobre los resultados de nuestra estrategia.
- B&P Neto: El beneficio o pérdida (B/P) total en el período analizado, neto de comisiones, deslizamientos y costes de licencia.
- Profit Factor: El Profit Factor es la relación entre las ganancias y las pérdidas, se calcula dividiendo la suma de ganancias entre la suma de pérdidas.
- Ratio Sharpe: El Ratio de Sharpe mide el exceso de rendimiento por unidad de desviación. Caracteriza lo bien que la rentabilidad de un activo compensa al inversor por el riesgo asumido. Al comparar dos activos frente a un punto de referencia común, el que tiene un mayor ratio de Sharpe ofrece un mejor retorno por el mismo riesgo.
- Sesiones analizadas: El número de sesiones analizadas en el período, es decir, días en los que el mercado sobre el que opera el sistema ha estado abierto, y el sistema ha sido calculado sobre los datos oficiales de dicha sesión.
- ROI Anualizado: El resultado total dividido el número de años en el período (Resultado total= B&P neto dividido por el capital sugerido).
- Comisión por contrato: Comisión aplicada a cada contrato.
- Slippage por contrato: Es la diferencia entre el precio de ejecución indicado por el sistema de trading, y el precio al que efectivamente se ejecuta en cuentas reales.
- B&P Neto sobre Drawdown: Medida de riesgo que indica las ganancias que tendremos en relación al drawdown (pérdidas). Por ejemplo un B&P Neto sobre Drawdown de 1.5 nos indica que de cada 1000€ de pérdidas tendremos unos 1500€ de beneficios.
- Expectancia matemática: Este ratio matemático nos indica en todo momento la esperanza matemática de éxito a la hora de invertir usando la estrategia.
- Sesiones ganadoras: El número de sesiones de trading en el período con resultados mayores a 0.
- Media de sesiones ganadoras: El promedio de resultado entre todas las sesiones ganadoras.
- Sesiones perdedoras: El número de sesiones de trading en el período con resultados menores a 0.
- Media de sesiones perdedoras: El promedio de resultado entre todas las sesiones perdedoras.
- Peor drawdown: La mayor racha de pérdidas que se ha producido, medido al cierre de sesión, con la fecha del valor menor listada.
- Mejor sesión: El resultado más alto en una sesión dentro del período analizado.
- Peor sesión: El resultado más bajo en una sesión dentro del período analizado.
- Capital sugerido: El capital sugerido se calcula con una metodología propietaria de TradingMotion, y está pensada para un usuario MUY ARRIESGADO con el criterio de tener más de un 95% de esperanza matemática (2-sigma) de no perder más del 33% del capital sugerido. En ningún caso se garantiza que el sistema no pueda perder más de ese porcentaje del capital sugerido.
- Capital requerido: El capital requerido es la cantidad que debe haber en la cuenta al inicio de cada sesión, para poder activar o mantener activo el sistema de trading. En el capital requerido se incluyen las garantías que se tendrían que depositar en el mercado en caso de que el sistema se quede abierto (no aplicable a sistemas intradía).
El botón "Exportar a Excel" situado abajo a la derecha sirve para exportar los resultados de la estrategia a una hoja de cálculo Excel.
B&P
El gráfico de B&P muestra el beneficio o pérdida total en el período analizado, neto de comisiones, deslizamientos y costes de licencia.
OHLC
En el gráfico OHLC encontramos la siguiente información:
- Los datos del mercado (en formato de velas: Apertura-Máx-Mín-Cierre).
- El volumen.
- Los indicadores que hemos añadido a nuestra estrategia.
- Las operaciones realizadas por la estrategia, junto con las órdenes ejecutadas con sus etiquetas personalizadas (flechas verdes representan las posiciones largas, flechas rojas posiciones cortas).
- El B&P para cada orden y líneas rectas que unen las operaciones (verde si el B&P es positivo, rojo si es negativo).
Log de operaciones
Listado de todas las órdenes que ha ejecutado la estrategia.
Log de sesiones
Información detallada día a día de la estrategia.
Log de barras
Listado de todas las barras que utiliza la estrategia.
Dispersión
Gráfico de dispersión de las órdenes ejecutadas por la estrategia.
Drawdown máximo
Gráfico que representa las pérdidas de la estrategia.
Salida
En la salida podemos ver las trazas de log que hemos programado en la estrategia.
Para más información sobre las trazas de log ver apartado Debug de estrategias con Visual Studio.
Proyecto de Optimizador
Para crear un proyecto de Optimizador iniciamos el Toolkit v2, una vez abierto nos aparece el diálogo de “Crear nuevo proyecto” (si no aparece el diálogo ir al menú superior Archivo → Nuevo → Proyecto) le damos a Siguiente.
Tras darle a Siguiente se nos presentarán dos opciones para crear un proyecto:
- Backtest
- Optimizador
Seleccionamos la opción Optimizador y le damos a Siguiente.
Una vez elegido el proyecto Optimizador tenemos que cargar el assembly que hemos generado previamente con el SDKv2 de TradingMotion (podemos ver que por defecto el Toolkit v2 lleva un assembly de ejemplo). Le damos a cargar y buscamos el assembly de la estrategia que queramos crear el proyecto de Optimizador, una vez seleccionado le damos a Finalizar.
Se crea el proyecto de Optimizador y ya podemos empezar a trabajar con él.
Pestañas proyecto Optimizador
A continuación se describen las diferentes partes de la interfície de un proyecto Optimizador.
Optimización
- Archivo cargado: Assembly que contiene la estrategia programada con el SDKv2 de TradingMotion.
- Estrategia: Estrategias incluidas en el binario.
- Gráfico Principal: Producto sobre el que se realizará el backtest, tamaño de las barras y la unidad de tiempo (minutos o días).
- Gráficos Secundarios: Gráficos secundarios que puede usar la estrategia.
- Fecha de Inicio: Fecha de inicio del backtest.
- Fecha de Fin: Fecha de fin del backtest.
- Slippage: El deslizamiento o slippage es la diferencia existente entre el precio al que teóricamente tendría que haberse ejecutado un sistema y el precio al que realmente se ha ejecutado en mercado. Por defecto se utiliza el deslizamiento promedio para cada combinación de símbolos/día que estamos simulando.
- Comisión: Podemos especificar una comisión fija para cada contrato de la estrategia. Por defecto se utiliza la comisión real del símbolo que marca el FCM.
- Coste de Licencia: Precio mensual de la licencia que el desarrollador cobra a los clientes. Por defecto es 0 (gratis).
- Zona horaria: Las fechas de inicio y fin del backtest se encuentran en la zona horaria especificada por el usuario. Las barras llegan a la estrategia en la misma zona horaria.
Para añadir gráficos secundarios hacemos clic en el botón Editar y nos aparecerá la siguiente pantalla:
Elegimos el símbolo, la compresión y la unidad de tiempo (minutos o días), le damos a Añadir y aparecerá en la lista de Gráficos secundarios añadidos. Podemos añadir los gráficos que queramos, una vez añadidos le damos a guardar.
Ajustes de Optimización
Tenemos dos tipos de algoritmo de optimización:
- Fuerza Bruta: El algoritmo más simple, calcula las distintas posibilidades siguiendo un orden preciso, de forma que comienza con el valor del primer parámetro y lo combina con el resto de valores de los demás parámetros, para seguir con el segundo y así sucesivamente.
- Genético: Algoritmo dotado de inteligencia artificial que calcula las distintas posibilidades siguiendo un mecanismo de selección eficiente que va combinando fundamentalmente aquellos valores que van demostrando mejor resultado (según la función de optimización).
Funciones de optimización
La función de optimización será la que guiará nuestro algoritmo genético en la búsqueda de las mejores soluciones, puede estar compuesta de más de un parámetro. Por ejemplo, si nuestra función de optimización está compuesta por el B&P y el Ratio Sharpe, nuestro algoritmo priorizará los resultados con un buen B&P y Ratio Sharpe para combinarlos y generar mejores resultados.
Para añadir parámetros a la función de optimización hacemos clic en editar y nos aparece la siguiente pantalla.
Podemos escoger el parámetro, su peso dentro de la función y si queremos maximizar o minimizar. Hacemos clic en añadir y nos aparecerá en la lista de Funciones de optimización añadidas. Podemos añadir los parámetros que queramos, y una vez añadidos le damos a Guardar.
Parámetros de Entrada
Aquí aparecen los parámetros que hemos expuesto cuando hemos programado nuestra estrategia.
Combinaciones
El rango que comprende los valores mín y máx, son los límites que tendrá dicho parámetro en las combinaciones durante la optimización. El paso es el incremento que se hace del valor mínimo hasta llegar al máximo, por ejemplo, si tenemos un mín de 20 y un máx de 30 con paso de 2, los valores que tendrá dicho parámetro serán 20-22-24-26-28-30.
Resultados
Muestra una lista de todas las combinaciones que ha hecho el algoritmo en el proceso de optimización. En la lista podemos observar los parámetros y varias métricas de rendimiento.
- La fila en verde muestra la mejor combinación, la que dio el mejor resultado (FitnessFunction) en la simulación de backtest.
- La fila en amarillo muestra la combinación recomendada por el sistema. La combinación recomendada se decide según un algoritmo de agrupamiento de inteligencia artificial heurístico llamado vecino más cercano.
Si hacemos clic en el símbolo
que se encuentra en el título de la columna, aparece la opción de filtrar los resultados.
Se pueden filtrar todos los campos que componen las métricas de rendimiento. Seleccionamos el parámetro, la función (mayor que o menor que), el valor y le damos a Filtro. En este caso hemos filtrado por el Profit Factor > 1,6.
Para mostrar/ocultar una columna, hacemos clic con el botón derecho del mouse sobre el título de una columna y aparecerá la siguiente pantalla:
Podemos observar que aparece una lista de todas las columnas, donde podemos seleccionar qué columnas queremos mostrar y cuales ocultar. El check quiere decir que esa columna està visible, sino está oculta. Simplemente haciendo clic en el nombre cambiamos el estado de la columna.
Para obtener más información sobre un resultado de optimización concreto hacemos doble click encima de la fila y nos aparecerá la siguiente pantalla
Podemos ver que tiene las mismas pestañas que un proyecto backtest, con la diferencia que hay un nuevo botón “Crear proyecto backtest” en la pestaña de resultados. Este botón nos permite exportar el resultado de una optimización a proyecto backtest, si hacemos clic se nos creará un nuevo proyecto de backtest con la combinación concreta de la optimización de ese resultado.
Combinaciones erróneas
Muestra una lista detallada de todas las combinaciones que no han podido hacer el backtest.
Mapa de calor
Mapa de calor para detectar el mejor rendimiento de las parejas de parámetros.
Por ejemplo, este mapa de calor está comparando la siguiente pareja de parámetro: el Slow Moving Average Period con el Fast Moving Average Period. Se puede ver a simple vista que la pareja Slow Moving Average Period 27 - Fast Moving Average Period 25, tiene el color más verde. Esto significa que esta combinación funciona mucho mejor que, por ejemplo, la pareja Slow Moving Average Period 29 - Fast Moving Average Period 18 (color rojo).
El Mapa de calor permite identificar rápidamente las "zonas calientes" (áreas donde la combinación de parámetros dan su mejor rendimiento).
Las dos listas de parámetros en la parte superior, permiten a los desarrolladores seleccionar la pareja de parámetros que quieren visualizar (comparar).
El filtro de color en la parte inferior derecha permite fijar el umbral para el color rojo puro. De esta forma podemos estirar la gama de colores, añadiendo más detalle sobre las zonas con valores similares.
Rendimiento de parámetro
Este gráfico muestra el rendimiento de un parámetro.
Los diferentes valores de optimización del parámetro están representados en el eje horizontal del gráfico, mientras que el eje vertical muestra la puntuación del parámetro optimizado elegido para cada valor. En la parte superior hay una lista con todos los parámetros para analizar uno a uno su rendimiento.
Salida
En la salida podemos ver las trazas de log que hemos programado en la estrategia.
Para más información sobre las trazas de log ver apartado Debug de estrategias con Visual Studio.
Importar estrategias de v1 a v2
Hemos creado una herramienta para convertir las estrategias del Toolkit v1 a v2, de esta forma podrás utilizar tus estrategias de v1 en el nuevo Toolkit v2.
Por favor antes de empezar a convertir un proyecto v1 revisa que funciona y compila bien.
Para convertir un proyecto al Toolkit v2, vamos al menú de arriba Herramientas → Convertir proyecto v1 a v2
Una vez hecho clic en la opción Convertir proyecto v1 a v2 nos aparecerá una pantalla con tres botones:
- Cargar proyecto v1: Seleccionar el proyecto v1.
- Seleccionar directorio v2: Seleccionar el directorio donde quieres guardar el proyecto en formato v2.
- Convertir: Iniciar proceso de conversión.
Una vez cargado el proyecto v1 y seleccionado el directorio v2 ya podemos hacer clic en Convertir.
Una vez hecho clic en Convertir, empezará el proceso de conversión, en el log de Salida nos informará del proceso y resultado.
Si todo ha ido bien, se abrirá el directorio del proyecto v2, donde encontraremos el proyecto compilado y listo para usar.
Subir estrategias al marketplace de TradingMotion
Antes de enviar una estrategia al marketplace vamos a explicar las estrategias y sus versiones. Supongamos que tengo una estrategia que se llama Golden Cross Strategy y que tiene 3 parámetros expuestos:
Nombre de la estrategia: Golden Cross Strategy
Parámetros:
- Slow Moving Average Period
- Fast Moving Average Period
- Initial Trailing Stop ticks margin
Y de esta estrategia modificando el valor los parámetros (sin modificar la estrategia) saco 3 versiones, una que será sobre el Dax otra sobre el Aex y la última sobre el Ibex.
Versiones de Golden Cross Strategy:
- Nombre Versión: Golden Cross Dax 60'
- DAX 60 Minutos
- Slow Moving Average Period: 20
- Fast Moving Average Period: 5
- Initial Trailing Stop ticks margin: 20
- Nombre Versión: Golden Cross Aex 147'
- AEX 147 Minutos
- Slow Moving Average Period: 17
- Fast Moving Average Period: 8
- Initial Trailing Stop ticks margin: 75
- Nombre Versión: Golden Cross Ibex 15'
- IBEX35 15 Minutos
- Slow Moving Average Period: 25
- Fast Moving Average Period: 2
- Initial Trailing Stop ticks margin: 47
Como vemos las 3 versiones son de la misma estrategia (Golden Cross Strategy), la primera vez que queramos subir una versión debemos crear la estrategia Golden Cross Strategy, una vez creada, cuando queramos subir más versiones solo tendremos que seleccionarla. En caso de haber modificado el código de la estrategia, será necesario crear una nueva dado que las estrategias no van a coincidir.
Para subir una estrategia al marketplace de TradingMotion, vamos al menú de arriba Herramientas → Enviar proyecto a TradingMotion (este ítem solo está habilitado cuando es un proyecto de backtest y hay resultado).
Una vez hecho clic en la opción Enviar proyecto a TradingMotion nos aparecerá una nueva ventana con un resumen de los parámetros de la estrategia (fecha de inicio, fecha de fin, producto y compresión...). Verás que la mayoría de campos no son editables, si desea cambiar alguno de estos campos, tendrá que modificar los settings de la estrategia y volver hacer el backtest.
Campos editables:
- Nombre de la Estrategia: Seleccionar la estrategia en el listado, si es la primera versión de la estrategia y todavía no la hemos creado, debemos seleccionar <Añadir nueva estrategia…> y rellenar el campo Nueva Estrategia con el nombre que queramos.
- Nombre de la Versión: Este nombre es el que se mostrará en el marketplace de TradingMotion.
- Coste de Licencia: El coste mensual de la licencia que quieres aplicar a la estrategia. Si modificas este valor, se volverá a realizar un backtest para aplicar el coste en el resultado. En cualquier momento puede modificar el precio en el portal de desarrolladores.
- Comentarios: Cualquier cosa que nos quieras comentar sobre la versión de la estrategia puedes escribirla aquí.
Una vez rellenado los campos editables ya podemos enviar nuestra estrategia al marketplace de TradingMotion haciendo clic en Enviar. Nos pondremos en contacto después de revisar su estrategia para confirmar su publicación.
Librería Base
La librería está compilada en la dll TradingMotionSDKv2.dll, y es necesaria su referencia para el desarrollo de cualquier programa TradingMotion. Esta librería incluye todos los conceptos y componentes para poder operar en un mercado financiero.
Espacio de nombres de TradingMotionSDKv2:
- TradingMotion.SDKv2.Markets: Contiene las clases que hacen referencia a los conceptos de mercado.
- TradingMotion.SDKv2.Markets.Symbols: Contiene las clases que definen los símbolos financieros disponibles para operar.
- TradingMotion.SDKv2.Markets.Indicators: Contiene las clases que modelan los conceptos relacionados con los indicadores técnicos.
- TradingMotion.SDKv2.Markets.Order: Contiene las clases utilizadas para operar en los mercados.
- TradingMotion.SDKv2.Markets.Series: Contiene la estructura de datos Serie, que proporciona un método fácil para "mirar atrás (lookback)" que se utiliza comúnmente en las operaciones a mercado.
- TradingMotion.SDKv2.Algorithm: Contiene las clases que hacen referencia a la ejecución del programa/simulación
- TradingMotion.SDKv2.Programs.InputParameter: Contiene las clases que definen los parámetros que los desarrolladores pueden exponer.
La librería de TradingMotionSDKv2 contiene algunos otros espacios de nombres. Estos son utilizados por los procesos internos (como los servicios web de recuperación de datos, o cálculos estadísticos ...) y no se espera que los desarrolladores interactúen con ellos.
Clases principales
Chart
Modelo financiero Apertura - Máx - Mín - Cierre (OHLC). Está definida por dos parámetros: el símbolo (en el que se ejecutará el algoritmo) y su compresión.
Symbol
Contiene toda la información de un producto financiero que es comercializable a través de la plataforma TradingMotion. Contiene el nombre, la moneda, el valor de tick, valor del punto, las horas de mercado…
Para obtener una lista completa de los productos disponibles ver el Apéndice II → Productos Disponibles
Bar
Modelado en formato velas (Apertura - Máx - Mín - Cierre), fecha y hora, intervalo de tiempo (compresión) y el volumen de contratos negociados en la barra.
Serie
Esta clase contiene un listado de valores que se acceden en orden inverso. Resulta bastante útil para el tipo de operación “mirar atrás (lookback)” que se utiliza comúnmente en las operaciones a mercados financieros.
Por ejemplo, si tenemos una lista con los precios de cierre Dim closePrices As
Serie(Of Double)
, se puede acceder al precio de cierre más reciente con la instrucción closePrices(0)
,
el precio de cierre anterior sería closePrices(1)
, y así sucesivamente.
Con el objeto Serie es extremadamente simple detectar los cruces. Por ejemplo imaginemos que tenemos los precios de cierre Dim closePrices As
Serie(Of Double)
y el valor del máximo de ayer almacenado en yesterdayHigh Dim yesterdayHigh As
Double
. Para detectar si estamos rompiendo el valor máximo de ayer, hecemos en VB.NET:
Visual Basic.NET
If (closePrices(1) < yesterdayHigh) And closePrices(0) > yesterdayHigh) Then 'Previous bar price was below yesterday's high and current bar price is above yesterday's high Console.WriteLine("Yesterday's high breakout detected!") End If
C#
if (closePrices[1] < yesterdayHigh && //Previous bar price was below yesterday's high closePrices[0] > yesterdayHigh) //Current bar price is above yesterday's high { Console.WriteLine("Yesterday's high breakout detected!"); }
Como nota final, disponemos del atributo MaxElements con el fin de optimizar el uso de memoria del sistema, de esta forma podemos indicar el número máximo de elementos que podrá almacenar una Serie. Por ejemplo, si el MaxElements es igual a 2 y hemos añadido 10 valores a la serie, sólo estarán disponibles los 2 últimos valores añadidos.
Visual Basic.NET
Dim mySerie As Serie(Of String) = New Serie(Of String)("mySerie") mySerie.MaxElements = 2 mySerie.AddValue("1st element") mySerie.AddValue("2nd element") Console.WriteLine(mySerie(0)) 'This prints "2nd element" Console.WriteLine(mySerie(1)) 'This prints "1st element" mySerie.AddValue("3rd element") Console.WriteLine(mySerie(0)) 'This prints "3rd element" Console.WriteLine(mySerie(1)) 'This prints "2nd element" Console.WriteLine(mySerie(2)) 'This prints Nothing because MaxElements = 2, so we are trying to access an out of range element
C#
Serie<String> mySerie = new Serie<String>("mySerie", false); mySerie.MaxElements = 2; mySerie.AddValue("1st element"); mySerie.AddValue("2nd element"); Console.WriteLine(mySerie[0]); //This prints "2nd element" Console.WriteLine(mySerie[1]); //This prints "1st element" mySerie.AddValue("3rd element"); Console.WriteLine(mySerie[0]); //This prints "3rd element" Console.WriteLine(mySerie[1]); //This prints "2nd element" Console.WriteLine(mySerie[2]); //This prints null because MaxElements = 2, so we are trying to access an out of range element
BarSerie
BarSerie es una clase de ayuda que permite a los desarrolladores acceder a los datos anteriores de las barras a través de las propiedades de los objetos de la serie:
- Serie(Of Bar) Bars
- Serie(Of DateTime) Time
- Serie(Of Double) Open
- Serie(Of Double) High
- Serie(Of Double) Low
- Serie(Of Double) Close
- Serie(Of Double) Volume
Indicator
Indicator es una clase abstracta que modela un indicador técnico. Los indicadores técnicos son "procesos" que tienen una serie de entrada, realizan cálculos, y devuelven varias series de salida que podemos utilizar en nuestros programas.
Los desarrolladores pueden crear sus propios indicadores técnicos. El proceso sería:
- Crear una clase personalizada que hereda de Indicator.
- Elegir el tipo de entrada de la Serie (que puede ser una Serie(Of Double) o una Serie(Of Bar))
- Declarar la salida de la Serie(Of Double) que el indicador personalizado proporcionará como resultado.
- Implementar el proceso de cálculo, sobreescribiendo el método Indicator.Compute
Visual Basic.NET
Imports TradingMotion.SDKv2.Markets Imports TradingMotion.SDKv2.Markets.Indicators Imports TradingMotion.SDKv2.Markets.Series Public Class ExampleTradingMotionIndicator Inherits TALibIndicatorSuperclass(Of Bar) Public Sub New (ByVal source As Serie (Of Bar)) MyBase.new(source) End Sub Public Overrides Function GetWarmUpPeriod() As UInteger Throw New NotImplementedException End Function Public Overrides Sub Compute() Throw New NotImplementedException End Sub End Class
C#
using TradingMotion.SDKv2.Markets; using TradingMotion.SDKv2.Markets.Indicators; using TradingMotion.SDKv2.Markets.Series; namespace ExampleStrategy { public class ExampleTradingMotionIndicator : TALibIndicatorSuperclass<Bar> { public ExampleTradingMotionIndicator(Serie<Bar> source) : base(source) { } public override uint GetWarmUpPeriod() { throw new NotImplementedException(); } public override void Compute() { throw new NotImplementedException(); } } }
Visual Basic.NET
Imports TradingMotion.SDKv2.Markets Imports TradingMotion.SDKv2.Markets.Indicators Imports TradingMotion.SDKv2.Markets.Series Public Class ExampleTradingMotionIndicator Inherits TALibIndicatorSuperclass(Of Bar) Dim TimePeriod As Integer Public Sub New (ByVal source As Serie (Of Bar), ByVal period As Integer) MyBase.new(source) Name = "ExampleTmIndicator" TimePeriod = period AddOutputSerie(New Serie(Of Double)(Name)) End Sub Public Function GetTmIndicator() As Serie(Of Double) Return ME(Name) End Function Public Overrides Function GetWarmUpPeriod() As UInteger Return TimePeriod End Function Public Overrides Sub Compute() Throw New NotImplementedException End Sub End Class
C#
using TradingMotion.SDKv2.Markets; using TradingMotion.SDKv2.Markets.Indicators; using TradingMotion.SDKv2.Markets.Series; namespace ExampleStrategy { public class ExampleTradingMotionIndicator : TALibIndicatorSuperclass<Bar> { private int _timePeriod; public ExampleTradingMotionIndicator(Serie<Bar> source) : base(source) { Name = "ExampleTmIndicator"; _timePeriod = period AddOutputSerie(new Serie<double>(Name)) } public Serie<double> GetTmIndicator() { return this[Name]; } public override uint GetWarmUpPeriod() { return (uint)_timePeriod; } public override void Compute() { throw new NotImplementedException(); } } }
Visual Basic.NET
Imports TradingMotion.SDKv2.Markets Imports TradingMotion.SDKv2.Markets.Indicators Imports TradingMotion.SDKv2.Markets.Series Public Class ExampleTradingMotionIndicator Inherits TALibIndicatorSuperclass(Of Bar) Dim TimePeriod As Integer Public Sub New (ByVal source As Serie (Of Bar), ByVal period As Integer) MyBase.new(source) Name = "ExampleTmIndicator" TimePeriod = period AddOutputSerie(New Serie(Of Double)(Name)) End Sub Public Function GetTmIndicator() As Serie(Of Double) Return ME(Name) End Function Public Overrides Function GetWarmUpPeriod() As UInteger Return TimePeriod End Function Public Overrides Sub Compute() Dim tm As Double = 0 If (sourceSerie.Count > Me.GetWarmUpPeriod()) Then tm = (100 * sourceSerie(0).Close) / sourceSerie(0).Open End If Me(Name).AddValue(tm) End Sub End Class
C#
using TradingMotion.SDKv2.Markets; using TradingMotion.SDKv2.Markets.Indicators; using TradingMotion.SDKv2.Markets.Series; namespace ExampleStrategy { public class ExampleTradingMotionIndicator : TALibIndicatorSuperclass<Bar> { private int _timePeriod; public ExampleTradingMotionIndicator(Serie<Bar> source) : base(source) { Name = "ExampleTmIndicator"; _timePeriod = period AddOutputSerie(new Serie<double>(Name)) } public Serie<double> GetTmIndicator() { return this[Name]; } public override uint GetWarmUpPeriod() { return (uint)_timePeriod; } public override void Compute() { double tm = 0; if (sourceSerie.Count > GetWarmUpPeriod()) { tm = (100 * sourceSerie[0].Close) / sourceSerie[0].Open; } this[Name].AddValue(tm); } } }
TradingMotionSDKv2 incluye más de 120 indicadores técnicos listos para usarse, tales como medias móviles, las Bandas de Bollinger, ATR, RSI, patrón Harami... Véase el Anexo I - Indicadores técnicos para obtener la lista completa..
Las propiedades más importantes de los objetos de indicador son:
- Serie sourceSerie: Contiene los datos de entrada para el indicador técnico. Estos pueden ser una serie de barras (cuando el indicador requiere valores de apertura, máximo, mínimo y cierre) o una serie de doubles (por ejemplo, cuando sólo requiere los precios de cierre). También podemos utilizar la salida de un indicador como sourceSerie (por ejemplo, podemos calcular un promedio móvil sobre la salida del indicador RSI).
- Serie outputSeries: Contiene la serie de salida del indicador técnico. Una media móvil contendrá sólo una serie de salida, en cambio en el indicador MACD la salida típica son 3 series diferentes (MACD, MACD Signal y MACD Average).
- Boolean ShownInChart: Indica si el indicador se muestra en el gráfico OHLC o no (por defecto true).
- Boolean ShownOverInputSeries: Devuelve true si el indicador tiene que ser dibujado sobre el gràfico principal. Si es false, se elaborará en un nuevo gràfico debajo del principal (por defecto false).
InputParameter
La classe InputParameter representa las variables que los desarrolladores pueden exponer externamente. De esta forma en el Toolkit v2 se pueden probar diferentes valores sin tener que volver a compilar el programa.
Algunos ejemplos de parámetros de entrada podrían ser el periodo de una media móvil, o la diferencia de precio para establecer un orden stop. Véase el Crear un nuevo proyecto Strategy para ver un ejemplo práctico
Otra característica de estos parámetros de entrada es que pueden ser optimizados en el Toolkit v2 con el proyecto optimizador. Véase el Proyecto Optimizador
Los tipos permitidos de InputParameter son: Integer, Double, String y TimeSpan. Las cadenas no se pueden optimizar.
Visual Basic.NET
Public Overrides Function SetInputParameters() As InputParameterList Return New InputParameterList() From() { New InputParameter("Example Integer", 20), New InputParameter("Example Double", 5.5), New InputParameter("Example String", "Hello world"), New InputParameter("Example TimeSpan", new TimeSpan(15, 0, 0)), } End Function
C#
public override InputParameterList SetInputParameters() { return new InputParameterList { new InputParameter("Example Integer", 20), new InputParameter("Example Double", 5.5), new InputParameter("Example String", "Hello world"), new InputParameter("Example TimeSpan", new TimeSpan(15, 0, 0)), }; }
Order
La clase Order modela las órdenes que se envían al mercado. Sus propiedades son:
- Side: Buy or Sell
- Quantity: Entero sin signo. Especifica el número de contratos que queremos comprar o vender.
- Label: Campo de texto en el que el desarrollador puede etiquetar órdenes específicas, con el fin de ayudar a identificarlas más adelante.
- Price: Necesario para activar la orden (requerido solo para las órdenes de límite/stop).
Hay 3 tipos diferentes de órdenes:
- MarketOrder: Comprar o vender inmediatamente al mejor precio disponible actualmente.
- LimitOrder: Establece el precio máximo o mínimo en el que usted está dispuesto a comprar o vender el valor (es necesario el precio límite). Garantiza que la transacción se hará a un precio determinado.
- StopOrder: Se ejecuta solo cuando el precio alcanza el nivel de seguridad marcado (es necesario el precio de stop / seguridad). Una vez que el precio de parada se ha activado, se convierte en una orden de mercado, por lo que será ejecutada al mejor precio posible (el precio de parada no está garantizada).
Los objetos Order sólo están permitidos si estás utilizando el “Advanced Order Management“ (Véase el Usos avanzados de la clase Strategy).
Strategy
La Strategy es una clase abstracta que los desarrolladores necesitan implementar para poder crear un programa ejecutable en TradingMotion.
El método principal de una estrategia es Sub Strategy.OnNewBar()
, que se llama cada vez que llega una nueva barra (tanto en backtest como en tiempo real). En este método el programador comprueba el estado actual del mercado, así como los datos sobre los indicadores técnicos y los objeto de las barras, y en consecuencia coloca las órdenes para entrar/salir.
Las Strategies programadas en TradingMotionSDKv2 se pueden subir a la plataforma TradingMotion, donde después de un control de calidad, pueden ser publicadas.
Programando nuestra primera estrategia
Vamos a codificar una estrategia automática basada en el "Golden Cross": Cruce que se produce cuando una media móvil simple de periodo corto (por ejemplo de 5 barras) rompe por encima de una media móvil simple de periodo largo (por ejemplo de 20 barras).
El cierre de la posición lo haremos mediante un Trailing Stop.
Los Trailing Stops se utilizan para reducir las pérdidas y maximizar los beneficios. Consiste en la colocación de una orden de stop algunos puntos por debajo del precio de compra, y moverla hacia arriba junto con el precio sólo cuando se mueve a nuestro favor. De esta forma se mantienen los beneficios cuando el precio sube, por otro lado, cuando el precio se invierte y cruza el nivel de parada, la orden se ejecuta y cierra la posición automáticamente.
1. Crear un nuevo proyecto Strategy
Abrimos el Microsoft Visual Studio vamos a Nuevo Proyecto VisualBasic / C# → TradingMotionSDK → TradingMotion Trading Strategy (asegúrate de que esté seleccionado el .NET Framework 4).
2. Crear nuestra clase “Strategy”
Una vez creado el proyecto, vamos a crear la clase GoldenCrossStrategy. Hacemos clic con el botón derecho del mouse encima del proyecto → Añadir → Nuevo Ítem → TradingMotionSDK → Strategy class.
La nueva clase contiene un esqueleto de todas las propiedades y métodos requeridos por la estrategia.
3. Implementar los métodos de la clase “Strategy”
Public Overrides ReadOnly Property Name As String
Devuelve el nombre de la estrategia.
Visual Basic.NET
Public Overrides ReadOnly Property Name As String Get Return "Golden Cross strategy" End Get End Property
C#
public override string Name { get { return "Golden Cross strategy"; } }
Public Overrides Function SetInputParameters() As InputParameterList
Este método permite al desarrollador exponer los parámetros de la estrategia. (Véase Clases principales → InputParameter).
Vamos a exponer los períodos de los dos indicadores: media móvil simple de periodo lento y la media móvil simple de periodo rápido, de esta forma vamos a ser capaces de probar diferentes combinaciones de valores fácilmente. También vamos a exponer la distancia de margen en puntos que utilizaremos para colocar nuestra orden trailing stop.
Visual Basic.NET
Public Overrides Function SetInputParameters() As InputParameterList Dim parameters As New InputParameterList() parameters.Add(New InputParameter("Slow Moving Average Period", 20)) parameters.Add(New InputParameter("Fast Moving Average Period", 5)) parameters.Add(New InputParameter("Initial Trailing Stop points margin", 15.0)) Return parameters End Function
C#
public override InputParameterList SetInputParameters() { InputParameterList parameters = new InputParameterList(); parameters.Add(new InputParameter("Slow Moving Average Period", 20)); parameters.Add(new InputParameter("Fast Moving Average Period", 5)), parameters.Add(new InputParameter("Initial Trailing Stop points margin", 15D)); return parameters; }
Public Overrides Sub OnInitialize()
Este método es el lugar adecuado para crear los indicadores técnicos que queramos utilizar en nuestra estrategia.
Se recomienda declarar los objetos de indicador como atributos de la clase, y crear instancias de ellos en este método. De esta forma será más fácil acceder a sus valores.
Visual Basic.NET
'Declare the moving averages as class attributes Dim indSlowSMA As SMAIndicator Dim indFastSMA As SMAIndicator
C#
//Declare the moving averages as class attributes SMAIndicator indSlowSMA; SMAIndicator indFastSMA;
Una vez que hemos definido los indicadores como atributos de la clase, podemos crear instancias de estos en el método OnInitialize
y añadirlos a la estrategia con la función Sub AddIndicator(name As String, indicator As Indicator)
.
Visual Basic.NET
Public Overrides Sub OnInitialize() indSlowSMA = New SMAIndicator(Bars.Close, GetInputParameter("Slow Moving Average Period")) indFastSMA = New SMAIndicator(Bars.Close, GetInputParameter("Fast Moving Average Period")) AddIndicator("Slow SMA", indSlowSMA) AddIndicator("Fast SMA", indFastSMA) End Sub
C#
public override void OnInitialize() { indSlowSMA = new SMAIndicator(Bars.Close, (int)GetInputParameter("Slow Moving Average Period")); indFastSMA = new SMAIndicator(Bars.Close, (int)GetInputParameter("Fast Moving Average Period")); AddIndicator("Slow SMA", indSlowSMA); AddIndicator("Fast SMA", indFastSMA); }
Public Overrides Sub OnNewBar()
Este método es donde el desarrollador tiene que escribir las reglas para entrar/salir del mercado.
Para nuestra estrategia GoldenCrossStrategy, tenemos que colocar una orden de compra a mercado con volumen = 1 cuando en la barra actual, la media móvil simple de periodo rápido cruza por encima de la media móvil simple de periodo lento, y establecer la orden trailing stop para la salida.
Visual Basic.NET
'Declare the Trailing Stop Order as class attribute Dim trailingStopOrder As StopOrder Public Overrides Sub OnNewBar() If (GetOpenPosition() = 0) Then 'We're flat. Check if current bar contains a golden cross If (indFastSMA.GetAvSimple()(0) > indSlowSMA.GetAvSimple()(0) And indFastSMA.GetAvSimple()(1) < indSlowSMA.GetAvSimple()(1)) Then 'Check if Fast moving average is higher than Slow moving average in current bar and 'Check if Fast moving average was lower than Slow moving average in previous bar 'Going Long (Buying 1 Contract at Market price) InsertOrder(New MarketOrder(OrderSide.Buy, 1, "Golden Cross - Open long position")) 'Set the level for our trailing stop trailingStopOrder = New StopOrder(OrderSide.Sell, 1, Bars.Close(0) - GetInputParameter("Initial Trailing Stop points margin"), "Trailing Stop Level Hit - Close long position") InsertOrder(trailingStopOrder) End If Else 'We're long. Check if the price has gone up If (Bars.Close(0) > Bars.Close(1)) Then 'The price has moved in favour of our position, increase the trailing stop level accordingly trailingStopOrder.Price = trailingStopOrder.Price + (Bars.Close(0) - Bars.Close(1)) ModifyOrder(trailingStopOrder) End If End If End Sub
C#
//Declare the Trailing Stop Order as class attribute StopOrder trailingStopOrder; public override void OnNewBar() { if (GetOpenPosition() == 0) { //We're flat. Check if current bar contains a golden cross if (indFastSMA.GetAvSimple()[0] > indSlowSMA.GetAvSimple()[0] && indFastSMA.GetAvSimple()[1] < indSlowSMA.GetAvSimple()[1]) //Check if Fast moving average is higher than Slow moving average in current bar and //Check if Fast moving average was lower than Slow moving average in previous bar { //Going Long (Buying 1 Contract at Market price) InsertOrder(new MarketOrder(OrderSide.Buy, 1, "Golden Cross - Open long position")); //Set the level for our trailing stop trailingStopOrder = new StopOrder(OrderSide.Sell, 1, Bars.Close[0] - (double)GetInputParameter("Initial Trailing Stop points margin"), "Trailing Stop Level Hit - Close long position"); InsertOrder(trailingStopOrder); } } else { //We're long. Check if the price has gone up if (Bars.Close[0] > Bars.Close[1]) { //The price has moved in favour of our position, increase the trailing stop level accordingly trailingStopOrder.Price = trailingStopOrder.Price + (Bars.Close[0] - Bars.Close[1]); ModifyOrder(trailingStopOrder); } } }
4. Depurando nuestra estrategia
Una vez que hemos creado nuestra clase GoldenCrossStrategy, es el momento de depurar y probar si funciona como se esperaba.
En primer lugar tendrá que poner sus credenciales TradingMotionAPI en el archivo "app.config" del proyecto:
<appSettings> <add key="TradingMotionAPILogin" value="your_login_here"/> <add key="TradingMotionAPIPassword" value="your_password_here"/> </appSettings>
Estas credenciales son necesarias para descargar los datos históricos del mercado de los servidores TradingMotion para realizar el backtest.
El proyecto TradingMotion contiene una clase DebugBacktest que es una aplicación de consola. Necesitamos crear una nueva instancia de nuestra estrategia, por lo que vamos a cambiar el tipo de objeto de GoldenCrossStrategy (línea 40 en C#, la línea 38 en VB) al nombre de nuestra estrategia. A continuación, basta con ejecutar el proyecto (tecla F5) y se realizará un backtest de 6 meses con el producto E-mini S&P de 30 minutos. Se mostrará una ventana de consola con esta salida:
Podemos colocar un punto de interrupción (breakpoint) en cualquier método, y durante el backtest el programa interrumpirá momentáneamente la ejecución allí, y nos permitirá ver el estado de nuestras variables y ejecutar el código paso a paso:
Otra técnica útil para la depuración de un programa TradingMotion son las trazas de log. El TradingMotionSDKv2 utiliza el el log4net de Apache, que permite al programador hacer trazas de log a consola (por defecto) o un fichero de texto.
El programa de TradingMotion tiene el atributo de log4net.ILog log, que se puede utilizar para hacer las trazas. Por ejemplo, la traza de esta instrucción cuando estamos moviendo la orden Trailing Stop a nuestro favor:
Visual Basic.NET
ModifyOrder(trailingStopOrder) log.Info("Market moving in our favor :) Rising stop price " + (bar.Close - Bars.Close(1)) + "points")
C#
ModifyOrder(trailingStopOrder); log.Info("Market moving in our favor :) Rising stop price " + (bar.Close - Bars.Close[1]) + "points");
La ejecución del backtest producirá esta salida:
Las líneas verdes son el resultado de las trazas de log.info. De esta forma podemos añadir tantas trazas como queramos, que nos permitirán monitorizar el comportamiento de nuestros programas TradingMotion a simple vista.
También podemos ver las trazas de log en el Toolkitv2 en la pestaña de Salida:
Usos avanzados de la clase Strategy
Gestión de órdenes simple y avanzada
Al codificar una estrategia, el desarrollador puede elegir utilizar la gestión de órdenes simple o avanzada. La selección correcta para este ajuste es importante, ya que condicionará la forma de escribir el código. La elección se realiza mediante el valor del atributo de la estrategia UsesAdvancedOrderManagement a verdadero o falso, lo que conducirá a usar órdenes avanzadas o no.
En la gestión de órdenes simples, cuando el sistema está plano (no hay ninguna posición abierta) puede enviar órdenes a mercado usando los métodos Buy()
y Sell()
. Los dos primeros parámetros de cada función (tipo de orden y cantidad) son obligatorios, mientras que los otros dos (precio de ejecución y etiqueta) no. El tipo de orden puede ser Market, Limit o Stop, el tercer parámetro (precio) es obligatorio para los tipos Limit y Stop ya que indica el precio a la que se debe ejecutar la orden.
Los desarrolladores también pueden utilizar los métodos ExitLong()
y ExitShort()
para cerrar sus posiciones. En estos métodos, el único parámetro obligatorio es el tipo de orden. El desarrollador también puede especificar el precio (requerido para órdenes limit/stop) y una etiqueta
El siguiente código de ejemplo muestra, mediante la gestión de órdenes simple, cómo enviar una señal de compra en la barra actual y:
- Colocar un tope de ganancia (Take Profit) cuando el precio aumenta 50 puntos
- Colocar una orden de stop de pérdidas (Stop Loss) cuando el precio cae 10 puntos.
Visual Basic.NET
Public Overrides Sub OnNewBar() Buy(OrderType.Market, 1, 0, "Buying at the current price: " + Bars.Close(0)) ExitLong(OrderType.Limit, Bars.Close(0) + 50, "Take Profit at " + (Bars.Close(0) + 50) + " points") ExitLong(OrderType.Stop, Bars.Close(0) - 10, "Stop Loss at " + (Bars.Close(0) - 10) + " points") End Sub
C#
public override void OnNewBar() { Buy(OrderType.Market, 1, 0, "Buying at the current price: " + Bars.Close[0]); ExitLong(OrderType.Limit, Bars.Close[0] + 50, "Take Profit at " + (Bars.Close[0] + 50) + " points"); ExitLong(OrderType.Stop, Bars.Close[0] - 10, "Stop Loss at " + (Bars.Close[0] - 10) + " points"); }
En la gestión de órdenes simple, las órdenes que no han sido ejecutadas se cancelan automáticamente después del cierre de la barra. Tenga en cuenta establecer las órdenes correctas para cada nueva barra.
Al utilizar la gestión de órdenes avanzada, el desarrollador debe crear un objeto Order, que puede ser una instancia de MarketOrder, StopOrder o LimitOrder. La orden debe ser enviada mediante el método de la estrategia InsertOrder()
. Las órdenes pueden ser vinculadas mediante la propiedad IsChildOf.
La gestión avanzada permite al desarrollador almacenar los objetos Order como atributos dentro de la estrategia, modificándolos cuando sea necesario utilizando el método ModifyOrder()
.
El siguiente código de ejemplo muestra, mediante la gestión de órdenes avanzadas, cómo enviar una señal de compra en la barra actual y colocar un tope de ganancia (Take Profit) cuando el precio aumenta 50 puntos y un stop de pérdidas (Stop Loss) cuando el precio cae 10 puntos. Entonces, si la posición es larga y el precio ha subido (en comparación con la barra anterior), se comprueba la orden de stop enviada previamente.
Visual Basic.NET
Public Overrides Sub OnNewBar() If (GetOpenPosition() = 0) Then InsertOrder(New MarketOrder(OrderSide.Buy, 1, "Golden Cross - Open long position")) trailingStopOrder = New StopOrder(OrderSide.Sell, 1, Bars.Close(0) - 10, "Trailing Stop Level Hit - Close long position") InsertOrder(trailingStopOrder) takeProfitOrder = New LimitOrder(OrderSide.Sell, 1, Bars.Close(0) + 50, "Take Profit Level Hit - Close long position") InsertOrder(takeProfitOrder) takeProfitOrder.IsChildOf = trailingStopOrder trailingStopOrder.IsChildOf = takeProfitOrder Else If (Bars.Close(0) > Bars.Close(1)) Then trailingStopOrder.Price = trailingStopOrder.Price + (Bars.Close(0) - Bars.Close(1)) ModifyOrder(trailingStopOrder) End If End If End Sub
C#
public override void OnNewBar() { if (GetOpenPosition() == 0) { InsertOrder(new MarketOrder(OrderSide.Buy, 1, "Golden Cross - Open long position")); trailingStopOrder = new StopOrder(OrderSide.Sell, 1, Bars.Close[0] - 10, "Trailing Stop Level Hit - Close long position"); InsertOrder(trailingStopOrder); takeProfitOrder = new LimitOrder(OrderSide.Sell, 1, Bars.Close[0] + 50, "Take Profit Level Hit - Close long position"); InsertOrder(takeProfitOrder); takeProfitOrder.IsChildOf = trailingStopOrder; trailingStopOrder.IsChildOf = takeProfitOrder; } else { if (Bars.Close[0] > Bars.Close[1]) { trailingStopOrder.Price = trailingStopOrder.Price + (Bars.Close[0] - Bars.Close[1]); ModifyOrder(trailingStopOrder); } } }
En la gestión de órdenes avanzadas, la duración de la orden es:
- GTC (good till cancelled): para las estrategias continuas (no intradía).
- DAY order: para las estrategias intradía (las órdenes activas se eliminan al final de la sesión)
Gráficos Secundarios
A pesar de que todas las estrategias deben ser ejecutadas sobre un gráfico principal, los desarrolladores pueden programar sus algoritmos usando varios gráficos secundarios. Estos gráficos deben ser diferentes entre sí (símbolo diferente y/o una compresión diferente).
Los gráficos secundarios se pueden usar para decidir si operar o no en una barra, o para comprobar barras de otro producto, añadir indicadores... pero no pueden ser utilizados para operar (las operaciones sólo se permiten en el gráfico principal). Por otra parte, la función de la estrategia OnNewBar()
sólo se llama cada vez que llega una nueva barra al gráfico principal; cuando ocurre esto, todas las barras de los gráficos secundarios ya están disponibles.
El siguiente código muestra un ejemplo de creación de un indicador RSI para el gráfico principal, y luego otro indicador RSI para un gráfico secundario usando el producto EuroFX con una compresión de 15 minutos. Si no se especifica el gráfico secundario en la ejecución del backtest, este será ignorado.
Visual Basic.NET
Public Overrides Sub OnInitialize() rsiMain = New RSIIndicator(Bars.Close) AddIndicator("RSI Main", rsiMain) If (ContainsSecondaryChart("URO", BarPeriodType.Minute, 15)) Then Dim euroFX15min As Chart = GetSecondaryChart("URO", BarPeriodType.Minute, 15) rsiEuroFX = New RSIIndicator(euroFX15min.Bars.Close) euroFX15min.AddIndicator("RSI EuroFX", rsiEuroFX) End If End Sub
C#
public override void OnInitialize() { rsiMain = new RSIIndicator(Bars.Close); AddIndicator("RSI Main", rsiMain); if (ContainsSecondaryChart("URO", BarPeriodType.Minute, 15)) { Chart euroFX15min = GetSecondaryChart("URO", BarPeriodType.Minute, 15); rsiEuroFX = new RSIIndicator(euroFX15min.Bars.Close); euroFX15min.AddIndicator("RSI EuroFX", rsiEuroFX); } }
El siguiente ejemplo de código muestra el uso del indicador RSI EuroFX, en caso de que el gráfico secundario sea creado.
Visual Basic.NET
Public Overrides Sub OnNewBar() If (GetOpenPosition() = 0 And rsiEuroFX IsNot Nothing) Then If (rsiEuroFX.GetRSI()(1) > 70 And rsiEuroFX.GetRSI()(0) <= 70) Then Sell(OrderType.Market, 1) ElseIf (rsiMain.GetRSI()(1) < 30 And rsiMain.GetRSI()(0) >= 30) Then Buy(OrderType.Market, 1) End If End If End Sub
C#
public override void OnNewBar() { if (GetOpenPosition() == 0 && rsiEuroFX != null) { if (rsiEuroFX.GetRSI()[1] > 70 && rsiEuroFX.GetRSI()[0] <= 70) { Sell(OrderType.Market, 1); } else if (rsiMain.GetRSI()[1] < 30 && rsiMain.GetRSI()[0] >= 30) { Buy(OrderType.Market, 1), } } }
Utilizando MarketDataTimeFrame
El horario de mercado es un atributo de la clase Chart. Indica el período de tiempo (hora de inicio y hora de fin) en el que la aplicación está abierta para recibir barras.
Su valor por defecto es de 00:00:00 a 23:59:59, pero puede ser modificado. Esto puede ser útil para calcular indicadores técnicos sólo en un conjunto concreto de barras de una sesión. Los indicadores no se podrán calcular fuera del intervalo de tiempo, dado que no tenemos los datos (barras).
El siguiente ejemplo de código muestra cómo el desarrollador define el horario de mercado de 8:00:00-14:00:00.
Visual Basic.NET
Public Overrides Sub OnInitialize() MarketDataTimeFrame = New TimeFrame(New TimeSpan(8, 0, 0), New TimeSpan(14, 0, 0)) End Sub
C#
public override void OnInitialize() { MarketDataTimeFrame = new TimeFrame(new TimeSpan(8, 0, 0), new TimeSpan(14, 0, 0)); }
Utilizando TradingTimeFrame
El atributo horario de negociación pertenece a la clase Strategy. Indica el período de tiempo donde se permite ejecutar órdenes, actuando como un filtro de seguridad.
Cualquier orden ejecutada en el intervalo de tiempo se realizará como siempre. Sin embargo, una orden ejecutada fuera del intervalo de tiempo producirá una excepción del tipo InvalidOperationException.
El siguiente ejemplo de código muestra cómo el desarrollador define el periodo de tiempo de negociación. Este código podría lanzar una excepción cuando llegara la primera barra con la hora 15:00:00, dado que hemos definido que se sólo se permiten negociaciones en horario de 8:00:00-14:00:00.
Visual Basic.NET
Public Overrides Sub OnInitialize() TradingTimeFrame = New TimeFrame(New TimeSpan(8, 0, 0), New TimeSpan(14, 0, 0)) End Sub Public Overrides Sub OnNewBar() If (GetOpenPosition() = 0) Then If (Bars.Time(0).TimeOfDay >= New TimeSpan(15, 0, 0)) Then Buy(OrderType.Market, 1) End If End If End Sub
C#
public override void OnInitialize() { TradingTimeFrame = new TimeFrame(new TimeSpan(8, 0, 0), new TimeSpan(14, 0, 0)); } public override void OnNewBar() { if (GetOpenPosition() == 0) { if (Bars.Time[0].TimeOfDay >= new TimeSpan(15, 0, 0)) { Buy(OrderType.Market, 1); } } }
Utilizando MaxOpenPosition
El atributo MaxOpenPosition indica la cantidad máxima de los contratos que podemos tener abiertos a la vez. Es un filtro de seguridad que asegura una estrategia nunca excederá su límite máximo de posiciones abiertas.
Si una estrategia intenta abrir más posiciones de las definidas en este atributo, el runner generará un excepción del tipo InvalidOperationException.
El siguiente ejemplo de código muestra cómo usar este atributo (con un valor máximo de 3).
Visual Basic.NET
Public Overrides ReadOnly Property MaxOpenPosition As UInteger Get Return 3 End Get End Property
C#
public override uint MaxOpenPosition { get { return 3; } }
Continuando con el ejemplo, el siguiente código podría lanzar una excepción en la llegada de la cuarta barra (porque ya tendría 3 posiciones abiertas, y no estamos controlando la posición abierta en ese momento).
Visual Basic.NET
Public Overrides Sub OnNewBar() Buy(OrderType.Market, 1) End Sub
C#
public override void OnNewBar() { Buy(OrderType.Market, 1); }
El siguiente ejemplo de código también produciría una excepción, ya que trata de abrir 5 posiciones en la misma operación, cuando el máximo permitido es de 3.
Visual Basic.NET
Public Overrides Sub OnNewBar() Buy(OrderType.Market, 5) End Sub
C#
public override void OnNewBar() { Buy(OrderType.Market, 5); }
Utilizando ForceClosingIntradayPosition y IntradayClosingBar
Los atributos ForceClosingIntradayPosition y IntradayClosingBar ambos pertenecen a la clase Strategy.
El primer atributo indica si la estrategia es intradía: esto indica si puede haber posiciones abiertas al final del día o no.
El segundo atributo sólo se utiliza cuando la estrategia es intradía e indica el número de barras que se consideran al final del día para cerrar posición. Su valor por defecto es 0. Por ejemplo, si queremos que nuestra estrategia tenga en cuenta al final del día la última barra, establecería ForceClosingIntradayPosition true y IntradayClosingBar a 1. De esta forma se cerrarán todas las posiciones abiertas cuando llegue la última barra del dia. Después de esta barra, la estrategia no recibirá ningún evento OnNewBar()
hasta el próximo período de sesiones.
Opciones de visualización de indicadores
Los indicadores tienen dos atributos que gestionan sus opciones de visualización cuando se muestran en el gráfico OHLC. Estos atributos son ShownInChart y ShownOverInputSeries, y pueden ser modificados por el desarrollador.
ShownInChart indica si el indicador se dibuja en el gráfico OHLC. Su valor por defecto es true. Si su valor es false no se dibujará, aunque se calcula y se puede acceder a sus series de salida.
ShownOverInputSeries es true cuando el indicador debe ser calculado en la misma área gráfica de su serie de entrada (por ejemplo, si un indicador toma como serie de entrada los precios de cierre este atributo se establece en true, el indicador se dibujará en el OHLC). Su valor por defecto es false.
En la siguiente imagen se muestran dos indicadores: el RSI con los precios de cierre como serie de entrada y que se dibuja en un área separada (ShowOverInputSeries = false); y un SMA que utiliza la salida del indicador RSI como serie de entrada, con los atributos ShownOverInputSeries establecidas en true.
El código utilizado para este ejemplo es el siguiente:
Visual Basic.NET
Public Overrides Sub OnInitialize() Dim rsi As RSIIndicator = New RSIIndicator(Bars.Close, 12) rsi.ShownInChart = True rsi.ShownOverInputSeries = False Dim sma As SMAIndicator = New SMAIndicator(rsi.GetRSI(), 4) sma.ShownInChart = True sma.ShownOverInputSeries = True AddIndicator("RSI Indicator", rsi) AddIndicator("SMA Indicator", sma) End Sub
C#
public override void OnInitialize() { RSIIndicator rsi = new RSIIndicator(Bars.Close, 13); rsi.ShownInChart = true; rsi.ShownOverInputSeries = false; SMAIndicator sma = new SMAIndicator(rsi.GetRSI(), 4); sma.ShownInChart = true; sma.ShownOverInputSeries = true; AddIndicator("RSI Indicator", rsi); AddIndicator("SMA Indicator", sma); }
Ejecución en tiempo real
Data Feed
Para realizar el backtesting y la ejecución en tiempo real, la plataforma SDK utiliza barras de datos intradía continuos, sin ajustar.
En tiempo real la plataforma SDK utiliza el modo de mercado tick-data para el rastreo de ejecuciones de órdenes limit/stop activas. El tick-data es de uso interno, y no está disponible para los desarrolladores.
Rollovers
- Índices Futuros Europeos: Cambiar a nueva fecha de expiración al principio de la fecha de expiración (si expira el 21 de Marzo, el gráfico del día 20 mostrará Marzo y el 21 mostrará la nueva expiración, Abril o Junio).
- Índices Futuros USA: Cambiar a nueva fecha de expiración al principio del jueves de la semana anterior a la expiración (si expira el viernes 21 de Marzo, el contrato contínuo mostrará Marzo hasta el día 12, y Junio a partir del 13 de Marzo).
- Futuros de Divisas: Cambiar a nueva fecha de expiración al principio del jueves de la semana anterior a la expiración (si expira el lunes 17 de de Marzo, el contrato contínuo mostrará Marzo hasta el día 12, y Junio a partir del 13 de Marzo).
- Futuros de Energía: Cambiar a nueva fecha de expiración al principio del último día de trading.
Precio de ejecución de las órdenes
Para las órdenes de mercado se utiliza el precio de apertura de la siguiente barra, con la excepción del cierre automático de cualquier posición abierta para las estrategias intradía. En este caso, cerramos la posición con Bars.Close[0] en el modo de backtest, mientras que en ejecución real, se cierra automáticamente cualquier posición abierta un par de minutos antes del final de la sesión.
Para las órdenes limit/stop siempre usamos los precios de ejecución hipotéticos, y medimos el deslizamiento (slippage) de todas las operaciones de los clientes.
Anexo I - Indicadores técnicos
Overlap Studies
Namespace: TradingMotion.SDK.Markets.Indicators.OverlapStudies
Name | Class Name | Info link |
---|---|---|
Bollinger Bands | BBandsIndicator | + info |
Double Exponential Moving Average | DEMAIndicator | + info |
Exponential Moving Average | EMAIndicator | + info |
Hilbert Transform - Instantaneous Trendline | HTTrendlineIndicator | + info |
Kaufman Adaptive Moving Average | KAMAIndicator | + info |
Moving Average | MovingAverageIndicator | + info |
MESA Adaptive Moving Average | MAMAIndicator | + info |
Moving average with variable period | MovingAverageVariablePeriodIndicator | + info |
MidPoint over period | MidPointIndicator | + info |
MidPoint price over period | MidPriceIndicator | + info |
Parabolic SAR | SARIndicator | + info |
Parabolic SAR - Extended | SARExtIndicator | + info |
Simple Moving Average | SMAIndicator | + info |
Triple Exponential Moving Average | T3Indicator | + info |
Triangular Moving Average | TriMAIndicator | + info |
Weighted Moving Average | WMAIndicator | + info |
Volatility Indicators
Namespace: TradingMotion.SDK.Markets.Indicators.Volatility
Name | Class Name | Info link |
---|---|---|
Average True Range | ATRIndicator | + info |
Normalized Average True Range | NATRIndicator | + info |
True Range | TrueRangeIndicator | + info |
Momentum Indicators
Namespace: TradingMotion.SDK.Markets.Indicators.Momentum
Name | Class Name | Info link |
---|---|---|
Average Directional Movement Index | ADXIndicator | + info |
Average Directional Movement Index Rating | ADXRIndicator | + info |
Absolute Price Oscillator | APOIndicator | + info |
Aroon | AroonIndicator | + info |
Aroon Oscillator | AroonOscIndicator | + info |
Balance of Power | BOPIndicator | + info |
Commodity Channel Index | CCIIndicator | + info |
Moving Average Convergence/Divergence | MACDIndicator | + info |
MACD with controllable MA type | MACDExtIndicator | + info |
MACD Fix 12/26 | MACDFixIndicator | + info |
Money Flow Index | MFIIndicator | + info |
Minus Directional Indicator | MinusDIIndicator | + info |
Minus Directional Movement | MinusDMIIndicator | + info |
Momentum | MomentumIndicator | + info |
Plus Directional Indicator | PlusDIIndicator | + info |
Plus Directional Movement | PlusDMIIndicator | + info |
Percentage Price Oscillator | PPOIndicator | + info |
Rate of change: ((price/prevPrice)-1)*100 | ROCIndicator | + info |
Rate of change percentage: (price-prevPrice)/prevPrice | ROCPIndicator | + info |
Rate of change ratio: price/prevPrice | ROCRIndicator | + info |
Rate of change ratio 100 scale: (price/prevPrice)*100 | ROCR100Indicator | + info |
Relative Strength Index | RSIIndicator | + info |
Stochastic | StochasticIndicator | + info |
Stochastic Fast | StochasticFastIndicator | + info |
Stochastic Relative Strength Index | StochasticRSIIndicator | + info |
1-day Rate-of-Change (ROC of a Triple Smooth EMA | TRIXIndicator |
+ info + info |
Ultimate Oscillator | UltOscIndicator | + info |
Williams' %R | WilliamsRIndicator | + info |
Cycle Indicators
Namespace: TradingMotion.SDK.Markets.Indicators.Cycle
Name | Class Name | Info link |
---|---|---|
Hilbert Transform - Dominant Cycle Period | HTDCPeriodIndicator | + info |
Hilbert Transform - Dominant Cycle Phase | HTDCPhaseIndicator | + info |
Hilbert Transform - SineWave | HTSineIndicator | + info |
Hilbert Transform - Trend vs. Cycle Mode | HTTrendModeIndicator | - |
Volume Indicators
Namespace: TradingMotion.SDK.Markets.Indicators.Volume
Name | Class Name | Info link |
---|---|---|
Chaikin A/D Line | ChaikinADLineIndicator | + info |
Chaikin A/D Oscillator | ChaikinADOscIndicator | + info |
On Balance Volume | OBVIndicator | + info |
Pattern Recognition
Namespace: TradingMotion.SDK.Markets.Indicators.Patterns
Name | Class Name | Info link |
---|---|---|
Abandoned Baby | AbandonedBabyIndicator | + info |
Advance Block | AdvanceBlockIndicator | + info |
Belt-Hold | BeltHoldIndicator | + info |
Breakaway | BreakawayIndicator | + info |
Closing Marubozu | ClosingMarubozuIndicator | + info |
Concealing Baby Swallow | ConcealingBabySwallowIndicator | + info |
Counterattack | CounterAttackIndicator | + info |
Dark Cloud Cover | DarkCloudCoverIndicator | + info |
Doji | DojiIndicator | + info |
Doji Star | DojiStarIndicator | + info |
Dragonfly Doji | DragonflyDojiIndicator | + info |
Engulfing Pattern | EngulfingPatternIndicator | + info |
Evening Doji Star | EveningDojiStarIndicator | + info |
Evening Star | EveningStarIndicator | + info |
Up/Down-gap side-by-side withe lines | GapSideBySideWhiteIndicator |
+ info + info |
Gravestone Doji | GravestoneDojiIndicator | + info |
Hammer | HammerIndicator | + info |
Hanging Man | HangingManIndicator | + info |
Harami Pattern | HaramiPatternIndicator | + info |
Harami Cross Pattern | HaramiCrossPatternIndicator | + info |
High-Wave Candle | HighWaveCandleIndicator | + info |
Hikkake Pattern | HikkakePatternIndicator | + info |
Modified Hikkake Pattern | ModifiedHikkakePatternIndicator | + info |
Homing Pigeon | HomingPigeonIndicator | + info |
Identical Three Crows | IdenticalThreeCrowsIndicator | + info |
In-Neck Pattern | InNeckPatternIndicator | + info |
Inverted Hammer | InvertedHammerIndicator | + info |
Kicking | KickingIndicator | + info |
Kicking - bull/bear determined by the longer marubozu | KickingByLengthIndicator | + info |
Ladder Bottom | LadderBottomIndicator | + info |
Long Legged Doji | LongLeggedDojiIndicator | + info |
Long Line Candle | LongLineCandleIndicator | + info |
Marubozu | MarubozuIndicator | + info |
Matching Low | MatchingLowIndicator | + info |
Mat Hold | MatHoldIndicator | + info |
Morning Doji Star | MorningDojiStarIndicator | + info |
Morning Star | MorningStarIndicator | + info |
On-Neck Pattern | OnNeckPatternIndicator | + info |
Piercing Pattern | PiercingPatternIndicator | + info |
Rickshaw Man | RickshawManIndicator | + info |
Rising/Falling Three Methods | RiseFallThreeMethodsIndicator | + info |
Separating Lines | SeparatingLinesIndicator |
+ info + info |
Shooting Star | ShootingStarIndicator | + info |
Short Line Candle | ShortLineCandleIndicator | + info |
Spinning Top | SpinningTopIndicator | + info |
Stalled Pattern | StalledPatternIndicator | + info |
Stick Sandwich | StickSandwichIndicator | + info |
Takuri (Dragonfly Doji with very long lower shadow) | TakuriIndicator | + info |
Tasuki Gap | TasukiGapIndicator |
+ info + info |
Two Crows | TwoCrowsIndicator | + info |
Three Black Crows | ThreeBlackCrowsIndicator | + info |
Three Inside Up/Down | ThreeInsideUpDownIndicator | + info |
Three-Line Strike | ThreeLineStrikeIndicator | + info |
Three Outside Up/Down | ThreeOutsideUpDownIndicator | + info |
Three Stars In The South | ThreeStarsInTheSouthIndicator | + info |
Three Advancing White Soldiers | ThreeAdvancingWhiteSoldiersIndicator | + info |
Thrusting Pattern | ThrustingPatternIndicator | + info |
Tristar Pattern | TriStarPatternIndicator | + info |
Unique 3 River | UniqueThreeRiverIndicator | + info |
Upside Gap Two Crows | UpsideGapTwoCrowsIndicator | + info |
Upside/Downside Gap Three Methods | UpDownGapThreeMethodsIndicator | + info |
Statistic Functions
Namespace: TradingMotion.SDK.Markets.Indicators.StatisticFunctions
Name | Class Name | Info link |
---|---|---|
Linear Regression | LinearRegressionIndicator | + info |
Linear Regression Angle | LinearRegressionAngleIndicator | + info |
Linear Regression Intercept | LinearRegressionInterceptIndicator | + info |
Linear Regression Slope | LinearRegressionSlopeIndicator | + info |
Standard Deviation | StdDevIndicator | + info |
Time Series Forecast | TimeSeriesForecastIndicator | + info |
Variance | VarianceIndicator | + info |
Price Transform
Namespace: TradingMotion.SDK.Markets.Indicators.PriceTransform
Name | Class Name | Info link |
---|---|---|
Average Price | AveragePriceIndicator | + info |
Median Price | MedianPriceIndicator | + info |
Typical Price | TypicalPriceIndicator | + info |
Weighted Close Price | WCLPriceIndicator | + info |
Anexo II - Productos Disponibles
Product ID | Name | Market | Currency | Point Value | Tick Size |
---|---|---|---|---|---|
NQ | E-mini Nasdaq | CME | USD | 20 | 0,25 |
ES | E-mini S&P | CME | USD | 50 | 0,25 |
YM | E-mini DowJones | CME | USD | 5 | 1 |
FDAX | DAX | EUREX | EUR | 25 | 1 |
GC | Gold | CME-COMEX | USD | 100 | 0,1 |
RTY | Mini-Russell CME | CME | USD | 50 | 0,1 |
FDXM | Mini-Dax | EUREX | EUR | 5 | 1 |
CL | Crude Oil | CME-NYMEX | USD | 1000 | 0,01 |
DM | S&P MidCap | CME | USD | 100 | 0,1 |
URO | EuroFX | CME | USD | 125000 | 0,00005 |
RB | RBOB Gasoline | CME-NYMEX | USD | 42000 | 0,0001 |
SI | Silver | CME-COMEX | USD | 5000 | 0,005 |
IFS | FTSE MIB | IDEM | EUR | 5 | 5 |
IX | IBEX | MEFF | EUR | 10 | 1 |
FGBL | BUND | EUREX | EUR | 1000 | 0,01 |
QM | E-mini Crude Oil | CME-NYMEX | USD | 500 | 0,025 |
HO | Heating Oil | CME-NYMEX | USD | 42000 | 0,0001 |
HG | Copper | CME-COMEX | USD | 25000 | 0,0005 |
FESX | EuroStoxx | EUREX | EUR | 10 | 1 |
ZB | 30y T-Bond | CME-CBOT | USD | 1000 | 0,03125 |
NG | Natural Gas | CME-NYMEX | USD | 10000 | 0,001 |
PL | Platinum | CME-COMEX | USD | 50 | 0,1 |
NKD | Nikkei USD | CME | USD | 5 | 5 |
FCE | CAC | EURONEXT | EUR | 10 | 0,5 |
ZS | Soybeans | CME-CBOT | USD | 50 | 0,25 |
ZW | Wheat | CME-CBOT | USD | 50 | 0,25 |
AEX | AEX | EURONEXT | EUR | 200 | 0,05 |
HE | Lean Hogs | CME-CBOT | USD | 400 | 0,025 |
MN | Mini-Ibex | MEFF | EUR | 1 | 5 |
BP | British Pound | CME | USD | 62500 | 0,0001 |
LE | Live Cattle | CME-CBOT | USD | 400 | 0,025 |
ZC | Corn | CME-CBOT | USD | 50 | 0,25 |
SF | Swiss Franc | CME | USD | 125000 | 0,0001 |
IFM | Mini FTSE MIB | IDEM | EUR | 1 | 5 |
ZN | 10y T-Note | CME-CBOT | USD | 1000 | 0,015625 |
SB11 | ICE Sugar #11 | ICE-US | USD | 1120 | 0,01 |
Damos soporte de todos los productos futuros de CME Group®, ICE®, EUREX® and EURONEXT® exchanges.
Contacte con nosotros en sdk@tradingmotion.com para obtener más información sobre otros productos.