Construye una aplicación de cotización de acciones: Buscar datos de acciones con YQL
() translation by (you can also view the original English article)
En esta serie de tutoriales, te enseñaré cómo crear una aplicación de cotización de acciones con Raphael JS, Titanium Mobile y el servicio web YQL de Yahoo. Los gráficos Raphael JS se usarán para presentar gráficamente la información de cotización de acciones, Titanium Mobile se usará para compilar una aplicación nativa de iOS y las tablas de datos YQL recuperarán la información de acciones.
Introducción a Yahoo YQL y Raphael JS
YQL es un lenguaje similar a SQL que te permite consultar, filtrar y combinar datos de múltiples fuentes en Yahoo! red y otras fuentes de datos abiertas. Normalmente, el acceso de los desarrolladores a los datos de varios recursos es dispar y requiere llamadas a varias API de diferentes proveedores, a menudo con diferentes formatos de alimentación. YQL elimina este problema al proporcionar un único punto final para consultar y dar forma a los datos que solicitas. En este tutorial, usaremos las tablas de datos abiertos de YQL proporcionadas por Yahoo Finance para obtener y presentar información sobre cotizaciones bursátiles.
Esta presentación de esta información es donde entran los gráficos Raphael JS. Los gráficos son la forma más fácil y lógica de presentar una línea de tiempo de datos financieros, y Titanium Mobile no viene con una API de gráficos nativa. Raphael es de código abierto y tiene licencia del MIT, y afortunadamente es muy amigable para dispositivos móviles porque está escrito en JavaScript estándar, mantiene una huella de procesamiento baja y en realidad se procesa en formato SVG, lo que significa que se puede cambiar de tamaño fácilmente para adaptarse a cualquier pantalla móvil sin una disminución en la calidad de la imagen!
Vista previa final de la aplicación
La siguiente es una vista previa de la aplicación que crearemos en esta serie:



Paso 1: Crea un nuevo proyecto
Abre Titanium Developer y crea un nuevo proyecto. Puedes darle al proyecto el nombre que quieras, pero usaré el título "StockQuotes" para simplificar. Ahora es un buen momento para descargar también los archivos fuente para este proyecto. Descarga y descomprime los archivos del proyecto adjuntos a esta publicación y copia la carpeta "images" en el directorio "Resources" de tu nuevo proyecto Titanium. De forma predeterminada, Titanium también incluye dos archivos de iconos en la raíz de tu directorio "Resources" llamados KS_nav_ui.png y KS_nav_views.png; no los necesitamos, así que adelante y mueve ambos a la papelera.
Paso 2: Crear la interfaz básica
Abre el archivo app.js, en la raíz de tu directorio "Resources", en tu editor favorito. No necesitamos ninguno de los códigos generados automáticamente, así que elimínalo todo y reemplázalo con lo siguiente:
1 |
// This sets the background color of the master UIView |
2 |
Titanium.UI.setBackgroundColor('#000'); |
3 |
|
4 |
// Create the application window |
5 |
var win1 = Titanium.UI.createWindow({ |
6 |
backgroundImage: 'images/background.png' |
7 |
}); |
8 |
|
9 |
// Create the title label for our app |
10 |
var titleLabel = Titanium.UI.createLabel({ |
11 |
text: 'Search Quotes', |
12 |
color: '#fff', |
13 |
height: 20, |
14 |
width: 320, |
15 |
top: 6, |
16 |
textAlign: 'center', |
17 |
font: {fontSize: 15, fontFamily: 'Helvetica', fontWeight: 'bold'} |
18 |
}); |
19 |
win1.add(titleLabel); |
20 |
|
21 |
//Create the scroll area, all our content goes in here |
22 |
var scrollArea = Titanium.UI.createScrollView({ |
23 |
top: 40, |
24 |
width: 320, |
25 |
height: 420, |
26 |
contentHeight: 'auto' |
27 |
}); |
28 |
|
29 |
// Create the stock quote search box |
30 |
var searchBox = Titanium.UI.createView({ |
31 |
width: 300, |
32 |
left: 10, |
33 |
top: 10, |
34 |
height: 50, |
35 |
borderRadius: 5, |
36 |
backgroundImage: 'images/gradient-small.png' |
37 |
}); |
38 |
|
39 |
scrollArea.add(searchBox); |
40 |
|
41 |
// Create the quote information box |
42 |
var quoteInfoBox = Titanium.UI.createView({ |
43 |
width: 300, |
44 |
left: 10, |
45 |
top: 70, |
46 |
height: 200, |
47 |
borderRadius: 5, |
48 |
backgroundImage: 'images/gradient.png' |
49 |
}); |
50 |
|
51 |
scrollArea.add(quoteInfoBox); |
52 |
|
53 |
// Create the quote chart box |
54 |
var quoteChartBox = Titanium.UI.createView({ |
55 |
width: 300, |
56 |
left: 10, |
57 |
top: 280, |
58 |
height: 300, |
59 |
borderRadius: 5, |
60 |
backgroundImage: 'images/gradient.png' |
61 |
}); |
62 |
|
63 |
scrollArea.add(quoteChartBox); |
64 |
|
65 |
// This small view just adds 10px of padding to the bottom of |
66 |
// our scrollview (scrollArea) |
67 |
var emptyView = Titanium.UI.createView({ |
68 |
height: 10, |
69 |
top: 580 |
70 |
}); |
71 |
|
72 |
scrollArea.add(emptyView); |
73 |
|
74 |
// Add the scrollview to the window |
75 |
win1.add(scrollArea); |
76 |
|
77 |
// Open the window |
78 |
win1.open(); |
Lo que hemos hecho anteriormente es crear un shell básico con un estilo agradable para nuestra aplicación. Hay un espacio en la parte superior para crear un campo de búsqueda y dos casillas vacías más para colocar nuestra información de acciones y nuestro gráfico. Todo esto se ha agregado a ScrollView para que podamos desplazarnos fácilmente por nuestra aplicación para ver cualquier información que esté oculta en los límites de la pantalla. Ejecuta tu aplicación en el emulador de iPhone y ahora debería verse como la imagen a continuación:



