TRABAJO FIN DE GRADO ESCUELA UNIVERSITARIA POLITECNICA Departamento de Ciencias Politécnicas Grado en Ingeniería Informática Desarrollo de un software de predicción financiera Autor: D. José Carlos Cano Lorente Directores: Dr. D. José María Cecilia Canales Dr. D. Horacio Pérez Sánchez Murcia, Junio de 2015
236
Embed
Defensa tfg prediccion y optimizacion en sistemas de trading automaticos para mercados financieros
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
TRABAJO FIN DE GRADO
ESCUELA UNIVERSITARIA POLITECNICA
Departamento de Ciencias Politécnicas
Grado en Ingeniería Informática
Desarrollo de un software de predicción financiera
Autor:
D. José Carlos Cano Lorente
Directores:
Dr. D. José María Cecilia Canales
Dr. D. Horacio Pérez Sánchez
Murcia, Junio de 2015
TRABAJO FIN DE GRADO
ESCUELA UNIVERSITARIA POLITECNICA
Departamento de Ciencias Politécnicas
Grado en Ingeniería Informática
Desarrollo de un software de predicción financiera
Autor:
D. José Carlos Cano Lorente
Directores:
Dr. D. José María Cecilia Canales
Dr. D. Horacio Pérez Sánchez
Murcia, Junio de 2015
Autorización
Dr. D. José María Cecilia Canales y Dr. D. Horacio Pérez Sánchez,
profesores de la UCAM
CERTIFICAN: que el Trabajo Fin de Grado titulado “Desarrollo de un
software de predicción financiera” que presenta D. José Carlos Cano Lorente,
para optar al título oficial de Grado en Ingeniería Informática, ha sido realizado
bajo su dirección.
A su juicio reúne las condiciones necesarias para ser presentado en la
Universidad Católica San Antonio de Murcia y ser juzgado por el tribunal
correspondiente.
Murcia, a de Junio de 2015
Agradecimientos
A mis directores de proyecto, José María Cecilia y Horacio Pérez, que
desde nuestra primera reunión para tratar el desarrollo de este TFG, mostraron
una gran confianza en lo que podríamos conseguir, y supieron transmitirme esa
ilusión. Sus enseñanzas e indicaciones han sido fundamentales para enfocar la
metodología y no perder de vista nunca los objetivos que perseguíamos.
A la empresa Artificial Intelligence Talentum, S.L., por haber colaborado
con la UCAM en definir este proyecto, y por darme la oportunidad de contribuir
humildemente en una parte del ambicioso proyecto del desarrollo de
herramientas de trading. Sus ánimos, desde nuestra primera entrevista, han
sido muy gratificantes.
A la Universidad Católica San Antonio de Murcia, por ofrecerme la
posibilidad de actualizar mi formación. Su plan de estudios on-line es de gran
calidad, y permite compaginar la vida profesional, familiar y académica de
muchas personas como yo.
Y a mi esposa y mis tres hijas, que me han acompañado con resignación
durante los dos últimos años en mis dedicación al estudio de las asignaturas y
a la elaboración de este TFG.
Índice de contenidos
Índice de contenidos ............................................................................................. 11
Como hemos indicado en el capítulo “5.3 Metodología elegida”, en este
proyecto no conocemos de antemano los detalles exactos del producto final,
por lo que hemos apostado por emplear la metodología SCRUM, que nos
permita tener el cliente vinculado al proyecto, entregándole regularmente
versiones del producto para que pueda ver a corto plazo el fruto de su inversión
y afine sus requerimientos, haciéndole partícipe del desarrollo y creando una
relación de confianza con el equipo.
Según Roman Pichler [2], una planificación conlleva una decisión
acerca de qué factores no deberían verse comprometidos de cara al
lanzamiento de un producto de éxito, lo cual nos lleva a hacernos una serie de
preguntas:
Tiempo: ¿es necesario respetar una fecha de lanzamiento o
finalización?
Coste: ¿hay un presupuesto fijo para el desarrollo del producto?
Funcionalidad: ¿deben desarrollarse todos los requerimientos que
figuran en la Pila de Producto?
Las tres restricciones no pueden satisfacerse de manera conjunta (al
menos una de ellas debe quedar libre como válvula de escape).
Fijar la funcionalidad no es una buena idea y, además, va en contra de
los principios de la metodología Ágil, donde esperamos evolucionar el producto
en base a las indicaciones del cliente.
Sin embargo, fijar la fecha de entrega de las diferentes versiones lleva a
una disciplina en el equipo de desarrollo, una mentalidad de producir resultados
periódicamente. Además, de esta manera, si el equipo de desarrollo es estable,
la elaboración del presupuesto es sencilla pues se reduce al cálculo: Nº de
desarrolladores x tiempo.
Flexibilizando el requisito de la funcionalidad permitimos que, en caso de
que el presupuesto se vea comprometido, el Propietario del Producto pueda
aceptar liberar un producto tras una reducción en las prestaciones.
5.1 Método de estimación utilizado
En SCRUM las tareas se estiman en Puntos Historia o Story Points (SP
a partir de ahora), que son una medida “relativa” del esfuerzo que es necesario
aplicar para desarrollar una Historia de Usuario. Cuando decimos “relativa”
58
estamos reflejando que una tarea etiquetada como 2SP conlleva el doble de
esfuerzo que otra etiquetada como 1SP.
Según Garzás [21], “un punto historia es una fusión entre la cantidad de
esfuerzo que supone desarrollar la historia de usuario, la complejidad de su
desarrollo y el riesgo inherente”. Al ser una medida relativa permite adaptarse
al equipo y nos deja libertad a la hora de asignar valores. Dado que debemos
usar rangos acotados, fijando un tope máximo, nos decantamos por la
siguiente serie: 1, 2, 3 ,5, 8, 13.
A la hora de calcular la duración del proyecto, sólo los Puntos Historia no
son suficientes, sino que necesitamos saber con qué rapidez el equipo es
capaz de desarrollar las Historias de Usuario. A este concepto se la denomina
Velocidad, que se calcula sumando el número de Puntos Historia de cada
Historia de Usuario “terminada” durante un Sprint. Dado que el Dueño del
Producto no consigue valor de las Historias de Usuario no acabadas, se
excluyen del cálculo todas aquéllas parcialmente desarrolladas.
Según Kenneth S. Rubin [3], “la velocidad mide el output (el tamaño de
lo que se entrega), no el outcome (el valor de lo que se entrega)”. Es decir,
completar una Historia de Usuario de 8SP no significa necesariamente que
aporte más valor al cliente que una de 5SP. Quizás interese trabajar más en la
de 5SP porque aporta más valor y es menos costosa.
La velocidad se suele mantener durante todo el proyecto, ya que es
inherente a la naturaleza de nuestro equipo y es conocida por proyectos
anteriores, o por sprints anteriores dentro del mismo proyecto. En nuestro caso,
esta información no está disponible y debemos realizar una estimación
adoptando alguna asunciones:
Nuestro equipo de desarrollo está compuesto por una persona
La jornada de trabajo dedicada al proyecto es 3 Horas/Día
El factor de disponibilidad será del 80% de esas 3 horas, donde el
20% restante lo dejamos como colchón para mejoras técnicas
que no aportan aparentemente valor al cliente, o bien para
imprevistos
Consideramos como punto de partida en nuestros cálculos que,
basándonos en nuestra experiencia, una Historia de Usuario de
1SP necesita una media de 3 horas para su desarrollo y prueba
59
Garzás [21] recomienda no considerar más de ese 80% de
disponibilidad.
Teniendo en cuenta que el Equipo de Desarrollo se compone de una
sola persona, con una dedicación de 3 horas al día durante 6 días a la semana,
durante 4 semanas, el número de horas de desarrollo es de 3 * 6 * 4 = 72 que,
aplicando un factor de disponibilidad del 80% nos deja el valor real de 58 horas
en cada iteración.
Por tanto la velocidad estimada será de 58 horas / 3 Horas por SP = 19
SP en cada Sprint.
5.2 Planificación
Sabemos que SCRUM trabaja en iteraciones o ciclos de, como máximo,
un mes de duración, llamados sprints, que presentan como características más
relevantes:
Tienen una fecha de inicio y de fin
Deben ser de corta duración (entre una semana y un mes)
Preferiblemente todos los Sprints deben tener la misma duración
El objetivo a cubrir durante cada ciclo no puede ser alterado y
debe ser completado al llegar el fin del Sprint
Según Kenneth S. Rubin [3], las ventajas de tener en mente una fecha
de fin son que:
Permite limitar el trabajo en curso (no terminado) porque el equipo
planificará sólo aquello que sabe que puede entregar en el Sprint
Fuerza la priorización y el llevar a cabo pequeños trabajos,
focalizándose en lo que aporta valor rápidamente al cliente
Muestra avances entregando nuevas versiones al fin de cada
ciclo
Evita perfeccionismos innecesarios, evitando perder tiempo
buscando algo “perfecto” cuando “suficientemente bueno” podría
valer
Motiva la conclusión de las tareas ya que los equipos tienen en
mente una fecha límite conocida
60
Mejora las predicciones sobre lo que se puede entregar porque es
razonable pensar que será parecido a lo entregado en el sprint
anterior
Por otro lado, una duración corta:
Facilita la planificación
Ofrece retroalimentación frecuente sobre el trabajo ya realizado y
en curso
Mejora el retorno de la inversión en el desarrollo al tener, al final
de cada sprint, una release
Limita la propagación de los posibles errores
Mantiene al equipo activo (en oposición a los proyecto de larga
duración, donde se pierde entusiasmo por el esfuerzo empleado)
Siguiendo esta indicaciones, nosotros nos decantamos por sprints de
cuatro semanas, que se alinean muy bien con la disponibilidad tanto del
Propietario del Producto, del SCRUM Master y del equipo de desarrollo.
En nuestra reunión inicial con el cliente queremos proponerle y acordar
una estimación de tiempos, en este caso, el número de sprints y, para ello,
basándonos en el documento de requerimientos proporcionados por la
empresa, se han podido identificar las siguientes Historias de Usuario:
STO001: Como cliente quiero poder leer un archivo con datos
históricos en formato csv para calcular sobre ellos indicadores
técnicos
STO002: Como cliente quiero que el software detecte el intervalo
de tiempos del archivo de datos para poder generar gráficos
intradía / interdía
STO003: Como cliente quiero que el software pueda manejar
grandes cantidades de datos para poder leer series históricas
STO004: Como cliente quiero poder leer uno o más archivos de
configuración para poder lanzar ejecuciones desatendidas
STO005: Como cliente quiero disponer de una lista de
indicadores técnicos disponibles, que sea ampliable para poder
utilizarla a la hora de declarar los escenarios
61
STO006: Como cliente quiero poder indicar rangos o listas de
parámetros de los indicadores para poder lanzar simulaciones
masivas
STO007: Como cliente quiero poder incluir constantes en los
ficheros de configuración de los escenarios para simplificar la
lectura de los mismos
STO008: Como cliente quiero poder escribir fórmulas o reglas en
formato matemático para que el software pueda interpretarlas
para dar versatilidad
STO009: Como cliente quiero poder indicar las fórmulas de
decisión en los archivos de configuración para poder generar
diferentes escenarios
STO010: Como cliente quiero poder generar un gráfico con
información diaria a partir de un archivo CSV (desde script) para
disponer de una herramienta visual de análisis
STO011: Como cliente quiero que los gráficos se puedan generar
dinámicamente en función a parámetros (estudiar solución
técnica) para decidir si se usan ficheros de configuración de
gráficos
STO012: Como cliente quiero que cada gráfico que se genere
lleve asociado un fichero csv con la información representada
para poder ser tratada con otras herramientas analíticas
STO013: Como cliente quiero que los gráficos puedan contener
varias ventanas, y se puedan asociar variables a cada ventana,
con tipos y colores parametrizables y que se pueda definir el
tamaño de la imagen resultante para ofrecer de esta manera
mayor versatilidad
STO014: Como cliente quiero indicar al software que me genere
gráficos siempre, nunca o en los n casos más favorables para no
sobrecargar en el caso de ejecución de escenarios masivos
STO015: Como cliente quiero poder mostrar en el gráfico las
operaciones de entrada/salida del mercado para permitir un
análisis visual
STO016: Como cliente quiero guardar en una matriz el resultado
de la ejecución de todos los escenarios para poder realizar
estudios posteriores
62
STO017: Como cliente quiero que el software ordene los
escenarios según uno o más ratios calculados tras su ejecución
para conocer las reglas de mercado más ventajosas
STO018: Como cliente quiero que, además de decidir entradas /
salidas del mercado en base a unas fórmulas, también contemple
Stop Loss y Take Profit para asimilarlo a las operaciones reales
del mercado
STO019: Como cliente quiero disponer de un LOG en un archivo
de texto indicando tiempos de ejecución para conocer el
rendimiento de la librería de indicadores técnicos usada y del
software en general
Ahora bien, ¿cómo calculamos el tamaño de cada historia en esta fase
inicial para poder presentar a la empresa un plan de proyecto? En realidad sólo
podemos hacerlo basarnos en estimaciones, seleccionando de la lista de
Historias de Usuario aquéllas con las que nos sintamos más confiados a la
hora de valorar su duración en Puntos de Historia y, haciendo uso de la
naturaleza relativa de este indicador, ponderando a continuación el resto.
Así, basándonos en nuestra experiencia como desarrolladores, sabemos
que STO001 (lectura de un fichero con cierto formato) no es una tarea
compleja y podríamos asignarle una duración de 1SP. Asimismo la ST008, que
supone el desarrollo de un analizador sintáctico (o parser), sin duda es una
tarea más compleja que la anterior, tanto en el desarrollo como en la fase de
pruebas, y creemos que debemos asignarle una duración de 5SP.
Mostramos a continuación una tabla donde hemos reflejado todas las
Historias de Usuario identificadas hasta la fecha y una estimación de
duración/complejidad en Puntos Historia tomando como referencia las
anteriores.
La columna nombrada como “Justificación” explica el razonamiento
seguido para asignar los Puntos de Historia a cada caso:
63
Tabla 4 Historias de usuario identificadas al inicio del proyecto
Historias de
Usuario
(STO)
Puntos de
Historia
(SP)
Justificación
STO001Como cliente quiero poder leer un archivo con datos históricos en
formato csv para calcular sobre ellos indicadores técnicos1 Tomada como base para el resto de estimaciones
STO002Como cliente quiero que el software detecte el intervalo de tiempos
del archivo de datos para poder generar gráficos intradía/interdía1
Serán cá lculos sobre el campo de fecha extra ído del
archivo de entrada
STO003Como cliente quiero que el software pueda manejar grandes
cantidades de datos para poder leer series históricas8
Esta tarea supone el diseño de la arquitectura y
gestión de la memoria que a lmacenará los datos
STO004Como cliente quiero poder leer uno o más archivos de configuración
para poder lanzar ejecuciones desatendidas13
En esta fase inicia l debemos decidi r s i desarrol lar
código para leer archivos con s intaxis a defini r o
buscar soluciones en el mercado
STO005Como cliente quiero disponer de una lista de indicadores técnicos
disponibles, que sea ampliable para poder utilizarla al declarar los 1 Usaremos un nuevo fichero de configuración
STO006Como cliente quiero poder indicar rangos o listas de parámetros de
los indicadores para poder lanzar simulaciones masivas5
El uso de rango y/o bucles aparentemente nos va a
l levar a elaborar a lgún proceso de l lamada recurs iva
STO007Como cliente quiero poder incluir constantes en los ficheros de
configuración de los escenarios para simplificar la lectura de los 1 Duración parecida a la STO005
STO008Como cliente quiero poder escribir fórmulas o reglas en formato
matemático y que el software pueda interpretarlas para dar
versatilidad
5Tomada como base para el resto de estimaciones .
Compleja .
STO009Como cliente quiero poder indicar las fórmulas de decisión en los
archivos de configuración para poder generar diferentes escenarios1 Duración estimada parecida a la STO005
STO010Como cliente quiero poder generar un gráfico con información diaria a
partir de un archivo csv (desde script)8
En esta fase inicia l sabemos la herramienta que
uti l i zaremos pero no tenemos el conocimiento sobre
su uso y debemos tener en cuenta el trabajo de
investigación
STO011Como cliente quiero que los gráficos se puedan generar
dinámicamente en función a parámetros (estudiar solución técnica)
para decidir si se usan ficheros de configuración de gráficos13
Supone la lectura del archivo de configuración, su
interpretación y la generación de sentencias que
generen el gráfico
STO012Como cliente quiero que cada gráfico que se genere lleve asociado un
fichero csv con la información representada para tratamientos en
otras herramientas
1 Simi lar en duración a la STO001
STO013
Como cliente quiero que los gráficos puedan contener varias ventanas,
y se puedan asociar variables a cada ventana, con tipos y colores
parametrizables y que se pueda definir el tamaño en pixels para
ofrecer mayor versatilidad
8 Simi lar en duración a la STO011
STO014Como cliente quiero indicar al software que me genere gráficos
siempre, nunca o en los n casos más favorables para no sobrecargar en
el caso de escenarios masivos5
Habrá que generar un módulo específico para gráficos .
La complejidad vendrá dada por la neces idad de
a lmacenar todos los parámetros usados en cada
escenario para reuti l i zarlos a la hora de graficar los
mejores
STO015Como cliente quiero poder mostrar en el gráfico las operaciones de
entrada/salida del mercado para permitir un análisis visual3 Simi lar a la STO013
STO016Como cliente quiero guardar en una matriz el resultado de la ejecución
de todos los escenarios para poder realizar estudios posteriores5
Almacenar los va lores no es en s í complejo pero s í el
trabajo posterior sobre el los
STO017Como cliente quiero que el software ordene los escenarios según uno
o más ratios calculados tras la ejecución para conocer las reglas más
ventajosas
5 Trabajo sobre cá lculos de ratios
STO018Como cliente quiero que, además de decidir entradas / salidas del
mercado en base a unas fórmulas, también contemple StopLoss y
TakeProfit para asimilarlo a las operaciones reales13
A tener en cuenta junto a las reglas de entrada / sa l ida
del mercado que se guiarán en base a las fórmulas
a lmacenadas en los archivos de los scripts
STO019Como cliente quiero disponer de un LOG de ejecución indicando
tiempos para conocer el rendimiento de la librería de indicadores
técnicos usada5
Desde cualquier punto del programa puede ser
necesario enviar mensajes a l fichero LOG
(especia lmente en caso de errores)
La suma de todos los SP arroja un total de 102 Puntos de Historia para
el desarrollo completo del proyecto que, convertido a horas por el factor
convenido en el apartado 7.1 de 1SP = 3 horas, nos da un valor de 306 horas
de trabajo del equipo de desarrollo.
Por tanto, ya estamos en disposición de estimar la duración del proyecto
en número de Sprints pues conocemos los Puntos de Historia totales y la
velocidad del equipo calculada al final del apartado 5.1:
64
102 SP / 19SP por Sprint = 5,4 ciclos, por lo que decidimos informar al
cliente de que vamos a trabajar durante 6 Sprints, con un margen de error
equivalente a 0,6 ciclos para imprevistos o nuevas Historias de Usuario que
pudieran ir surgiendo a lo largo del proyecto en la reuniones de revisión y
planificación de los sprints.
En la naturaleza de SCRUM está el hecho de revisar, al final de cada
Sprint, las desviaciones de la velocidad estimada frente a la real. Para ello
utilizaremos el gráfico del Sprint Burndown, que nos mostrará las tareas
estimadas durante el sprint y las desviaciones. La velocidad real en cada Sprint
se tomará como nueva velocidad del equipo para los siguientes Sprints y será
un factor decisivo a la hora de seleccionar Historias de Usuario para cada
nuevo Sprint cuando confeccionemos el Sprint Backlog.
5.3 Valoración de la dedicación y coste económico
En nuestro cálculos del coste económico del proyecto vamos a
considerar dos grupos:
Costes de material, donde reflejaremos el coste del material
empleado durante la realización del proyecto
Costes de consultoría, donde reflejaremos el coste de personal
basado en horas de trabajo
5.3.1 Costes de material
Incluiremos todos los costes de hardware y software empleados, que
son independientes de la duración del proyecto. Estos costes no se aplicarán al
cliente dado que esta misma infraestructura es utilizada para proyectos con
otros clientes.
La siguiente tabla identifica los distintos elementos considerados:
65
Tabla 5 Costes de material no facturables
Hardware Euros
Ordenador portátil Lenovo T420 800
Monitor Lenovo 24'' 350
Impresora HP Deskjet H450 60
HDD externo para copias de seguridad 60
Periféricos 50
1.320
Software Euros
Licencia Windows 7 Professional SP1 149
Licencia Microsoft Office 2010 Profesional (MS Word y MSExcel) 393
Virtual Machines Player (VMWare) 0
Linux (Ubuntu) 0
Entorno de desarrollo (Eclipse) 0
Entorno Linux para Windows (CygWin) 0
542
5.3.2 Costes de consultoría
Como indicamos en el capítulo 5 (metodología), en SCRUM
identificamos 3 roles: el SCRUM Mater, El Propietario del Producto y el Equipo
de Desarrollo.
Los roles de SCRUM Master y Propietario del Producto no implican una
dedicación completa al proyecto sino que requiere su intervención durante
momentos clave bien definidos dentro del proceso de SCRUM. Sin embargo, el
coste de los miembros del Equipo de Desarrollo asignados a este proyecto se
aplicará íntegramente al mismo.
De cara a negociar con un cliente el coste de un proyecto desarrollado
siguiendo la metodología SCRUM podemos ofrecer facturar cada Sprint
basándonos en los Puntos de Historia completados y aceptados. De esta
manera estamos creando una relación con el cliente en la que se asegura de
pagar únicamente por las funcionalidades que recibe y que previamente se han
solicitado y acordado al principio de cada sprint.
Usaremos el factor de conversión “1 Punto de Historia” = “3 Horas de
desarrollo”, sobre un coste de horas de consultoría de 30 Euros/Hora.
Según este criterio, y basándonos en la estimación inicial de 102 Puntos
de Historia, podremos informar al cliente de un coste del proyecto aproximado
de 7.500 Euros.
66
Tabla 6 Estimación de costes iniciales facturables al cliente
Puntos de
Historia
Horas de
desarrollo Euros
Sprint 1 19 57 1.710
Sprint 2 19 57 1.710
Sprint 3 19 57 1.710
Sprint 4 19 57 1.710
Sprint 5 19 57 1.710
Sprint 6 7 21 630
102 306 7.470
Consultoría
Como hemos comentado, la facturación real de cada Sprint se adaptará
a lo realmente entregado, e incluirá los impuestos aplicables en cada momento.
Si se decidiera un incremento en la funcionalidad que conllevara nuevos
Sprints o nuevos Puntos de Historia, se seguiría el mismo criterio a la hora de
facturarlo (así quedará reflejado en el contrato entre ambas partes).
67
6 Desarrollo del proyecto
6.1 Preparativos
Existe una gran controversia sobre cómo incluir en la metodología
SCRUM las tareas técnicas y no técnicas previas al inicio del desarrollo y, por
tanto, a la entrega de alguna funcionalidad al cliente.
Podríamos incluir en este grupo las siguientes:
preparar los entornos de desarrollo.
trabajar en el Product Backlog, principalmente en dejar listas las
historias de usuario, priorizadas y estimadas.
Hacer una previsión del reparto de historias de usuario por
iteración.
Hacer un estudio de la arquitectura.
Alcanzar un acuerdo sobre la definición de “Done”, es decir, de
cuándo una Historia de Usuario está acabada y aceptada
Existen tres corrientes que ofrecen diferentes soluciones:
1. Una corriente aboga por la existencia de un sprint 0, a pesar de
que no desarrolle ninguna Historia de Usuario, pero respetando la
naturaleza de SCRUM (asignándole una duración fija, realizando
SCRUM diarios y la Revisión del Sprint).
2. Otra corriente, contraria a la anterior, opina que un sprint de este
tipo presenta los siguientes inconvenientes:
No genera código funcional
Elimina el sentido de urgencia
Conduce a malentendidos sobre cómo funciona SCRUM
Disgusta al cliente
y aboga por evitar denominar como sprint a esta fase porque
considera que, si lo llamáramos así, estaríamos ejecutando SCRUM,
pero eso sería incompatible con los citados cuatro inconvenientes.
3. La tercera vía es incluirlas como tareas técnicas en el sprint 1,
junto a otras que sí aporten valor al cliente. De esta manera, en la
revisión del sprint, el Product Owner puede obtener una primera
68
versión entregable del software, aunque con funcionalidades
reducidas.
En este proyecto preferimos ceñirnos completamente a la metodología
SCRUM y, de acuerdo con el cliente, no comenzar el proyecto en su fase de
desarrollo hasta no estar en disposición de generar valor.
Por tanto, durante las primeras semanas, mantuvimos dos reuniones
para conocer los requerimientos del cliente, traducirlos a Historias de Usuario,
decidir la arquitectura e instalar los entornos de desarrollo y pruebas
necesarios.
Tabla 7 Fase inicial: Objetivos del cliente
OG1 Objetivo General 1: Desarrollo de una aplicación eficiente
OE1Objetivos Específico 1: Desarrollo de un programa scriptable, mediante archivos de configuración,
para el funcionamiento en supercomputadoras
OE2 Objetivos Específico 2: Lenguaje de programación eficiente en términos de velocidad y memoria
OG2 Objetivo General 2: Desarrollo de una herramienta de análisis visual de operaciones en los mercados
OE3 Objetivos Específico 3: Lectura de datos históricos
OE4 Objetivos Específico 4: Representación gráfica de datos históricos e indicadores técnicos
OG3 Objetivo General 3: Desarrollo de una herramienta de backtesting
OE5 Objetivo Específico 5: Cálculo de indicadores técnicos sobre un conjunto de datos históricos
OE6Objetivo Específico 6: Decisión acerca del momento de realizar una operación en el mercado y de
finalizar la misma
OE7Objetivo Específico 7: Calcular el beneficio neto del conjunto de operaciones que se produzcan en
el periodo de tiempo que se ha extraído de los históricos
OE8 Objetivo Específico 8: Elaborar un informe con datos estadísticos sobre las operaciones realizadas
Tabla 8 Fase inicial. Traducción a Historias de Usuario
Historias de Usuario
(STO)
Puntos de
Historia (SP)
STO001 Como cliente quiero poder leer un archivo con datos históricos en formato CSV para calcular sobre ellos indicadores técnicos
1
STO002 Como cliente quiero que el software detecte el intervalo de tiempos del archivo de datos para poder generar gráficos intradía/interdía
1
STO003 Como cliente quiero que el software pueda manejar grandes cantidades de datos para poder leer series históricas
8
STO004 Como cliente quiero poder leer uno o más archivos de configuración para poder lanzar ejecuciones desatendidas
13
69
STO005 Como cliente quiero disponer de una lista de indicadores técnicos disponibles, que sea ampliable para poder utilizarla al declarar los escenarios
1
STO006 Como cliente quiero poder indicar rangos o listas de parámetros de los indicadores para poder lanzar simulaciones masivas
5
STO007 Como cliente quiero poder incluir constantes en los ficheros de configuración de los escenarios para simplificar la lectura de los mismos
1
STO008 Como cliente quiero poder escribir fórmulas o reglas en formato matemático y que el software pueda interpretarlas para dar versatilidad
5
STO009 Como cliente quiero poder indicar las fórmulas de decisión en los archivos de configuración para poder generar diferentes escenarios
1
STO010 Como cliente quiero poder generar un gráfico con información diaria a partir de un archivo CSV (desde script)
8
STO011 Como cliente quiero que los gráficos se puedan generar dinámicamente en función a parámetros (estudiar solución técnica) para decidir si se usan ficheros de configuración de gráficos
13
STO012 Como cliente quiero que cada gráfico que se genere lleve asociado un fichero CSV con la información representada para tratamientos en otras herramientas
1
STO013 Como cliente quiero que los gráficos puedan contener varias ventanas, y se puedan asociar variables a cada ventana, con tipos y colores parametrizables y que se pueda definir el tamaño en pixels para ofrecer mayor versatilidad
8
STO014 Como cliente quiero indicar al software que me genere gráficos siempre, nunca o en los n casos más favorables para no sobrecargar en el caso de escenarios masivos
5
STO015 Como cliente quiero poder mostrar en el gráfico las operaciones de entrada/salida del mercado para permitir un análisis visual
3
STO016 Como cliente quiero guardar en una matriz el resultado de la ejecución de todos los escenarios para poder realizar estudios posteriores
5
STO017 Como cliente quiero que el software ordene los escenarios según uno o más ratios calculados tras la ejecución para conocer las reglas más ventajosas
5
STO018 Como cliente quiero que, además de decidir entradas / salidas del mercado en base a unas fórmulas, también contemple StopLoss y TakeProfit para asimilarlo a las operaciones reales
13
STO019 Como cliente quiero disponer de un LOG de ejecución indicando tiempos para conocer el rendimiento de la librería de indicadores técnicos usada
5
Por último, y no menos importante, también acordamos entre el Product
Owner y el el Equipo de Desarrollo que, en cada Historia de Usuario,
incluiremos un campo que especifique la definición de “Terminado” en modo de
criterios de aceptación, porque nos resulta difícil encontrar una definición
aplicable a todas en conjunto.
70
En este punto ya teníamos toda la información necesaria para plantear
al cliente los costes estimados del proyecto, el número de sprints y, por tanto,
una primera estimación de duración del proyecto. Los costes de esta fase de
análisis no se trasladaron al cliente.
También inicializamos en Kunagi el proyecto Trading, creando los
usuarios y asignando los roles a cada miembro del equipo:
Asimismo, dimos de alta las Historias de Usuario con su estimación en
Puntos de Historia y la velocidad estimada del Equipo de Desarrollo (Kunagi
realiza con toda esa información una estimación de fechas de entrega):
Figura 13 Trading en Kunagi: Roles
71
Figura 14 Trading en Kunagi: Historias de Usuario
Ya estábamos preparados para el Sprint 1.
6.2 Sprint 1
6.2.1 Sprint Planning
En la reunión de planificación de este primer sprint, el Product Owner ha
seleccionado dos Historias de Usuario estimadas en un total de 14 Puntos de
Historia.
72
STO001: Como cliente quiero poder leer un archivo con datos
históricos en formato csv para calcular sobre ellos indicadores
técnicos
STO004: Como cliente quiero poder leer uno o más archivos de
configuración para poder lanzar ejecuciones desatendidas
Una aclaración: la velocidad del equipo calculada en el aparatado “5.1
Método de estimación utilizado” era de 19 SP, que supera en 5 SP a la suma
de la duración estimada de las dos historias seleccionadas. Podríamos haber
incluido otra Historia de Usuario más pero, para el cliente, la siguiente en
prioridad tiene una duración de 8 SP, lo cual superaría la capacidad de trabajo
del equipo. Una opción podría haber sido fragmentar la tercera historia en dos
partes, una de las cuales hubiera entrado en este sprint. Pero en este primer
ciclo optamos por ser conservadores y no incluir nada. En el Sprint Review
podremos ajustar este dato.
Figura 15 Sprint 1 Backlog
73
Falta completar en cada Historia de Usuario el valor que aporta al
negocio (según indique el Product Owner) y los criterios de aceptación para
tener toda la información que SCRUM recomienda en su estándar.
ID
STO001DESCRIPCIONComo cliente quiero poder leer un archivo con datos históricos en formato csv para calcular sobre ellos indicadores técnicosVALOR2ESTIMACION1 SPACEPTACIONEl nombre del fichero podrá ser un parámetroSe debe controlar la existencia del ficheroControlar que los datos del fichero tienen el formato esperado
ID
STO004DESCRIPCIONComo cliente quiero poder leer uno o más archivos de configuración para poder lanzar ejecuciones
desatendidasVALOR10ESTIMACION13 SPACEPTACIONAdmitir campos individuales y listas como elementos en los archivosVerificar existencia de archivos de configuraciónAlmacenar en variables locales
Figura 16 Sprint 1 Historias de Usuario
Ahora el equipo detallará las tareas y, en base a ello, confirmará la
duración de estas Historias de Usuario.
A continuación se muestra una tabla con la lista de tareas identificadas
para el Sprint 1:
Tabla 9 Sprint 1 Tareas
Historia de
Usuario
Tarea Descripción Horas
STO001 TSK001 Crear función en C para control de existencia de fichero en
disco
1
STO001 TSK002 Crear bucle de lectura controlando número de columnas y tipo,
almacenando array en memoria
1
STO001 TSK003 Realizas las pruebas de acuerdo a los criterios de aceptación 1
STO004 TSK001 Crear una función que interprete un fichero de texto que
contenga nombre de parámetros y valores (individuales o listas)
24
STO004 TSK002 Crear funciones que recuperen parámetros concretos y los
almacene en variables en memoria
9
STO004 TSK003 Realizar control de errores: valor incorrecto en parámetros o no
existencia
3
STO004 TSK004 Realizas las pruebas de acuerdo a los criterios de aceptación 3
74
Una vez incorporadas las tareas en Kunagi, nuestro tablero Kanban
muestra el siguiente aspecto:
Figura 17 Sprint 1 Tablero al inicio del Sprint
6.2.2 Sprint Review
Este ha sido el primer Sprint de nuestro proyecto. Las tareas asociadas
a las Historias de Usuario fueron estimadas por el Equipo de Desarrollo en 42
horas (3 para la primera y 39 para la segunda).
Como podemos comprobar en el gráfico Burndown que mostramos a
continuación, la primera parte del Sprint fuimos con retraso debido a los
siguientes motivos:
1. Configuraciones iniciales
2. Cambio de estrategia en la segunda Historia de Usuario
75
Durante la realización de la primera Historia de Usuario realizamos
también tareas de preparación del proyecto en Eclipse (enlazado con Cygwin) y
el diseño de la arquitectura del software. Por ello no fue hasta el tercer día en
que comenzamos con su primera tarea. Una vez iniciada, esta Historia de
Usuario se desarrolló y probó en el plazo previsto.
Durante la segunda Historia de Usuario, que sabíamos compleja,
tuvimos que abordar un cambio de estrategia, que dilató la primera tarea en la
que el objetivo era el desarrollo de una función para interpretar ficheros de
texto donde almacenar los parámetros de la aplicación. Una vez iniciado el
desarrollo, vimos cómo la complejidad aumentaba ya que había que controlar
que la sintaxis de la información contenida en el fichero fuera correcta, e
implementar funciones que accedieran a contenidos concretos (un parámetro u
otro).
Pensamos que quizás habría software ya creado y decidimos detener el
desarrollo que habíamos iniciado e emprender una búsqueda. Con cierta
rapidez encontramos la librería libconfig que parecía responder a nuestros
requerimientos. Para asegurarnos, dedicamos tiempo a las tareas de
instalación y enlazado en nuestro proyecto, y unas primeras pruebas para
comprobar que funcionaba correctamente, antes de continuar el desarrollo en
torno a ella.
El tiempo invertido es investigar esta librería trajo sus frutos a partir de la
mitad del sprint, donde pudimos recuperar rápidamente el atraso de los
primeros días, confirmando lo acertado de nuestra apuesta por este producto.
Figura 18 Sprint 1 Burndown Chart
76
Como ejemplo del seguimiento en el tablero, adjuntamos situación que
nos muestra Kunagi justo antes de realizar las últimas pruebas del sprint (tarea
que podemos ver en la columna central):
Figura 19 Sprint 1 Tablero a falta de las pruebas de la Historia STO004
En cuanto al desarrollo general del proyecto, el Release Burndown Chart
nos muestra la entrega de 4 SP menos de lo esperado en función de nuestra
velocidad teórica debido a que inicialmente seleccionamos menos Historias de
Usuario.
6.2.3 Sprint Retrospective
Cabe en este punto hacernos las siguientes preguntas:
Si hiciéramos el sprint otra vez, ¿haríamos las cosas igual? ¿o haríamos
algunas cosas de forma diferente y cómo?
Figura 20 Sprint 1 Release Burndown Chart
77
De lo ocurrido en este sprint con el cambio de estrategia respecto a la
lectura de archivos de configuración, hemos aprendido que al valorar el
esfuerzo de una Historia de Usuario, debemos incluir un factor de incertidumbre
para aquéllos casos en los que no tengamos claro qué tecnología usar.
A pesar de ello, el equipo ha trabajado a la velocidad estimada al
principio del proyecto porque, al haber seleccionado menos Puntos de Historia,
este sprint ha sido llevado con soltura, especialmente en el último tercio del
mismo. Por este motivo mantenemos la velocidad del Equipo en 19 SP por
Sprint y nos hace sentirnos confiados para las siguientes iteraciones.
6.2.4 Demos
6.2.4.1 Lectura de fichero csv
Partimos de un fichero de datos históricos proporcionados por el cliente.
Figura 21 Sprint 1 Demo: fichero CSV de entrada
El programa muestra en consola el resultado de la lectura, indicando el
número de líneas leídas y los datos de las tres últimas lecturas.
Figura 22 Sprint 1 Demo: lectura de fichero csv
78
6.2.4.2 Lectura de fichero de configuración
Partimos de un fichero de configuración con sintaxis admitida por la
librería libconfig.
Figura 23 Sprint 1 Demo: fichero de configuración ejemplo
El software muestra los valores extraídos del fichero e incorporados en
memoria
Figura 24 Sprint 1 Demo: lectura fichero de configuración
6.2.4.3 Control de errores
A continuación se muestra el control de errores en la lectura del archivo
de datos históricos:
Figura 25 Sprint 1 Demo: error en lectura del fichero csv
79
6.3 Sprint 2
6.3.1 Sprint Planning
En la reunión de planificación de este primer sprint, el Product Owner ha
priorizado cinco Historias de Usuario estimadas en un total de 19 Puntos de
Historia.
STO010: Como cliente quiero poder generar un gráfico con
información diaria, inicialmente desde script, para disponer de una
herramienta visual de análisis
STO003: Como cliente quiero que el software pueda manejar
grandes cantidades de datos para poder leer series históricas
STO002: Como cliente quiero que el software detecte el intervalo
de tiempos del archivo de datos para poder generar gráficos
intradía/interdía
Figura 26 Sprint 2 Backlog
80
STO012: Como cliente quiero que cada gráfico que se genere
lleve asociado un fichero csv con la información representada
para tratamientos en otras herramientas analíticas
STO005: Como cliente quiero disponer de una lista de
indicadores a poder utilizar, que sea editable para poder utilizarla
al declarar los escenarios
Hemos acordado con el Product Owner seleccionar Historias cuya
duración completen la velocidad del equipo, estimada en 19 SP. Recordemos
que en Sprint 1 realizamos 14 SP pero que, conforme se desarrollaron las
tareas, somos optimistas en alcanzar las 19 SP.
Analizamos en detalle cada Historia de Usuario junto al Product Owner):
ID
STO010DESCRIPCIONComo cliente quiero poder generar un gráfico con información diaria (desde script),para disponer de una herramienta visual de análisisVALOR5ESTIMACION8 SPACEPTACIONSe debe controlar la existencia del ficheroQueremos guardar el gráfico como una imagen png en disco
ID
STO003DESCRIPCIONComo cliente quiero que el software pueda manejar grandes cantidades de datos, para poder leer series
históricasVALOR10ESTIMACION8 SPACEPTACIONManejar dinámicamente la memoriaControlar en todo momento errores de asignaciónReutilizar espacio de memoria ya reservado en ejecuciones anteriores
ID
STO002DESCRIPCIONComo cliente quiero que el software detecte el intervalo de tiempos del archivo de datos para poder generar gráficos intradía/interdíaVALOR1ESTIMACION1 SPACEPTACIONPoder distinguir entre minutos, horas y díasControlar que los datos fecha/hora son correctos antes de realizar los cálculos
ID
STO012DESCRIPCIONComo cliente quiero que cada gráfico que se genere lleve asociado un fichero csv con la información representada para tratamientos en otras herramientasVALOR3ESTIMACION1 SPACEPTACIONImplementar control de errores al escribir en discoIncluir en el fichero datos históricos y dejar preparado para incluir resultados del cálculo de indicadores
81
ID
STO005DESCRIPCIONComo cliente quiero disponer de una lista de indicadores a poder utilizar, que sea editable para poder utilizarla al declarar los escenariosVALOR1ESTIMACION1 SPACEPTACIONLeer un archivo de configuración de texto donde poder incluir los indicadores aceptados y sus parámetrosAlmacenar en memoria dinámicamente
Figura 27 Sprint 2 Historias de Usuario
Ahora el equipo detallará las tareas y, en base a ello, confirmará la
duración de estas Historias de Usuario.
A continuación se muestra la tabla que elaboramos con la lista de tareas
identificadas para el Sprint 2:
Tabla 10 Sprint 2 Tareas
Historia de
Usuario
Tarea Descripción Horas
STO010 TSK001 Análisis de alternativas que ofrece matplotlib para graficar
información financiera
18
STO010 TSK002 Crear función que compruebe existencia del script en el
directorio de la aplicación y lo ejecute
3
STO010 TSK003 Realizas las pruebas de acuerdo a los criterios de aceptación 3
STO003 TSK001 Diseñar y crear structs y arrays para toda la información a
manejar: indicadores técnicos, datos históricos parámetros
6
STO003 TSK002 Crear un módulo específico para manejo de memoria con
malloc, realloc y free (datos de texto y numéricos float e int)
12
STO003 TSK003 Implementar un control de errores de manejo de memoria 3
STO003 TSK004 Realizas las pruebas de acuerdo a los criterios de aceptación 3
STO002 TSK001 Desarrollar una función que valide que la información histórica
leída contiene el detalle necesario para permitir el cálculo
1
82
STO002 TSK002 Desarrollar función que calcule el salto temporal entre los dos
últimos datos consecutivos
1
STO002 TSK003 Realizas las pruebas de acuerdo a los criterios de aceptación 1
STO012 TSK001 Crear función que recorra la estructura de datos históricos y
genere información en fichero en formato tabular
1
STO012 TSK002 Controlar mensajes de error de acceso a ficheros del sistema
operativo
1
STO012 TSK003 Realizas las pruebas de acuerdo a los criterios de aceptación 1
STO005 TSK001 Ampliar la rutina de lectura de archivos de configuración y
estructuras en memoria
2
STO005 TSK002 Realizas las pruebas de acuerdo a los criterios de aceptación 1
A continuación activamos en Kunagi el sprint 2 y asignamos las Historia
de Usuario y sus tareas asociadas. Podemos ver a continuación el tablero
completo en el momento del inicio, justo antes de que el equipo comience a
trabajar con él.
83
Figura 28 Sprint 2 Tablero al inicio del Sprint
6.3.2 Sprint Review
En la fase inicial de este sprint nos vimos penalizados por las tareas de
investigación de las dos grandes Historias de Usuario seleccionadas: la
creación de gráficos usando matplotlib y el diseño de nuestra aplicación en lo
que se refiere al uso de memoria dinámica.
Fueron muchas las horas de trabajo dedicadas a la investigación de esta
librería y a su enlace con nuestra aplicación en C. Pronto pudimos ver que es
una magnífica utilidad y que proporciona gráficos de gran calidad estética y una
84
fantástica interface para los programadores. En este sprint trabajamos
básicamente con ficheros script propietarios de matplotlib, pero pudimos
vislumbrar que podríamos generar los gráficos dinámicamente con un poco
más de investigación.
En cuanto al manejo de memoria, nuestra decisión fue implementar
estructuras que contendrían la información recogida de los archivos de
configuraciones pero, además, un sistema de arrays de punteros a estructuras
en memoria para contener el grueso de la información, es decir, los datos
históricos sobre los que realizaremos el backtesting y los indicadores
calculados por la librería TA-Lib. En el apartado “10, Anexo I Diseño de la
aplicación” se explica en detalle la solución técnica aplicada.
Una vez concluida esta fase de diseño, la implementación fue rápida y
pudimos recuperar, e incluso adelantarnos, al calendario previsto.
El resto de Historias de Usuario no presentaron dificultades y se
mantuvo el buen ritmo.
La sensación que tenemos en el Equipo de Desarrollo es que podríamos
admitir cargas de más de 19SP
Adjuntamos a continuación el tablero justo al terminar la primera Historia
de Usuario del sprint, mostrando la primera tarea de la segunda Historia
seleccionada.
Figura 29 Sprint 2 Burndown Chart
85
Figura 30 Sprint 2 Tablero al finalizar la Historia de Usuario STO010
En cuanto al desarrollo general del proyecto, el Release Burndown Chart
nos muestra la entrega de 4 SP menos de lo esperado, en función de nuestra
velocidad teórica, debido al retraso acumulado desde el primer Sprint.
6.3.3 Sprint Retrospective
Al igual que en el sprint 1, las tareas de investigación en el uso de
nuevos productos pueden conducir a retrasos en las etapas iniciales. Sin
embargo hemos observado que en tareas de desarrollo nuestra velocidad está
por encima de los estimado.
Figura 31 Sprint 2 Release Burndown Chart
86
En el Sprint 3 intentaremos incluir alguna Historia que nos haga superar
nuestros 19SP. Creemos poder manejarla y, así, podríamos recuperar el
retraso inicial.
6.3.4 Demos
6.3.4.1 Gráfico de velas simple generado por matplotlib
Figura 32 Sprint 2 Demo: script de matplotlib
Figura 33 Sprint 2 Demo: gráficos de velas con matplotlib
87
6.3.4.2 Almacenamiento de información en estructuras C y cálculo del
intervalo temporal
Tomamos de nuevo el fichero csv de entrada del sprint 1:
Figura 34 Sprint 2 Demo: fichero CSV de entrada
El software lee y graba la información en la siguiente estructura:
Figura 35 Sprint 2 Demo: estructura para almacenar datos históricos
Adjuntamos un volcado de la información almacenada en la estructura
junto al resultado del cálculo del intervalo de tiempo entre muestras (en este
caso, 5 minutos):
88
Figura 36 Sprint 2 Demo: información almacenada en la estructura
6.3.4.3 Fichero generado
Adjuntamos imagen de una muestra del archivo generado por la
aplicación. Este fichero contiene la información leída del fichero CSV de
entrada, pero contendrá columnas adicionales para almacenar los resultados
de los indicadores técnicos (ver últimas columnas del fichero, con información
de ejemplo):
Figura 37 Sprint 2 Demo: fichero de salida generado
89
6.4 Sprint 3
6.4.1 Sprint Planning
Como comentamos en el Sprint Review del ciclo 2, en esta ocasión
pediremos abordar Historias de Usuario con una duración estimada superior a
nuestra velocidad inicial, ya que consideramos que somos capaces de
realizarlas, especialmente si no hay tareas de investigación implicadas.
Por tanto, según la prioridad marcada por el Product Owner, decidimos
aceptar las siguientes Historias de Usuario, con un peso total de 21 SP:
STO011: Como cliente quiero que los gráficos se puedan generar
dinámicamente en función a parámetros (estudiar solución
técnica) para decidir si se usan ficheros de configuración de
gráficos
STO013: Como cliente quiero que los gráficos puedan contener
varias ventanas, y se puedan asociar variables a cada ventana,
con tipos y colores parametrizables y que se pueda definir el
tamaño en pixels para ofrecer mayor versatilidad
Figura 38 Sprint 3 Backlog
90
Analizamos en detalle cada Historia de Usuario junto al Product Owner:
ID
STO011DESCRIPCIONComo cliente quiero que los gráficos se puedan generar dinámicamente en función a parámetros (estudiar solución técnica) para decidir si se usan ficheros de configuración de gráficosVALOR5ESTIMACION13 SPACEPTACIONQueremos prescindir del uso de ficheros de script estáticosQueremos poder crear o no los gráficosQueremos que la creación de gráficos sea desatendida y los genere con nombres que se puedan posteriormente identificar
ID
STO013DESCRIPCION
Como cliente quiero que los gráficos puedan contener varias ventanas, y se puedan asociar variables a cada ventana, con tipos y colores parametrizables y que pueda definir en pixels el tamaño para ofrecer mayor versatilidadVALOR8ESTIMACION8 SPACEPTACION
Definir el formato del gráfico en el archivo de configuraciónAceptar número de ventanas, tipos de gráficos, colores, variables a representar, mostrar/ocultar ejes, ...
Figura 39 Sprint 3 Historias de Usuario
Una vez completa toda la información que describe totalmente las
Histoias de Usuario para este sprint, el equipo de desarrollo identifica y valora
las tareas asociadas, obteniendo como resultado la siguiente tabla:
Tabla 11 Sprint 3 Tareas
Historia de
Usuario
Tarea Descripción Horas
STO011 TSK001 Estudiar solución técnica (llamadas desde C a matplotlib).
Seleccionar el paso de información por memoria o en base a
ficheros
24
STO011 TSK002 Crear un módulo sólo para la generación de los gráficos 12
STO011 TSK003 Realizas las pruebas de acuerdo a los criterios de aceptación 3
STO013 TSK001 Identificar las características de los gráficos parametrizables 14
STO013 TSK002 Modificar los ficheros de configuración de los escenarios para
incluir la información
4
STO013 TSK003 Realizar una función para recoger de los archivos de
configuración la información sobre los gráficos
3
STO013 TSK004 Realizas las pruebas de acuerdo a los criterios de aceptación 3
Procedemos a continuación a reflejar el contenido del sprint en Kunagi.
Primero incluimos las Historias de Usuario. En la siguiente imagen observamos
el paso de incluir la STO013 (“Pull to Spring”).
91
También vemos cómo la aplicación nos va mostrando la velocidad del
equipo en base a la conseguida en los sprints anteriores.
Figura 41 Sprint 3: Tablero a falta de incluir las tareas
Y ahora mostramos el tablero completo en el momento del inicio del
sprint:
Figura 40 Sprint 3: incluir Historias de Usuario en un Sprint
92
Figura 42 Sprint 3 Tablero al inicio del Sprint
6.4.2 Sprint Review
Este sprint 3 se ha desarrollado con total normalidad. Parte del esfuerzo
dedicado a la investigación de la librería matplotlib durante el ciclo anterior ha
dado sus frutos en éste, donde la mayor parte del trabajo se ha empleado en
implementar la solución en nuestro proyecto.
Dada la versatilidad y potencia de este módulo gráfico y de la librería
libconfig (para la lectura de los archivos de configuración), se ha podido crear
un completo paquete de gráficos financieros dentro de nuestra aplicación.
Podemos observar en el Burndown Chart cómo el desarrollo de las
tareas ha estado prácticamente en todo momento mejor de lo presupuestado,
sin encontrar grandes dificultades.
La única excepción fue le creación de gráficos intradía, donde el Equipo
de Desarrollo tardó en encontrar la configuración correcta para el eje de
abscisas (la documentación existente es muy extensa y lleva tiempo localizar
un aspecto en concreto).
93
Con este sprint el Equipo de desarrollo ha mostrado gran interés en
recuperar el terreno perdido a nivel general del proyecto, consiguiendo
acercarse al objetivo inicial. Véase el siguiente gráfico:
6.4.3 Sprint Retrospective
Definitivamente el Equipo ha sido capaz de trabajar por encima de las
19SP. En la reunión de planificación del siguiente sprint informaremos al
Product Owner de este hecho, de cara a la selección de las siguientes Historias
de Usuario.
Figura 43 Sprint 3 Burndown Chart
Figura 44 Sprint 3 Release Burndown Chart
94
6.4.4 Demos
6.4.4.1 Lectura de la configuración de gráficos
En esta demo mostramos al cliente cómo, a partir de un archivo de
configuración, el software almacena esta información en memoria para su
posterior uso al graficar los resultados de las simulaciones:
Figura 45 Sprint 3 Demo: configuración del formato de los gráficos
Figura 46 Sprint 3 Demo: salida por consola de la información leída
95
6.4.4.2 Gráfico dinámico: primera versión
Figura 47 Sprint 3 Demo: gráfico creado dinámicamente
6.5 Sprint 4
6.5.1 Sprint Planning
En este cuarto ciclo informamos al Product Owner que nuestra apuesta
por superar las 19SP ha sido acertada y proponemos modificar la velocidad a
21SP, actualización permitida por SCRUM si se produce en función del
resultado de las revisiones de rendimiento realizadas durante los Sprint Review
y Sprint Retrospective.
El Product Owner nos presenta sus requerimientos traducidos a
Historias de Usuario priorizadas:
96
STO008: Como cliente quiero poder escribir fórmulas en formato
matemático para que el software pueda interpretarlas
STO006: Como cliente quiero poder indicar rangos o listas de
parámetros de los indicadores para lanzar simulaciones masivas
STO009: Como cliente quiero poder indicar las fórmulas de
decisión en los archivos de configuración para poder generar
diferentes escenarios
STO019: Como cliente quiero disponer de un LOG de ejecución
indicando tiempos para conocer el rendimiento de la librería de
indicadores técnicos usada y del software en general
STO015: Como cliente quiero poder indicar en el gráfico las
operaciones de entrada/salida del mercado para permitir un
análisis visual (esta Historia de Usuario, en función de la
conversación mantenida con el cliente, y por su complejidad,
Figura 48 Sprint 4 Backlog
97
hemos decidido estimarla al alza en 5SP, en lugar de los 3SP
que tenía inicialmente)
Y el detalle de cada una se muestra a continuación:
ID
STO008DESCRIPCIONComo cliente quiero poder escribir fórmulas en formato matemático y que el software pueda interpretarlasVALOR8ESTIMACION5 SPACEPTACIONDebe ejecutar operaciones aritméticas básicasDebe contemplar el uso de paréntesisDebe poder evaluar condicione >,<,=Debe poder recoger el valor de variables e indicadoresDebe poder recoger el valor de constantesValor absoluto y negaciónAdmitir subíndices
ID
STO006DESCRIPCIONComo cliente quiero poder indicar rangos o listas de parámetros de los indicadores para lanzar simulaciones masivasVALOR8ESTIMACION5 SPACEPTACIONAceptar valores únicosAceptar lista de valoresAceptar rando: desde-hasta-salto
ID
STO009DESCRIPCIONComo cliente quiero poder indicar las fórmulas de decisión en los archivos de configuración para poder generar diferentes escenariosVALOR3ESTIMACION1 SPACEPTACIONDebe contemplar las fórmulas para cálculo de tendencia alcista y bajistaDebe permitir indicar las fórmulas para el volumen a contratar
ID
STO019DESCRIPCIONComo cliente quiero disponer de un LOG de ejecución indicando tiempos para poder conocer el rendimiento del softwareVALOR3ESTIMACION5 SPACEPTACIONDebe poder ser opcional su generaciónDebe mostrar tiempos de ejecuciónMostrar errores cuando se produzcan, y el motivoResultados de las simulacionesPoder seleccionar el directorio donde se genera
98
ID
STO015DESCRIPCIONComo cliente quiero poder indicar en el gráfico las operaciones de entrada/salida del mercado para poder realizar un análisis visualVALOR3ESTIMACION5 SPACEPTACIONIndicar el punto en el tiempo donde se realiza una operaciónDistinguir por colores/texto el tipo de entrada/salida
Tras el análisis de cada Historia, el Equipo de Desarrollo identifica las
siguientes tareas, y su duración en horas de trabajo:
Tabla 12 Sprint 4 Tareas
Historia de
Usuario
Tarea Descripción Horas
STO008 TSK001 Desarrollar un analizador sintáctico para expresiones
matemáticas
7
STO008 TSK002 Desarrollar una función que reemplace el nombre de las
variables por su valor numérico
5
STO008 TSK003 Realizas las pruebas de acuerdo a los criterios de aceptación 3
STO006 TSK001 Modificar la lectura de los archivos de configuración para poder
distinguir entre valores individuales, listas y rangos
5
STO006 TSK002 Almacenar en estructuras en memoria para su posterior uso por
el simulador
7
STO006 TSK003 Realizas las pruebas de acuerdo a los criterios de aceptación 3
STO009 TSK001 Preparar las estructuras en memoria para almacenar las
fórmulas
1
STO009 TSK002 Desarrollar la función de lectura del archivo de configuración
para el apartado de las fórmulas
1
STO009 TSK003 Realizas las pruebas de acuerdo a los criterios de aceptación 1
STO019 TSK001 Crear una función que, en función de un parámetro, genera el
archivo en un directorio seleccionado en el config
3
STO019 TSK002 Modificar todo el código fuente en los puntos que manejen 10
99
información relevante para ser enviada al fichero
STO019 TSK003 Realizas las pruebas de acuerdo a los criterios de aceptación 2
STO015 TSK001 Incluir una nueva columna en la estructura que almacena los
indicadores, para indicar la operación realizada en cada
momento (codificar numéricamente el tipo … p.e. 1: entrada 2:
salida …..)
4
STO015 TSK002 Modificar el módulo de los gráficos para recoger esta
información y dibujar una etiqueta en el gráfico según el color
de cada operación
8
STO015 TSK003 Realizas las pruebas de acuerdo a los criterios de aceptación 3
Ahora procedemos a recoger esta información en nuestra herramienta
de seguimiento del proyecto (Kunagi). Observamos en la imagen siguiente el
cambio del Product Backlog antes y después de enviar estas cinco Historias de
Usuario al sprint 4.
También podemos observar la nueva velocidad del equipo de 21 SP.
Figura 49 Sprint 4: Reducción del Product Backlog tras asignar al Sprint
100
Y éste es el tablero completo en el momento del inicio del Sprint:
Figura 50 Sprint 4 Tablero al inicio del Sprint
En la siguiente imagen podemos observar un momento del sprint con
una Historia de Usuario parcialmente completada (una tarea están en
desarrollo). Podemos observar en las líneas horizontales (verde y azul) el
estado de completitud de la misma.
101
Figura 51 Sprint 4 Tablero con dos tareas finalizadas y una en curso
6.5.2 Sprint Review
Este sprint ha resultado técnicamente muy interesante al incluir el
desarrollo de un analizador sintáctico de expresiones matemáticas y la lógica
para manejar parámetros que puedan tomar valores en un conjunto o en un
rango del tipo desde-hasta-salto.
Únicamente nos ha quedado por mejorar (no lo hemos hecho por
ceñirnos a las horas de trabajo estimadas) el tratamiento correcto de la
precedencia en las operaciones +, -, *, /. De momento, en esta versión,
indicaremos en el manual de usuario que se deben usar paréntesis para suplir
esta carencia.
Observamos el buen alineamiento de la ejecución de tareas con la
estimación realizada por el Equipo de Desarrollo:
Podemos observar en el gráfico Release Burn down global del proyecto
que, al aumentar nuestra velocidad, hemos conseguido recuperar el atraso con
que iniciamos el primer sprint. El Equipo es capaz de desarrollar de manera
sostenida a una velocidad de 21SP.
Figura 52 Sprint 4 Burndown Chart
102
6.5.3 Sprint Retrospective
No tenemos nada relevante que comentar en esta retrospectiva. Este
ciclo se ha desarrollado con total normalidad. El manejo de tiempos ha sido
adecuado y hemos sido incluso capaces de detectar el peligro de invertir
demasiado tiempo en el desarrollo de un analizador sintáctico que incluyera la
complejidad del manejo de la precedencia. Por el contrario, hemos preferido
concluir una versión sin esta funcionalidad, en aras de que el cliente pueda ver
una demo del producto.
6.5.4 Demos
6.5.4.1 Analizador sintáctico de fórmulas
Mostramos a continuación el resultado satisfactorio de un análisis de la
fórmula que determina una situación alcista. Se observa la sustitución de los
nombres de las variables/indicadores por sus posiciones en la tabla de datos.
En este caso:
Outmacd se encuentra almacenado en el índice 9 de la tabla
Outma se encuentra almacenado en el índice 7 de la tabla
Figura 53 Sprint 4 Release Burndown Chart
Figura 54 Sprint 4 Demo: analizador sintáctico de expresiones
103
6.5.4.2 Rangos de números
Se muestra la salida en la que, a partir del fichero de configuración
donde el parámetro optInFastPeriod del indicador MACD toma dos valores
(“12” y 14”), se generan dos líneas con el mismo id de parámetro, pero con
diferentes valores:
6.5.4.3 Ejemplo de fichero LOG
Figura 56 Sprint 4 Demo: fichero LOG
Figura 55 Sprint 4 Demo: parámetros con varios valores
104
6.5.4.4 Operaciones de entrada/salida en gráficos
6.6 Sprint 5
6.6.1 Sprint Planning
En la reunión de planificación del quinto sprint, el Product Owner había
seleccionado 4 Historias de Usuario, que en total sumaban 16 Puntos de
Historia (SP), lo cual quedaba por debajo de las 21 SP que éramos capaces de
desarrollar (-5SP).
La siguiente Historia de Usuario, priorizada según el valor para el
negocio tenía un tamaño de 13SP, lo que nos hacía imposible incluirla en su
totalidad.
SCRUM nos permite dividir una Historia de Usuario en otras de menores
dimensiones, siempre y cuando las resultantes sigan ofreciendo una
funcionalidad al cliente.
Solicitamos por tanto al Product Owner que analizara si era posible
dividir la historia STO018 (como cliente quiero que, además de decidir entradas
/ salidas del mercado en base a unas fórmulas, también contemple Stop Loss y
Figura 57 Sprint 4 Demo: indicadores de entrada/salida del mercado
105
Take Profit) en, al menos, otras dos, siendo una de ellas de tamaño entorno a
los 5SP para que pudiera ser incluida en este sprint.
Finalmente llegamos a un acuerdo, y la Historia de Usuario STO018 se
convirtió en dos:
La STO018, con un nuevo tamaño de 5SP: Como cliente quiero
que se puedan incluir en los archivos de configuración
información relativa al StopLoss y TakeProfit para asimilarlo a las
operaciones reales
Una nueva STO020, de tamaño 8SP: Como cliente quiero que las
simulaciones tengan en cuenta el efecto del StopLoss y
TakeProfit para generar órdenes de salida del mercado
Podemos observar en la siguiente figura esta división:
Figura 58 Sprint 5 Backlog
106
STO016: Como cliente quiero guardar en una matriz el resultado
de la ejecución de todos los escenarios para poder realizar
estudios posteriores
STO017: Como cliente quiero que el software me ordene los
escenarios según uno o más ratios para conocer las reglas de
mercado más ventajosas
STO014: Como cliente quiero indicar al software que me genere
gráficos siempre, nunca o en los n casos más favorables para no
sobrecargar en el caso de ejecución de escenarios masivos
STO007: Como cliente quiero poder incluir constantes en los
ficheros de configuración de los escenarios para simplificar la
lectura de los mismos
STO018: Como cliente quiero incluir en los archivos de
configuración información relativa al Stop Loss y Take Profit para
asimilarlo a las operaciones reales del mercado
Como en los sprint anteriores, ahora debemos documentar para cada
Historia de Usuario, los aspectos que la definen completamente, desde su
estimación en Puntos de Historia, hasta el valor que aportaría al negocio y los
criterios que, una vez satisfechos, determinarían que la Historia está
completamente realizada y aceptada:
107
ID
STO016DESCRIPCIONComo cliente quiero guardar en una matriz el resultado de la ejecución de todos los escenarios para poder realizar estudios posterioresVALOR3ESTIMACION5 SPACEPTACIONAlmacenar el detalle de las operaciones de entrada/salidaAlmacenar el profitCalcular y almacenar otros ratios
ID
STO017DESCRIPCIONComo cliente quiero que el software me ordene los escenarios según uno o más ratios para conocer las regla del mercado más ventajosasVALOR3ESTIMACION5 SPACEPTACIONComprobar que hay resultados para ordenarDebe contemplar que haya escenarios con el mismo resutado
ID
STO014DESCRIPCIONComo cliente quiero indicar al software que me genere gráficos siempre, nunca o en los n casos más favorables para no sobrecargar el sistema en ejecuciones masivasVALOR3ESTIMACION5 SPACEPTACIONComprobar que no queremos generar más gráficos que los disponiblesNombrar los ficheros para que se pueda distinguir si son parte de los n-mejores o del total
ID
STO007DESCRIPCIONComo cliente quiero poder incluir constantes en los ficheros de configuración de los escenarios para simplificar la lectura de los mismosVALOR1ESTIMACION1 SPACEPTACIONLas constantes deben ir para cada escenarioLos nombres de las constantes debe poder usarse en las fórmulas que interpreta el analizador sintáctico
ID
STO018DESCRIPCIONIncluir en los archivos de configuración información relativa al StopLoss y TakeProfit para asimiilarlo a las operaciones reales del mercadoVALOR11ESTIMACION5 SPACEPTACIONDebe poder basarse en fórmulasDebe estar por separado SL y TPIndicar una para compra (operaciones a largo) y venta (operaciones en corto)
108
Se muestran a continuación las tareas asociadas a cada Historia de Usuario:
Tabla 13 Sprint 5 Tareas
Historia de
Usuario
Tarea Descripción Horas
STO016 TSK001 Definir las estructuras para almacenar resultados de cada
iteración y el historial de operaciones de entrada/salida
3
STO016 TSK002 Desarrollar la función que almacene la información de cada
ciclo
10
STO016 TSK003 Realizas las pruebas de acuerdo a los criterios de aceptación 2
STO017 TSK001 Seleccionar un método de ordenación( burbuja, otros) 2
STO017 TSK002 Desarrollar la función Sort tomando como entradas las
estructuras del historial de simulaciones y operaciones de
entrada/salida
10
STO017 TSK003 Realizas las pruebas de acuerdo a los criterios de aceptación 3
STO014 TSK001 Modificar fichero de configuración general para incluir este
parámetros y realizar la función de lectura
1
STO014 TSK002 Revisar todo el código para generar gráficos o no, según el
valor del parámetro
10
STO014 TSK003 Realizas las pruebas de acuerdo a los criterios de aceptación 4
STO007 TSK001 Modificar ficheros de configuración de los escenarios para
incluir una lista de constantes, con nombre y valor
1
STO007 TSK002 Modificar el código del analizador sintáctico para que
reconozca los nombre de las constantes
1
STO007 TSK003 Realizas las pruebas de acuerdo a los criterios de aceptación 1
STO013 TSK001 Modificar ficheros de configuración de los escenarios para
incluir fórmulas de TP y SL
4
STO013 TSK002 Realizar la función de lectura y almacenamiento en memoria de
las fórmulas de TP y SL
8
STO013 TSK003 Realizas las pruebas de acuerdo a los criterios de aceptación 3
109
Ahora procedemos a recoger esta información en nuestra herramienta
de seguimiento del proyecto (Kunagi):
Figura 59 Sprint 5 Tablero al inicio del Sprint
110
6.6.2 Sprint Review
Durante este quinto sprint, hemos experimentado un poco de retraso en
las etapas iniciales, coincidiendo con las tareas de desarrollo del código fuente
para almacenar en un array los resultados que se van produciendo en cada
iteración del programa de simulación. El diseño de cómo implementar esta
función y las tareas asociadas ha sido algo más complicado de lo que
estimábamos, ya que también identificamos que teníamos que guardar
punteros a otras estructuras donde se almacenarían los apuntes financieros de
entradas/salidas del mercado.
Sin embargo, como podemos observar en el gráfico, hemos podido
terminar el ciclo apenas un poco peor de lo previsto, por lo que, de cara al
proyecto completo, la evolución es correcta y se van cumpliendo las
estimaciones. Lo podemos observar en la figura siguiente:
Figura 60 Sprint 5 Burndown Chart
111
6.6.3 Sprint Retrospective
No tenemos nada reseñable que comentar. Este ciclo se ha desarrollado
con total normalidad.
6.6.4 Demos
6.6.4.1 Matriz de resultados ordenada
Mostramos al cliente una captura del output del programa donde se
obtiene una tabla con las iteraciones de cada escenario ejecutado, ordenados
de mayor a menor beneficio neto. Es en sí la matriz solicitada en la historia
STO016, ordenada según pedía la historia STO017.
Figura 62 Sprint 5 Demo: Tabla de resultados
También se obtiene, al final de la ejecución, un informe con los
escenarios que ofrecen los mejores resultados:
Figura 61 Sprint 5 Release Burndown Chart
112
Figura 63 Sprint 5 Demo: Resultados ordenados
6.6.4.2 Lectura de constantes desde el fichero de configuración
En esta demo mostramos cómo los datos contenidos en el archivo de
configuración, en el apartado de constantes, son recogidos y almacenados
para su posterior tratamiento:
Figura 64 Sprint 5 Demo: constantes en los archivos de configuración
Figura 65 Sprint 5 Demo: constantes almacenadas en la aplicación
113
6.7 Sprint 6
6.7.1 Sprint Planning
Recordamos cómo en las primeras reuniones con el cliente, y
basándonos en los requerimientos del negocio (traducidos a Historias de
Usuario) y en la velocidad estimada del equipo, pudimos identificar un total de
6 sprints.
Conforme se ha ido desarrollando el proyecto, hemos llegado a este
sexto sprint con una Historia de Usuario pendiente de una duración estimada
de 8 Puntos de Historia (8SP) y, además, hemos podido confirmar que
podemos entregar hasta 21SP.
El cliente nos ha comunicado que la funcionalidad que hemos entregado
hasta el momento se ajusta a las expectativas. Este hecho, junto al remanente
de 13SP que quedan disponibles en este último ciclo, da al cliente la
oportunidad de enriquecer el producto final con más funcionalidades que se
han ido identificado conforme se han entregando las sucesivas versiones:
En esta última reunión de planificación, el Product Owner ha
informado que le gustaría aumentar la utilidad de la herramienta
permitiendo que los datos históricos usados para el backtesting
pudieran incorporarse desde una base de datos, alojada en un
servidor propiedad del cliente, y no sólo con desde el fichero csv
con el hemos trabajado durante todo el proyecto.
Adicionalmente, habiendo observado la demo que se recoge en el
apartado 6.6.4.1, el cliente pide que el criterio de ordenación de
los escenarios pueda ser en base a otros parámetros, y no sólo el
beneficio neto. De aquí ha surgido otra Historia de Usuario.
Por último, y a la vista de la versatilidad que ofrece la
funcionalidad de que los parámetros puedan tomar valores en
listas o en rangos, pide que el StopLoss y el TakeProfit puedan
también ser optimizados de esta manera.
Por tanto, a la Historia de Usuario que quedaba pendiente, se han unido
otras tres que, si el resultado del sprint es satisfactorio y aceptado por el
cliente, habrán supuesto completar la funcionalidad completa requerida al inicio
del proyecto.
Identificamos a continuación las Historias de Usuario para el sprint 6:
114
STO020: Como cliente quiero que las simulaciones tengan en
cuenta el efecto del StopLoss y TakeProfit para generar órdenes
de salida del mercado
[nueva] STO021: Como cliente quiero poder leer datos históricos
desde una base de datos MySQL, para poder diferenciar mi
producto de otras herramientas comerciales que manejan datos
en formato estándar
[nueva] STO022: Como cliente quiero que el software calcule
indicadores de eficacia de la estrategia de trading, aparte del
beneficio neto, para poder determinar cuál es el mejor escenario
[nueva] STO023: Como cliente quiero que el StopLoss y
TakeProfit puedan tratarse como un parámetro más, admitiendo
valores en listas o en rangos, al igual que el resto de parámetros
de los indicadores para poder generar escenarios múltiples
En la siguiente imagen podemos observar el proceso de asignar
Historias del Product Backlog al sprint que se inicia. Observamos cómo en el
Product Backlog ya no quedan Historias de Usuario por entregar.
Sólo queda ahora completar toda la información que identifica
totalmente a estas Historia de Usuario:
Figura 66 Sprint 6 Backlog
115
ID
STO020DESCRIPCIONComo cliente quiero que las simulaciones tengan en cuenta el efecto del StopLoss y TakeProfit para generar órdenes de salida del mercado VALOR11ESTIMACION8SPACEPTACIONPara cada operación a corto o a largo se debe poder marcar el SL y TPEn cada iteración el simulador debe evaluar la condición de SL y TPSi se dispara la condición, debe quedar registros del momento y del beneficio obtenido
ID
STO021DESCRIPCION
Como cliente quiero poder leer
datos históricos desde una base de
datos MySQL, para poder
diferenciar mi producto de otras
herramientas comerciales que
manejan datos en formato estándarVALOR8ESTIMACION5 SPACEPTACIONPoder indicar los parámetros de conexión en el archivo de configuraciónControlar cuando no se obtenga ningún resultado, que no genere errores
ID
STO022DESCRIPCIONComo cliente quiero que el software calcula indicadores de eficacia de la estrategia de trading, aparte del beneficio neto, para poder determinar cuál es el mejor escenarioVALOR1ESTIMACION3 SPACEPTACIONPermitir tener varios indicadores, no sólo el beneficioPoder ordenar por cualquiera de ellosPoder conocer los parámetros usados en cada iteación
ID
STO023DESCRIPCIONComo cliente quiero que el StopLoss y TakeProfit puedan calcularse como un parámetro más, admitiendo valores en listas o en rangos, al igual que el resto de parámetros de los indicadores para poder generar escenarios múltiplesVALOR5ESTIMACION3 SPACEPTACIONPoder considerar a SLy TP como un parámetro más, con valores discretos o en listas/rangoAlmacenar los valores que toman en cada iteración
Tabla 14 Sprint 6 Tareas
Un análisis detallado por parte del Equipo de Desarrollo, lleva a
identificar las siguientes tareas necesarias para desarrollar las Historias de
Usuario:
Historia de
Usuario
Tarea Descripción Horas
STO020 TSK001 Incluir en el bucle de cálculo el disparado del StopLoss y
TakeProfit, generando las órdenes de salida
10
116
STO020 TSK002 Incluir en el libro de apuntes, la salida debido a SL/TP y su
valor en beneficio/pérdida
10
STO020 TSK003 Realizas las pruebas de acuerdo a los criterios de aceptación 4
STO021 TSK001 Incluir en el archivo de configuración parámetros de conexión a
una BBDD
3
STO021 TSK002 Escribir una función similar a la que lee archivos csv, pero
desde tablas de una base de datos
10
STO021 TSK003 Realizas las pruebas de acuerdo a los criterios de aceptación 2
STO022 TSK001 Preparar espacio en las struct para alojar varios cálculos de
rendimiento
1
STO022 TSK002 Al final de cada simulación calcular todos los ratios 6
STO022 TSK003 Realizas las pruebas de acuerdo a los criterios de aceptación 2
STO023 TSK001 Modificar ficheros de configuración de los escenarios para
incluir una lista de constantes, con nombre y valor
1
STO023 TSK002 Modificar el código del analizador sintáctico para que
reconozca los nombre de las constantes
6
STO023 TSK003 Realizas las pruebas de acuerdo a los criterios de aceptación 2
Con toda esta información, actualizamos Kunagi, nuestra
herramienta de control y seguimiento del proyecto. Asignamos las Historias al
sprint y creamos las tareas dentro de cada Historia:
117
Figura 67 Sprint 6 Tablero al inicio del Sprint
6.7.2 Sprint Review
El Equipo de Desarrollo reconoce que nuevamente una tarea de
investigación, en este caso el acceso a una base de datos de MySQL ha
supuesto un ligero retraso en la implementación de una tarea. Si bien existe
una librería MySQL estándar de acceso a datos para C/C++, se ha dedicado
algo más tiempo del previsto a la configuración del acceso al servidor de
cliente. Además, para poder trabajar off-line, se ha preparado una base de
datos MySQL local para realizar más pruebas.
Una vez realizadas estas tareas, el sprint se ha desarrollado con
normalidad y los desarrollos siguientes han estado en plazo. Observamos en el
gráficos el efecto de este retraso a partir de la mitad del sprint.
118
C
Para poder reflejar en el gráfico del proyecto la inclusión de las tres
nuevas Historias de Usuario, hemos recalculado el Release Burndown Chart
con objeto de añadir los 11 Puntos de Historia, elevando el total del proyecto
desde los 102 estimados al principio, hasta los 116 conseguidos.
6.7.3 Sprint Retrospective
Como hemos venido observando durante los sucesivos Sprints, la
velocidad del equipo se ha ajustado bien a las estimaciones. El aumento
de19SP a 21SP ha sido muy efectivo y se ha podido recuperar el retraso con el
que iniciamos el sprint 1.
Figura 68 Sprint 6 Burndown Chart
Figura 69 Sprint 6 Release Burndown Chart
119
En los casos en los que alguna Historia de Usuario se ha desviado
respecto a lo previsto, siempre se ha reaccionado antes del final de la iteración,
consiguiendo entregar las funcionalidades previstas.
6.7.4 Demos
6.7.4.1 Uso de TakeProfit y StopLoss como parámetros
Observamos en primer lugar cómo se especifican estos elementos en el
archivo config. Un indicador del tipo KTE (constante) albergará todas aquéllas
variables que, sin ser parámetros de indicadores técnicos de TALib, van a
tomar valores cambiantes en las sucesivas iteraciones;
Mostramos a continuación una salida por consola donde el programa ha
leído y reconocido los parámetros, y cómo los usa (en el cálculo del Take
Profit) a la hora de realizar la siguiente operación en el mercado:
Figura 70 Sprint 6 Demo: Variables para cálculo de TP y SL
Figura 71 Sprint 6 Demo: Uso del parámetro en el cálculo del SoptLoss
120
6.7.4.2 Ejecución de las condiciones StopLoss y TakeProfit
En esta demo comprobamos que la aplicación tiene en cuenta los
valores de Stop Loss y Take Profit para generar operaciones de salida al
alcanzar los precios cierto umbral.
Vemos un log de operaciones con dos salidas por Stop Loss y una por
Take Profit:
6.7.4.3 Ratios de performance
En esta demo hemos mostrado al cliente tres ratios calculados en cada
iteración, en concreto el Profit, Profit Factor y Nº de Trades (operaciones):
Consultar el “apartado 2.1” de este TFG para la descripción de estos
ratios.
Figura 72 Sprint 6 Demo: Ejecuciones de Stop Loss y Take Profit
Figura 73 Sprint 6 Demo: Indicadores de rendimiento
121
7 Pruebas y Despliegue de la solución
7.1 Pruebas
Las metodologías de desarrollo ágil han surgido intentando generar
sistemas con alta calidad y a la vez, con una reducción y simplificación de
tareas. Bajo este enfoque, las pruebas de software han tomado un papel
crucial, dada la necesidad de realizar pequeñas liberaciones “funcionalmente”
estables, surgiendo así el testing ágil.
Mientras que en las metodologías tradicionales las actividades de
prueba normalmente no se pueden iniciar hasta que la especificación de
requisitos se encuentre completa, en el caso del testing ágil dichas tareas
quedan inmersas dentro de cada iteración.
Otra diferencia importante entre las metodologías tradicionales de
pruebas y las ágiles, es que mientras las primeras tienen como objetivo
primordial la validación del producto desarrollado, en las ágiles tiene gran peso
su utilización como medio para guiar el desarrollo del software, sustituyendo así
la definición formal de requisitos.
En nuestro proyecto, al elaborar cada historia de usuario habíamos
incluido los criterios de aceptación. A continuación detallamos el plan de
pruebas que cada criterio lleva asociado:
Tabla 15 Caso de prueba 001
CP-001 El nombre del fichero debe informarse como un parámetro y debe
verificarse que existe en el directorio de la aplicación
Usuario Cliente
Historia de
Usuario STO001
Prerrequisitos Debemos tener en el directorio de la aplicación el archivo config.cfg, o bien, el que
hayamos informado como argumento en la llamada a trading.exe
Descripción Incluir en config.cfg la línea inputDataFile =”xxxxxxx” y lanzar la aplicación trading.exe
Resultado
esperado Informar con un mensaje de error si el fichero no existe en el directorio de la aplicación
Probador José Carlos Cano
122
Tabla 16 Caso de prueba 002
CP-002 Comprobar que los datos del fichero de históricos tiene el formato
esperado
Usuario Cliente
Historia de
Usuario STO001
Prerrequisitos El fichero de configuración y el de datos históricos deben existir en el directorio de la
aplicación
Descripción Incluir en config.cfg la sección columnsInDataFile, conteniendo una lista de nombres
de campo y tipo de datos (d:date, t:time, f:float) y lanzar la aplicación
Resultado
esperado
El software abrirá el fichero y leerá todas las líneas del mismo, verificando que existen
el mismo número de columnas de entrada, y con el mismo formato, que el informado en
la sección columnsInDataFile. Mostrar un mensaje en caso de error o, por el contrario,
el número de líneas leídas en caso de éxito
Probador José Carlos Cano
Tabla 17 Caso de prueba 003
CP-003 El software debe poder recorrer los archivos de escenario y validar
su sintaxis
Usuario Cliente
Historia de
Usuario STO004
Prerrequisitos El fichero de configuración general config.cfg y el fichero de datos históricos existen en
el directorio de la aplicación
Descripción Situamos en el directorio de la aplicación los ficheros de los escenarios en formato:
scenarioXXXX.cfg y lanzamos trading.exe
Resultado
esperado
El sistema debe efectuar un recorrido por todos los ficheros con nombre
scenarioXXXXX.cfg, y abrirlos por medio de la librería libconfig, mostrando un error en
caso de que se encuentre un error en la sintaxis.
Probador José Carlos Cano
123
Tabla 18 Caso de prueba 004
CP-004 El software debe incorporar en memoria la información contenida
en los ficheros de escenarios
Usuario Cliente
Historia de
Usuario STO004
Prerrequisitos El fichero de configuración general config.cfg y el fichero de datos históricos existen en
el directorio de la aplicación
Descripción Situamos en el directorio de la aplicación los ficheros de los escenarios en formato:
scenarioXXXX.cfg y lanzamos trading.exe
Resultado
esperado
Cada vez que se abre y lee un fichero scenarioXXXXX.cfg por medio de la librería
libconfig, el sistema almacena su contenido en estructuras de datos en memoria,
informando si falta alguna sección requerida
Probador José Carlos Cano
Tabla 19 Caso de prueba 005
CP-005 El software genera un gráfico en formato png
Usuario Cliente
Historia de
Usuario STO010
Prerrequisitos
Existen en el directorio de la aplicación los ficheros de los escenarios en formato:
scenarioXXXX.cfg y se ha incluído en config.cfg la sección outputFolder, para indicar
dónde se deben generar las imágenes
Descripción Colocar un archivo con extensión .py (scripts de Python) en el directorio de la aplicación
y ejecutar
Resultado
esperado
Si la sintaxis del script es correcta, en el directorio indicado por outputFolder se
encuentra una imagen en formato png, o se captura un error si el script tiene sintaxis
incorrecta o no se puede acceder a la ruta en disco especificada
Probador José Carlos Cano
124
Tabla 20 Caso de prueba 006
CP-006 Manejar dinámicamente memoria controlando en todo momento
errores de asignación
Usuario Cliente
Historia de
Usuario STO003
Prerrequisitos El fichero de configuración general config.cfg y el fichero de datos históricos existen en
el directorio de la aplicación
Descripción Crear dos archivos de datos, con volumen diferente de información y lanzarlo en
ejecuciones separadas
Resultado
esperado
En cada ejecución el sistema lee el archivo y almacena los datos en memoria, haciendo
llamadas al sistema operativo para reservar memoria. Muestra las tres últimas líneas
almacenadas en la memoria interna para comprobar su integridad. Intercepta y muestra
un error en caso de fallo de memoria
Probador José Carlos Cano
Tabla 21 Caso de prueba 007
CP-007 Controlar crecimiento de uso de memoria reutilizando espacio ya
reservado
Usuario Cliente
Historia de
Usuario STO003
Prerrequisitos El fichero de configuración general config.cfg y el fichero de datos históricos existen en
el directorio de la aplicación
Descripción Crear dos ficheros de escenarios, scenario1.cfg y scenario2.cfg. El primero contiene 3
indicadores y el segundo contiene 2 indicadores y lanzar la aplicación
Resultado
esperado
El sistema lee el archivo de datos y almacena la información en memoria. A
continuación lee el primer escenario y reserva espacio para tres indicadores. Al leer el
segundo escenario no reserva memoria, sino que reutiliza el espacio de dos de los
indicadores de la anterior ejecución, inicializando a -1 el tercero. El sistema muestra el
contenido del último registro de los tres indicadores (el último mostrará -1) para
comprobar la integridad de los datos
Probador José Carlos Cano
125
Tabla 22 Caso de prueba 008
CP-008 El sistema calculará el lapso de tiempo entre dos datos leídos del
archivo de históricos
Usuario Cliente
Historia de
Usuario STO002
Prerrequisitos El fichero de configuración general config.cfg y el fichero de datos históricos existen en
el directorio de la aplicación
Descripción
Crear tres archivos de datos, dos de ellos con intervalo de tiempos diferentes (5 minutos
y 1 día) y el tercero con formato erróneo en el campo de fecha, y lanzarlos en
ejecuciones separadas
Resultado
esperado
El sistema lee el archivo de datos y almacena la información en memoria. A
continuación calcula el intervalo de tiempo y lo muestra junto al número de líneas
leídas. En caso de formato de fecha errónea, intercepta y muestra el error
Probador José Carlos Cano
Tabla 23 Caso de prueba 009
CP-009 El sistema generará un archivo csv conteniendo los datos
históricos y los indicadores calculados
Usuario Cliente
Historia de
Usuario STO012
Prerrequisitos El fichero de configuración general config.cfg y el fichero de datos históricos existen en
el directorio de la aplicación.
Descripción Crear dos archivos de datos, con volumen diferente de información, y lanzarlo en
ejecuciones separadas para comprobar la escritura a ficheros en las dos situaciones
Resultado
esperado
El sistema lee el archivo de datos y almacena la información en memoria. El sistema
simula el cálculo de indicadores reservando un espacio con números aleatorios. El
sistema vuelca toda la memoria a un archivo con formato separado por comas.
Intercepta y muestra error de manejo de ficheros en caso de producirse.
Probador José Carlos Cano
126
Tabla 24 Caso de prueba 010
CP-010 El sistema leerá un archivo de configuración y lo almacenará en
una estructura en memoria
Usuario Cliente
Historia de
Usuario STO005
Prerrequisitos El fichero de configuración general config.cfg y el fichero de datos históricos existen en
el directorio de la aplicación
Descripción Situamos en el directorio de la aplicación un fichero de configuración con el nombre
functions.cfg y lanzamos trading.exe
Resultado
esperado
El sistema debe abrir el archivo functions.cfg, y leerlo por medio de la librería libconfig,
almacenando la información en una estructura en memoria. Mostrará un error en caso
de que la sintaxis no sea correcta, o un volcado por consola de la información
almacenada.
Probador José Carlos Cano
Tabla 25 Caso de prueba 011
CP-011 Queremos configurar la creación de gráficos de manera que se
generen sin necesidad de crear un script estático
Usuario Cliente
Historia de
Usuario STO011
Prerrequisitos El fichero de configuración general config.cfg y el fichero de datos históricos existen en
el directorio de la aplicación
Descripción Crearemos un array en memoria con instrucciones Python de prueba para generar un
gráfico de ejemplo (función seno)
Resultado
esperado
El sistema debe generar un archivo png con la función seno
El sistema recogerá un error en caso de que alguna instrucción no se pueda ejecutar o
falte algún componente
Probador José Carlos Cano
127
Tabla 26 Caso de prueba 012
CP-012 Queremos configurar la apariencia de los gráficos
Usuario Cliente
Historia de
Usuario STO013
Prerrequisitos El fichero de configuración general config.cfg y el fichero de datos históricos existen en
el directorio de la aplicación
Descripción
Situamos en el directorio de la aplicación los ficheros de los escenarios en formato:
Nunca destruimos o eliminamos columnas. Si en el próximo escenario
se usan menos indicadores, ese espacio queda en desuso pero disponible para
próximos escenarios donde puedan haber más indicadores. De este manera no
desfragmentamos memoria.
Vemos en la siguiente figura cómo la estructura de datos (que
representa una matriz bidimensional), crece inicialmente con la incorporación
de los datos históricos y, durante el proceso de cálculos, cada vez que
necesitamos espacio para un nuevo indicador.
Figura 75 Espacio para un nuevo indicador
Figura 76 Crecimiento bidimensional de la tabla de datos
148
10.1.3 Datos de configuración y control del proceso
Con este mismo diseño, disponemos de estructuras donde
almacenamos la información que nos viene de los archivos de configuración y
de los escenarios. Mostramos a continuación las más relevantes:
Form
ato
de
l
fichero
de e
ntr
ad
a typedef struct FileFormat
{ unsigned int nbData; /* number of elements in the arrays */ unsigned int nbNumeric; /* number of numeric columns */ char** fieldName; /* char(20) */ char** fieldFormat; /* char(2) */ float* fieldIndex; /* float */ } FileFormat;
Form
ato
de
l grá
fico
typedef struct GraphFormat { unsigned int nbData; /* number of elements in the arrays */ unsigned int nbWindows; /* number of windows in the chart */ unsigned int width; /* image width */ unsigned int height; /* image height */ unsigned int fontSize;/* image height */ char** variableName; /* char(20) */ char** chartWindow; /* char(1) */ char** chartType; /* char(20) */ char** variableLabel; /* char(20) */ char** variableColor; /* char(20) */ int* chartWindowLevel2; float* variableIndex; /* Index in HistData */ } GraphFormat;
typedef struct ParametersList { char* parameterName; /* char(20) */ unsigned int nbValues; /* Number of possible values for the parameter in the case of values list */ char** parameterValueList; /* char(20) (for input parameters) several values possible (but only one for output) */ float* inputParameterIndex; /* float (for input parameters). Each value has an index. Index of existing variable in table of data. */ float parameterIndex; /* float (for output parameters).Index of existing variable in table of data. */ char* parameterDirection; /* char(1) */ char* parameterFormat; /* char(2) */ float parameterRangeFrom; /* float (for input parameters). For loops. */ float parameterRangeTo; /* float (for input parameters). For loops. */ float parameterRangeStep; /* float (for input parameters). For loops. */ unsigned int nbSteps; /* Number of steps in the case of RangeFrom RangeTo RangeStep loop */ unsigned int parameterID; /* Unique ID used in the loop recursive algorithm */ } ParametersList; typedef struct IndicatorsList { unsigned int nbData; /* number of elements in the arrays */ unsigned int nbNumeric; /* number of numeric output parameters -> results will be saved in datatable */ unsigned int nbAll; /* number of all parameters */ char** indicatorName; /* char(20) */ char** functionName; /* char(20) */ float* nbParameters; /* number of params for each indicator */ ParametersList **parList; /* parameters for each indicator */ } IndicatorsList;
150
Regis
tro e
n m
em
oria
de
l re
sultad
o d
e c
ada
escenari
o,
el va
lor
de los p
ará
metr
os u
sados y
el h
istó
rico d
e o
pera
cio
nes d
e
entr
ad
a y
salid
a d
el m
erc
ado
typedef struct operationsHist { unsigned int operationTime; /* index in the big matrix */ unsigned int exitTime; /* index in the big matrix */ int closeReason; /* 0: rules 1: SL 2: TP */ int operationStatus; /* 0:open / 1:closed */ int operationType; /* 1:buy / 2:sell */ float operationVolume; /* Quantitative information regarding the operation */ float operationPrice; /* operation price */ float exitPrice; /* closure price */ float StopLoss; /* Stop Loss price */ float takeProfit; /* Take Profit price */ float profit; /* result of the operation */ float balance; /* current balance */ } operationsHist;
//------------------------------------------------------------------------------//Matrix to store the different parameter values in each execution loop together //with the result //------------------------------------------------------------------------------typedef struct histLoopParameterValues { unsigned int nbData; /* number of loops executed --> number of records */ parameterCurrentValues **loopHist; operationsHist **loopOperations; char** scenarioName; float* loopValues; /* number of parameterCurrentValues for each loop */ float* loopOperationValues; /* number of buy/sell operations for each loop */ float* loopResult; /* profit of the simulation, used to compare how good the scenario is */ float* loopDrawDown; /* profit of the simulation, used to compare how good the scenario is */ float* loopProfitFactor; /* profit of the simulation, used to compare how good the scenario is */ float* loopSharpe; /* profit of the simulation, used to compare how good the scenario is */ float* loopNofTrades; /* profit of the simulation, used to compare how good the scenario is */ float* loopRecFactor; /* profit of the simulation, used to compare how good the scenario is */ char** loopStartTime; char** loopEndTime; float* loopDuration; float* loopRetCode; float* loopOrder; /* Based on loopResult, indicates the sorted order */ } histLoopParameterValues;
151
10.2 Proceso
Una vez tenemos en memoria toda la información, el bucle de ejecución
consiste en un recorrido por los archivos de escenarios que se encuentran en
el directorio de la aplicación. En la siguiente imagen se recogen las 5 etapas
que lo componen:
Es en el paso 4 donde se identifican y deciden las operaciones de
entrada y salida del mercado, en función del valor que nos devuelven las
fórmulas de posición alcista/bajista o de alcance del umbral del Stop Loss /
Take Profit.
Figura 77 Bucle principal de la aplicación
152
10.3 Módulos
El software está compuesto por los siguientes módulos:
main:
o Lee los parámetros generales informados en config.cfg
(configuración general de la aplicación)
o Abre el archivo LOG en caso de ser necesario
o Lee el archivo functions.cfg
o Lee la estructura del fichero de entrada informado en
config.cfg
o Llama a la lectura de los datos históricos, bien desde un
archivo, o desde una base de datos MySQL
o Busca los archivos scenario___.cfg y efectúa una llamada
a la ejecución del escenario para cada uno de ellos
o Ordena todos los escenarios para mostrar los de mejor
resultado
o Libera memoria y cierra el programa
scripts:
o Lee la definición de constantes del fichero del escenario
o Lee los indicadores técnicos a usar del fichero del
escenario
o Lee las fórmulas que definen el algoritmo de trading
o Lee la definición de los gráficos
o Redimensiona la matriz de datos para poder acoger a
todos los indicadores especificados
o Llama al proceso de simulación
o Ejecuta una ordenación para mostrar los escenarios
ordenados de mayor a menor profit
o Genera un gráfico, un log de operaciones y un archivo csv
en el caso de que se solicitase para n escenarios
filesystem:
o Contiene las funciones de acceso a disco: crear archivos,
borrar archivos, escribir en archivos
153
o Contiene las funciones que leen los datos que vienen en
los archivos de configuración (mediante llamadas a
libconfig)
o Contiene las funciones que leen datos de archivos csv
o Contiene las funciones que leen los datos del archivo de
datos históricos desde MySQL
trading:
o Ejecuta la simulación
o Almacena durante el proceso los valores de los parámetros
usados, y el resultado obtenido con cada uno de ellos
o Genera un gráfico, un log de operaciones y un archivo csv
en el caso de que se solicite para todos los escenarios
parse:
o Ejecuta el análisis sintáctico de las fórmulas
o Sustituye las variables por los valores que tienen en cada
momento y calcula el resultado de las fórmulas
graph:
o Contiene la creación de sentencias para llamar a matplotlib
utils:
o Contiene el algoritmo de ordenación por el método de la
burbuja
o Contiene funciones de validación de tipos de datos, de
máximos y mínimos, y para concatenar cadenas de texto
o Contiene funciones que crean la información para el LOG
sobre los escenarios, en formato tabular
error:
o Contiene la función que relaciona un número de error con
su descripción
memory:
o Contiene las funciones que redimensionan arrays en
memoria
El proceso completo de trading, con las llamadas a los distintos módulos
está descrito en la siguiente imagen:
154
Figura 78 Módulos de la aplicación
155
11 Anexo II Manual de Usuario
La aplicación “Trading” se ha diseñada para ejecutarse como un
proceso, sin interfaz de usuario, dando prioridad a la velocidad de ejecución.
Por tanto, tanto la entrada de datos como la salida se hacen a través de
ficheros de texto, con una determinada sintaxis que se describe en este
capítulo.
11.1 Introducción
En la siguiente imagen observamos los procesos implicados durante la
ejecución del software:
1. Partiendo de un conjunto de datos históricos (de un archivo csv o
de una base datos), se seleccionan las columnas que hayamos
especificado en un archivo de configuración.
2. Partiendo de estos datos, podemos realizar una selección
filtrando por fecha para quedarnos con el período de estudio que
interese.
Figura 79 Esquema general aplicación “Trading”
156
3. Sobre el conjunto de datos final se realizarán las estrategias de
trading que se describen en los archivos de configuración de
escenarios. Cada escenario trabaja usando indicadores técnicos
cuyos parámetros de cálculo pueden adoptar múltiples valores,
con lo que cada ejecución supone, en realidad, varias iteraciones.
4. Los resultados de cada escenario son almacenados, de manera
que se ofrece una lista ordenada en función de cualquier ratio
disponible
5. Se genera un LOG de ejecución, gráficos configurables y
documentos con las operaciones de entrada/salida del mercado
11.2 Preparando la ejecución
El control de la ejecución de la aplicación la gestiona un fichero de
configuración general. En este fichero se informa, por ejemplo, de la fuente de
los datos históricos sobre los que se realizará el backtesting de las estrategias
de trading.
A continuación podemos ver en detalle la información contenida en dicho
archivo:
Figura 80 Configuración general de la aplicación
157
Tabla 45 Parámetros aplicables en la configuración general
Parámetro
Descripción Ejemplo
logFile Nombre del fichero donde se almacenará
información sobre el proceso de ejecución:
tiempos consumidos, resultados obtenidos y
errores
logFile = "LOG.txt";
Si no se informa nombre de fichero, no se
generará el log
logFile = "";
outputFolder Directorio, a partir del directorio de la
aplicación, donde se generarán los gráficos y
el resto de outputs
outputFolder = "output";
outputGraphMode Especifica qué gráficos en formato png se
generarán. Puede tomar los siguientes
valores:
-1: no genera ningún gráfico
0: genera un gráficos para cada iteración
n: genera los gráficos de los n mejores
escenarios
outputGraphMode= -1;
outputCSVMode Especifica qué ficheros de datos en formato
csv (históricos e indicadores) se generarán.
Puede tomar los siguientes valores:
-1: no genera ningún archivo
0: genera un archivo para cada iteración
n: genera los archivos de los n mejores
escenarios
outputOpBookMode= -1;
outputOpBookMode Especifica qué ficheros de log de operaciones
de compra/venta se generarán en formato txt.
Puede tomar los siguientes valores:
-1: no genera ningún archivo
0: genera un archivo para cada iteración
n: genera los archivos de los n mejores
escenarios
En caso de seleccionar -1, tampoco se
mostrará información de las operaciones en
el archivo de LOG ni por consola
outputOpBookMode= -1;
maxRunningTime Especifica el número de segundos máximo de
ejecución del programa.
0 indica que no hay límite
maxRunningTime = 0;
maxLoopsNumber Especifica el número máximo de iteraciones
que ejecutará el programa
0 indica que no hay límite
maxLoopsNumber = 80;
maxNumData Especifica el número máximo de datos que se
leerán de un archivo o de una base de datos
0 indica que no hay límite
maxNumData = 0;
inputDataFile Especifica el nombre del fichero csv que
contiene los datos históricos
El fichero debe situarse en el directorio de la
aplicación
Si se informa en blanco, no se leerá ningún
archivo, y se deberá informar la base de
datos desde la que importar la información
histórica
inputDataFile= "EURUSD5.csv";
158
filterByColumn Este parámetro indica si se filtrará por alguna
columna (en el caso de haberse informado el
dato inputDataFile,)
-1 indica que no habrá filtros
filterByColumn = 1
filterFrom Si filterByColumn no es -1 y se ha informado
inputDataFile, este parámetro contiene el
valor “desde”
filterFrom = "2013.02.18";
filterTo Si filterByColumn no es -1 y se ha informado
inputDataFile, este parámetro contiene el
valor “hasta”
filterTo = "2013.02.19";
inputSQLServer Especifica el nombre del servidor MySQL inputSQLServer="192.168.1.34";
inputSQLDatabase Especifica la base de datos que contiene los
datos históricos
inputSQLDatabase = "trading";
inputSQLUser Especifica el usuario que tiene permisos para
ejecutar la consulta
inputSQLUser = "test";
inputSQLPassword Especifica la clave del usuario que tiene
permisos para ejecutar la consulta
inputSQLPassword = "test";
inputSQLQuery Consulta a ejecutar contra la base de datos select […] from
trading.indice_data where […]
columnsInDataFile Especifica las columnas de datos (nombre y
formato) que se esperan recibir en el fichero
csv o en la consulta contra la base de datos
El formato puede tomar estos valores:
d: fecha (date)
t: hora (time)
f: numérico (float)
columnsInDataFile = (
{columnName = "operationDate";
columnFormat="d" },
{columnName = "operationTime";
columnFormat="t" },
{columnName = "openPrice";
columnFormat="f" },
{columnName = "highPrice";
columnFormat="f" },
{columnName = "lowPrice";
columnFormat="f" },
{columnName = "closurePrice";
columnFormat="f" },
{columnName = "volume";
columnFormat="f" }
);
En la figura siguiente vemos un ejemplo del contenido de un archivo de
configuración típico:
159
Figura 81 Ejemplo de archivo de configuración general
A la hora de lanzar la aplicación, podemos añadir un argumento con el
nombre que hayamos dado al archivo de configuración. En caso de no añadir
este argumento, el programa usará el valor por defecto “config.cfg”.
El archivo de configuración debe estar localizado en el directorio de la
aplicación. En caso de no encontrarse, se informará del error.
11.3 Indicadores técnicos
La aplicación “trading” hace uso de la librería TA-Lib, que ofrece el
cálculo de hasta 200 indicadores técnicos y un interface para aplicaciones
desarrolladas en C/C++ y Java. Este interface, y toda la lista de funciones con
sus parámetros, pueden encontrarse en el archivo de cabecera ta_func.h, en el
directorio de instalación de TA-Lib.
Dado el gran número de indicadores disponibles, y con objeto de facilitar
su lectura, hemos creado un archivo donde recogeremos sólo los indicadores
que podremos usar en nuestra aplicación. Posteriormente, durante la
ejecución, se mapearán las llamadas a los indicadores contra las definiciones
incluidas en este archivo, cuyo nombre debe ser obligatoriamente
“functions.cfg”.
160
El contenido de este archivo tiene como raíz un parámetro functions
que contiene una lista de indicadores y sus parámetros, como se describe a
continuación:
Tabla 46 Parámetros aplicable a la lista de indicadores
Parámetro
Descripción Ejemplo
functionName Es el nombre de indicador técnico en
TALib
functionName = "MACD";
functionParameters Es, a su vez, una lista de elementos,
que serán los parámetros de llamada a
la función, con los siguientes campos:
Name, o nombre del parámetro functionParameters = (
{Name="startIdx";
Direction="i";
Type="i";
Optional=0;},
{Name="endIdx";
Direction="i";
Type="i";
Optional=0;},
…);
Direction, que puede tomar los
valores:
i: (input) parámetro de entrada
o: (output) parámetro de salida
Type, que puede tomar los valores:
i: (integer) un número entero
f (float) un número decimal
Mi: matriz de números enteros
Mf: matriz de números decimales
s: (string) un texto
Optional, que puede tomar los valores:
0: es obligatorio
1: es opcional
Podemos ver a continuación un ejemplo de archivo con dos indicadores:
Figura 82 Ejemplo de listado de indicadores
161
Para usar un nuevo indicador basta con incluirlo en este archivo,
copiando la definición que figura en la cabecera ta_func.h.
11.4 Definiendo los escenarios
El núcleo de esta aplicación radica en la ejecución de escenarios de
trading. Se pueden definir múltiples escenarios, cada uno de ellos descrito en
detalle en archivos de texto cuyos nombres tendrán la siguiente nomenclatura:
Por ejemplo, scenario1.cfg, scenario002.cfg, scenario1530.cfg
En estos archivos se reflejan los indicadores técnicos a utilizar en las
simulaciones, las reglas que determinan las entradas/salidas del mercado y el
tipo de gráficos que se generarán.
A continuación detallamos la información contenida en dichos archivos.
11.4.1 Indicadores técnicos
Debemos definir qué indicadores técnicos vamos a necesitar en cada
escenario. Estos indicadores los usaremos en nuestras fórmulas para decidir
los momentos alcistas y bajistas del mercado, y ayudarán a decidir los
momentos de entrada y salida. Se muestran a continuación los parámetros
necesarios para definirlos correctamente:
Tabla 47 Escenarios (1/5): indicadores técnicos
Parámetro
Descripción Ejemplo
scriptName Texto libre que describe el escenarios scriptName = "First";
technicalIndicators Lista que contendrá los indicadores
técnicos que son necesarios en este
escenario. Contiene los siguientes
campos:
indicatorName, texto libre que
describe el indicador
indicatorName = "MA90";
functionName, nombre de la función
en TA-Lib. Debe coincidir con algunos
de los parámetros functionName del
fichero functions.cfg
functionName = "MA";
indicatorParameters. Parámetros del
indicador. Contiene los siguientes
campos:
parameterName parameterName="startIdx";
162
parameterValue, indica un valor, o
una lista de valores separados por
comas
parameterValueRange, indica un
rango de valores, que se forman
usando el primer valor como
“desde”, el segundo como “hasta”
y el tercero como el “salto”
parameterValue=("26");
parameterValueRange=("2","3","1");
parameterDirection, que puede
tomar los valores:
i: (input) parámetro de entrada
o: (output) parámetro de salida
parameterDirection="i";
ParameterFormat que puede
tomar los valores:
i: (integer) un número entero
f (float) un número decimal
Mi: matriz de números enteros
Mf: matriz de números
decimales
s: (string) un texto
ParameterFormat="i";}
Es posible crear variables que, sin ser parámetros de indicadores
técnicos, adopten la ventaja de poder tomar valores múltiples. Para ello se
puede incluir un indicador con functionName = “KTE”, y se le añaden las
variables que necesitemos como parámetros de tipo “i” (input-entrada). A partir
de entonces ya podremos usar estas variables en nuestras fórmulas.
Vemos en esta imagen un ejemplo de definición de indicadores técnicos
para un escenario.
Figura 83 Escenarios (1/5): indicadores técnicos
Observamos el uso del indicador “KTE” para crear una variable
TakeProfit y otra StopLoss, adoptando éstas múltiples valores.
163
11.4.2 Gráficos
Definimos la configuración de los gráficos que se podrán generar
asociados a cada escenario. Podemos especificar las variables a representar
(correspondientes a un dato de entrada o a un valor calculado de un indicador)
y la apariencia del gráfico. Los parámetros necesarios son los siguientes:
Tabla 48 Escenarios (2/5): definición de gráficos
Parámetro
Descripción Ejemplo
graphicWidth Ancho en pixels del gráfico a generar graphicWidth = 1900;
graphicHeight Alto en pixels del gráfico a generar graphicHeight = 900;
graphicFontSize Tamaño de letra en el gráfico (para los
ejes, etiquetas, números)
graphicFontSize = 12;
graphicNbWindows Número de ventanas que compondrá el
gráfico que se genere
graphicNbWindows = 3;
graphicWindows Lista que contendrá el formato de cada
una de las ventanas que componen el
gráfico. Contiene los siguientes
campos:
Size Valor de 1 a 10 que indica el
tamaño relativo de la ventana. La suma
de los campos size de todas la
ventanas debe sumar 10, en caso
contrario se obtiene un error.
size=2;
AxisLabelTitle Título del eje Y de cada
ventana
AxisLabelTitle = "Test one ";
showGrid Indica si se debe mostrar la
cuadrícula en el gráfico
showGrid="true";
showXlabels Indica si se deben o no
mostrar los valores del eje X
showXlabels="false";
pruneYlabels Indica si se deben omitir
las etiquetas del eje X que solapan con
las de la ventana anexa
pruneYlabels="true"}
Figura 84 Especificación de los indicadores técnicos
164
graphicData Lista que contendrá los datos
(variables) que se mostrarán en el
gráfico. Contiene los siguientes
campos:
variableName Nombre del dato a
representar. Debe corresponder con un
nombre de campo del fichero de
entrada, o con un parámetro de salida
de un indicador técnico
variableName = "openPrice";
Window Número de la ventana donde
se mostrará la variable (la primera
ventana toma el valor 0, y es la que
muestra en la parte superior del gráfico)
window="1";
type Tipo de gráfico. Puede tomar
estos valores:
cO: precio de apertura en gráfico de
velas
cH: precio más alto en gráfico de velas
cL: precio más bajo en gráfico de velas
cC: precio de cierre en gráfico de velas
l: gráfico de línea
b: gráfico de barra
a: gráfico de área
type="b";
Label Etiqueta asociada a la variable label = "Volume";
color Color para la variable. Se puede
especificar de dos formas:
Usando el formato #aabbcc (con aa,
bb y cc números hexadecimales)
Usando un nombre de la lista
disponible en el apartado 13 de esta
memoria
color= "forestgreen"}
Vemos en esta imagen un ejemplo de definición de los gráficos
asociados a un escenario.
Figura 85 Escenarios (2/5): definición de gráficos
165
Observamos cómo la definición contenida en la sección de gráficos del
archivo de escenarios guía la búsqueda de información en el conjunto de datos
y genera un archivo csv que sirve de base para crear el gráfico:
11.4.3 Constantes
Podemos crear un número ilimitado de constantes que usaremos
posteriormente en las fórmulas, simplificando así la lectura de las mismas:
Tabla 49 Escenarios (3/5): definición de constantes
Parámetro
Descripción Ejemplo
constants Lista que contendrá constantes con un
valor que se podrán referenciar en las
fórmulas de cálculo de operaciones de
trading. Contiene los siguientes campos:
Name Nombre de la constante name = "factor";
Value Valor de la constante (debe ser
un valor float)
value=0.00001 }
Figura 87 Escenarios (3/5): definición de constantes
Hay cuatro constantes que se deben definir obligatoriamente:
Figura 86 Proceso de creación de un gráfico
166
Lots: Define el tamaño del lote (por ejemplo, 0.1)
LotsSize: Define el valor al que corresponde cada lote (por
ejemplo, un valor típico en operaciones FOREX podría ser
100000)
CloseOrders, indica si se puede cerrar una orden con tan sólo un
cambio de tendencia en el mercado:
o Un valor 0.0 (equivalente a false) indica que habrá que
esperar a una condición de StopLoss o TakeProfit para
cerrar las operaciones abiertas
o Un valor de 1.0 (equivalente a True) indica que se cerrarán
las operaciones abiertas al encontrar un cambio de
tendencia
Use_Closing_SL_TP:
o Un valor de 0.0 (equivalente a False) indica que el precio
que se usará como el de cierre de la operación será el
valor del precio de apertura de la vela del período en que
nos encontramos
o Un valor de 1.0 (equivalente a True) indica que el precio
que se usará como el de cierre de la operación será el
valor del Stop Loss o Take Profit, según el caso
11.4.4 Operaciones
Definimos las condiciones y fórmulas relacionadas con la identificación
de un momento alcista o bajista del mercado y las operaciones de entrada y
salida usando los siguientes parámetros:
Tabla 50 Escenarios (4/5): operaciones de trading
Parámetro
Descripción Ejemplo
buy Recoge toda la información relativa a
una operación alcista. Se compone de
los siguientes campos:
167
Condition Especifica la fórmula que,
de cumplirse, indica una situación
alcista del mercado. (ver siguiente
apartado para conocer más sobre el
uso de fórmulas)
condition = "(outmacd<0) & (outmacd >
outmacdsignal) &
(outmacd(1)<outmacdsignal(1)) & (
#outmacd > (3*factor)) &
(outma>outma(1))";
Formula Especifica la fórmula cuyo
resultado será el volumen invertido en
una operación “a largo”
formula="lots";
Stoploss Especifica una fórmula para
el Stop Loss
stoploss ="openprice-(StopLoss*factor)";
Takeprofit Especifica una fórmula
para el Tak Profit
takeprofit="openprice+(takeprofit*factor)";
Color Especifica un color para la
etiqueta que en el gráfico indica una
entrada en el mercado. Se puede
especificar de dos formas:
Usando el formato #aabbcc (con aa,
bb y cc números hexadecimales
Usando un nombre de la lista
disponible en el apartado 13 de esta
memoria
color="green"
sell Recoge toda la información relativa a
una operación bajista. Se compone de
los siguientes campos:
Condition Especifica la fórmula que,
de cumplirse, indica una situación
bajista del mercado. (ver siguiente
apartado para conocer más sobre las
fórmulas)
condition = "(outmacd>0) & (outmacd <
outmacdsignal) &
(outmacd(1)>outmacdsignal(1)) & (
outmacd > (3*factor)) &
(outma<outma(1))";
Formula Especifica la fórmula cuyo
resultado será el volumen invertido en
una operación “a corto”
formula="lots";
Stoploss Especifica una fórmula para
el Stop Loss
stoploss ="openprice+(StopLoss*factor)";
Takeprofit Especifica una fórmula
para el Tak Profit
takeprofit="openprice-
(TakeProfit*factor)";
Color Especifica un color para la
etiqueta que en el gráfico indica una
salida del mercado. Se puede
especificar de dos formas:
Usando el formato #aabbcc (con aa,
bb y cc números hexadecimales
Usando un nombre de la lista
disponible en el apartado 13
color="red"
Figura 88 Escenarios (4/5): operaciones de trading
168
11.4.5 Precios
Finalmente usaremos dos parámetros para especificar la variable que
contiene los precios de apertura y de cierre. Estos datos se usan habitualmente
como parámetro de entrada en el cálculo de los indicadores técnicos.
Tabla 51 Escenarios (5/5): asignación de precios
Parámetro
Descripción Ejemplo
openprice Variable que contiene el precio de
apertura
openprice = "openPrice";
closureprice Variable que contiene el precio de cierre closureprice = "openPrice";
En este último ejemplo, el programa de trading tomaría siempre como
valor del precio el de apertura de la vela (“openPrice”).
11.4.6 Uniéndolo todo
En la siguiente imagen se puede observar cómo el nombre de una
columna del archivo de datos (línea negra) declarada en config.cfg, se usa
posteriormente para calcular un indicador técnico declarado en un archivo de
escenarios, cuyo valor de salida (línea amarilla) se usa, a su vez, para
mostrarse en un gráfico o para ser parte de una fórmula que determina si el
mercado se encuentra en una situación alcista o bajista (declarada también en
un archivo de escenarios):
Figura 89 Ejemplo de relación entre variables
169
11.5 Escritura de fórmulas
Como hemos indicado en el apartado anterior, es posible especificar
fórmulas para calcular condiciones de entrada y salida del mercado, así como
el volumen de una operación, o el valor que tomarán las condiciones de Stop
Loss y Take Profit.
El analizador sintáctico incluido en el software admite las siguientes
operaciones:
Tabla 52 Operadores admitidos en fórmulas
+, -, *, / Operadores aritméticos
>, <, = Operadores lógicos
| OR
& AND
¡ NOT
# ABS
(, )
Tabla 53 Operandos admitidos en fórmulas
Números (enteros y float) Enteros y float
Nombres de variables:
parámetros de salida de indicadores técnicos
columnas del fichero (o base de datos) de entrada
constantes especificadas en los archivos de los
escenarios
Los nombre de las variables que hacen referencia a resultados del
cálculo de indicadores pueden llevar un índice, por ejemplo outmacd(n), para
hacer referencia a un dato de n períodos anteriores.
Por ejemplo, el bucle que realiza el backtesting de un juego de 200
datos, cuando evalúe la situación en el período 150, sustituirá la variable
outmacd por su valor en el momento 150. Sin embargo, cuando encuentre
outmacd(1) la sustituirá por su valor en el período 149, es decir, en el período
anterior. Cuando el período anterior se refiere a una fecha anterior a la inicial,
mantendrá el valor del período actual.
El analizador sintáctico desarrollado NO CONTEMPLA la precedencia
de operadores, por lo que cualquier orden en las operaciones que se quieran
ejecutar en primer lugar deberá ser especificado expresamente mediante el uso
de paréntesis.
170
Vemos a continuación algunos ejemplos de fórmulas válidas:
Tabla 54 Ejemplos de fórmulas
12+(34/28*2)
¡(4>2)
(precio*0.3)>(indicador-2)
Takeprofit>#variable
11.6 Ejecución
Para ejecutar la aplicación en Windows teclearemos:
trading [nombre_archivo_config]
Por ejemplo podríamos escribir trading myconfig.cfg para ejecutar
trading tomando como archivo de configuración myconfig.cfg
O podríamos escribir trading (sin argumentos) para ejecutar
tomando como entrada el archivo por defecto config.cfg
El contenido de myconfig.cfg o config.cfg debe ajustarse a lo descrito en
el apartado 11.1 de esta memoria.
Si el archivo de configuración especificado existe en el directorio de la
aplicación y contiene las secciones requeridas, comienza a buscar todos los
ficheros cuyos nombres son de la forma scenario____.cfg y procesa los
escenarios descritos en cada uno de ellos, mostrando por consola la operación
en curso:
Figura 90 Ejecución: información mostrada en la consola
171
y un resumen final con el tiempo total de ejecución y los mejores
escenarios ordenados por Profit:
Figura 91 Ejecución: resumen mostrado en la consola
A la vez crea varios ficheros, según se haya especificado así en el
(python2.7 en el momento de realización del presente TFG)
Accedemos a un terminal:
usuario@ubuntu:~$
Actualizamos los repositorios, es decir , la lista de todos los paquetes
usuario@ubuntu:~$ sudo apt-get update
usuario@ubuntu:~$ sudo apt-get install python-dev
Tras comprobar las dependencias con otros paquetes tendremos que
responder “y” al requerimiento adicional de espacio necesario para instalar este
paquete y sus dependencias:
Figura 124 Instalación de Python en Ubuntu
A partir de este momento ya tenemos el fichero “python.h” disponible
para usarlo en nuestro desarrollo en C (estará en /usr/include/python2.7)
196
Debemos tener en cuenta que los ficheros include no están por defecto en el path de include, ni la librería de Python está enlazada con el ejecutable por defecto. Necesitamos añadir los siguientes flags:
-I/usr/include/python2.7 -lpython2.7
12.1.6 Instalación de matplotlib
Es el componente necesario para crear los gráficos de velas, que forman
parte de la funcionalidad de la aplicación desarrollada.
Accedemos a un terminal:
usuario@ubuntu:~$
Actualizamos los repositorios, es decir, la lista de todos los paquetes de