Paso 3: Crear el campo de búsqueda
Nuestro siguiente paso es crear el campo de texto y el botón de búsqueda que el usuario usará para interactuar con nuestra aplicación proporcionando un símbolo de acciones (por ejemplo, APPL para computadoras Apple) para buscar. Ingresa el siguiente código antes de la línea donde agregaste tu objeto searchBox
al scrollArea
(línea 39).
1 |
// This is the input textfield for our stock code |
2 |
var txtStockCode = Titanium.UI.createTextField({ |
3 |
hintText: 'Stock code, e.g. APPL', |
4 |
borderWidth: 0, |
5 |
width: 200, |
6 |
left: 10, |
7 |
height: 30, |
8 |
font: {fontSize: 14, fontColor: '#262626', fontFamily: 'Helvetica'}, |
9 |
autoCorrect: false, |
10 |
autocapitalization: Titanium.UI.TEXT_AUTOCAPITALIZATION_ALL |
11 |
}); |
12 |
|
13 |
searchBox.add(txtStockCode); |
14 |
|
15 |
// Create the search button from our search.png image |
16 |
var btnSearch = Titanium.UI.createButton({ |
17 |
backgroundImage: 'images/search.png', |
18 |
width: 80, |
19 |
height: 30, |
20 |
right: 10, |
21 |
borderRadius: 3 |
22 |
}); |
23 |
|
24 |
// Add the event listener for this button |
25 |
btnSearch.addEventListener('click', searchYQL); |
26 |
|
27 |
searchBox.add(btnSearch); |
Lo que logramos anteriormente es crear los dos componentes de entrada necesarios para que el usuario ingrese datos (una cotización de acciones en este caso) y para realizar una acción basada en esa entrada tocando el botón de búsqueda. Si aún no lo habías notado, nuestro objeto de botón btnSearch
tiene un detector de eventos que se activará cada vez que el usuario lo toque y llame a una función llamada searchYQL
. Si ejecutaras la aplicación en el emulador ahora, terminarías con una gran pantalla de error roja ya que aún no hemos creado esta función. Hagámoslo ahora.
Ingresa lo siguiente en la parte superior de tu archivo app.js, después de la línea Titanium.UI.setBackgroundColor
:
1 |
// This function is called on search button tap, it will query YQL for our stock data |
2 |
function searchYQL() { |
3 |
} |
Si aún no lo has hecho, guarda tu archivo app.js y ejecútalo en el emulador. Deberías ver una pantalla similar a la siguiente:



Paso 4: Búsqueda de cotizaciones de acciones con Yahoo YQL
Ahora, antes de buscar en YQL información sobre nuestras acciones, necesitamos crear algunas etiquetas e imágenes que irán a nuestro quoteInfoBox y presentarán la información al usuario. Este es un proceso bastante sencillo. El siguiente código debe colocarse antes de agregar quoteInfoBox
al scrollArea
en la línea 93.
1 |
// Add the labels and images we need to show some basic stock information |
2 |
var lblCompanyName = Titanium.UI.createLabel({ |
3 |
width: 280, |
4 |
height: 30, |
5 |
left: 10, |
6 |
top: 10, |
7 |
color: '#003366', |
8 |
font: {fontSize: 17, fontWeight: 'bold', fontFamily: 'Helvetica'}, |
9 |
text: 'No company selected' |
10 |
}); |
11 |
quoteInfoBox.add(lblCompanyName); |
12 |
|
13 |
var lblDaysLow = Titanium.UI.createLabel({ |
14 |
width: 280, |
15 |
height: 20, |
16 |
left: 10, |
17 |
top: 50, |
18 |
color: '#000', |
19 |
font: {fontSize: 14, fontWeight: 'bold', fontFamily: 'Helvetica'}, |
20 |
text: 'Days Low: ' |
21 |
}); |
22 |
|
23 |
quoteInfoBox.add(lblDaysLow); |
24 |
|
25 |
var lblDaysHigh = Titanium.UI.createLabel({ |
26 |
width: 280, |
27 |
height: 20, |
28 |
left: 10, |
29 |
top: 80, |
30 |
color: '#000', |
31 |
font: {fontSize: 14, fontWeight: 'bold', fontFamily: 'Helvetica'}, |
32 |
text: 'Days High: ' |
33 |
}); |
34 |
|
35 |
quoteInfoBox.add(lblDaysHigh); |
36 |
|
37 |
var lblLastOpen = Titanium.UI.createLabel({ |
38 |
width: 280, |
39 |
height: 20, |
40 |
left: 10, |
41 |
top: 110, |
42 |
color: '#000', |
43 |
font: {fontSize: 14, fontWeight: 'bold', fontFamily: 'Helvetica'}, |
44 |
text: 'Last Open: ' |
45 |
}); |
46 |
|
47 |
quoteInfoBox.add(lblLastOpen); |
48 |
|
49 |
var lblLastClose = Titanium.UI.createLabel({ |
50 |
width: 280, |
51 |
height: 20, |
52 |
left: 10, |
53 |
top: 140, |
54 |
color: '#000', |
55 |
font: {fontSize: 14, fontWeight: 'bold', fontFamily: 'Helvetica'}, |
56 |
text: 'Last Close: ' |
57 |
}); |
58 |
|
59 |
quoteInfoBox.add(lblLastClose); |
60 |
|
61 |
var lblVolume = Titanium.UI.createLabel({ |
62 |
width: 280, |
63 |
height: 20, |
64 |
left: 10, |
65 |
top: 170, |
66 |
color: '#000', |
67 |
font: {fontSize: 14, fontWeight: 'bold', fontFamily: 'Helvetica'}, |
68 |
text: 'Volume: ' |
69 |
}); |
70 |
|
71 |
quoteInfoBox.add(lblVolume); |
Una vez que se hayan agregado tus etiquetas y nuestra flecha de imagen de movimiento de stock, deberías poder ejecutar el emulador y terminar con una pantalla como esta:



Ahora hagamos algo útil con este diseño y rellénalo con datos de stock de Yahoo!. Para hacer eso, necesitamos expandir nuestra función searchYQL() vacía y realizar una búsqueda en las tablas de datos financieros de Yahoo YQL usando una combinación de sintaxis YQL y el método Titanium.Yahoo.yql() de Titanium.
1 |
// This function is called on search button tap. It will query YQL for our stock data |
2 |
function searchYQL() { |
3 |
|
4 |
// Do some basic validation to ensure the user has entered a stock code value |
5 |
if(txtStockCode.value != '') |
6 |
{ |
7 |
txtStockCode.blur(); //hides the keyboard |
8 |
|
9 |
// Create the query string using a combination of YQL syntax and the value of the txtStockCode field |
10 |
var query = 'select * from yahoo.finance.quotes where symbol = "' + txtStockCode.value + '"'; |
11 |
|
12 |
// Execute the query and get the results |
13 |
Titanium.Yahoo.yql(query, function(e) { |
14 |
var data = e.data; |
15 |
|
16 |
// Iff ErrorIndicationreturnedforsymbolchangedinvalid is null then we found a valid stock |
17 |
if(data.quote.ErrorIndicationreturnedforsymbolchangedinvalid == null) |
18 |
{ |
19 |
//we have some data! let's assign it to our labels etc |
20 |
lblCompanyName.text = data.quote.Name; |
21 |
lblDaysLow.text = 'Days Low: ' + data.quote.DaysLow; |
22 |
lblDaysHigh.text = 'Days High: ' + data.quote.DaysHigh; |
23 |
lblLastOpen.text = 'Last Open: ' + data.quote.Open; |
24 |
lblLastClose.text = 'Last Close: ' + data.quote.PreviousClose; |
25 |
lblVolume.text = 'Volume: ' + data.quote.Volume; |
26 |
lblPercentChange.text = data.quote.PercentChange; |
27 |
|
28 |
//if the previous close was equal or higher than the opening price, the |
29 |
//stock direction is up... otherwise it went down! |
30 |
if(data.quote.PreviousClose >= data.quote.Open) { |
31 |
imgStockDirection.image = 'images/arrow-up.png'; |
32 |
} |
33 |
else { |
34 |
imgStockDirection.image = 'images/arrow-down.png'; |
35 |
} |
36 |
|
37 |
} |
38 |
else |
39 |
{ |
40 |
//show an alert dialog saying nothing could be found |
41 |
alert('No stock information could be found for ' + txtStockCode.value + '!'); |
42 |
} |
43 |
}); |
44 |
} |
45 |
else |
46 |
{ |
47 |
alert('You must provide a stock code to search upon, e.g. AAPL or YHOO'); |
48 |
} |
49 |
} |
Entonces, ¿qué está sucediendo realmente aquí dentro de la función searchYQL()
? Primero, estamos haciendo una validación muy básica en el campo de texto para asegurarnos de que el usuario haya ingresado una cotización de acciones antes de presionar buscar. Si se encuentra una cotización de acciones, usamos el método blur()
del campo de texto para asegurarnos de que el teclado quede oculto. La esencia del código gira en torno a la creación de una consulta de Yahoo YQL utilizando la sintaxis correcta y proporcionando el valor del campo de texto como parámetro de símbolo. Esta consulta YQL es simplemente una cadena, unida con el símbolo + de la misma forma que lo harías con cualquier otra manipulación de cadenas en JavaScript. Luego ejecutamos nuestra consulta usando el método Titanium.Yahoo.yql()
, que devuelve los resultados dentro del objeto 'e' de la función en línea.
Los datos dentro del objeto 'e' son simplemente JSON, un formato de datos rápido y común que se está volviendo ubicuo en la web y con todas las API principales. El uso de estos datos es una simple notación de puntos. En nuestro código, primero verificamos la propiedad llamada data.quote.ErrorIndicationreturnedforsymbolchangedinvalid para asegurarnos de que el símbolo que ingresó el usuario era un código de stock válido. Si es así, ¡podemos asignar todos los valores a nuestras etiquetas! Por último, verificamos si el precio de las acciones cerró más alto de lo que abrió, si es así, podemos establecer la imagen del movimiento de las acciones en una flecha verde "hacia arriba", lo que indica que su valor aumentó. Si bajó de valor, podemos mover la imagen a una flecha roja "hacia abajo".
Ejecuta el código en tu emulador e ingresa un código, como AAPL. Deberías obtener la siguiente pantalla con datos similares devueltos después de presionar el botón de búsqueda:



Para la próxima vez...
En el próximo tutorial de esta serie, que se publicará la próxima semana, te guiaré a través de la configuración de la biblioteca de gráficos Raphael JS, la configuración de una vista web para mostrar el gráfico, la recopilación de datos históricos de acciones con YQL y, por supuesto, realmente dibujar una representación gráfica en la pantalla para el usuario. ¡Asegúrate de suscribirte a través de RSS o Twitter si deseas recibir una notificación para la próxima publicación!