Advertisement
Titanium Mobile

Make a Stock Quote App: Search Stock Data with YQL

by

In this tutorial series, I will be teaching you how to build a stock quote application with Raphael JS, Titanium Mobile, and Yahoo's YQL web service. Raphael JS charts will be used to graphically present the stock quote information, Titanium Mobile will be used to cross-compile a native iOS app, and YQL data tables will actually retrieve the stock information.

Introduction to Yahoo YQL & Raphael JS

YQL is a SQL-like language that allows you to query, filter and combine data from multiple sources across both the Yahoo! network and other open data sources. Normally, developer access to data from multiple resources is disparate and requires calls to multiple APIs from different providers, often with varying feed formats. YQL eliminates this problem by providing a single endpoint to query and shape the data you request. In this tutorial, we'll be using the YQL open data tables provided by Yahoo Finance in order to retrieve and present stock quote information.

This presentation of this information is where Raphael JS charts come in. Charts and graphs are the easiest, most logical way to present a timeline of financial data, and Titanium mobile does not come with a native charting API. Raphael is open-source and MIT licensed, and it is fortunately very mobile friendly because it is written in standard JavaScript, maintains a low processing footprint, and actually renders in SVG format which means that it can be easily resized to fit any mobile screen without a decrease in image quality!

Final App Preview

The following is a preview of the application we will be building in this series:

Step 1: Create a New Project

Open up Titanium Developer and create a new project. You can give the project any name you want, but I'll use the title "StockQuotes" for simplicity. Now is a good time to download the source files for this project as well. Download and unzip the project files attached to this post and copy the "images" folder across into the "Resources" directory of your new Titanium project. By default Titanium also includes two icon files in the root of your "Resources" directory called KS_nav_ui.png and KS_nav_views.png - we don't need either so go ahead and move both of these to the trash.

Step 2: Create the Basic Interface

Open the app.js file, in the root of your "Resources" directory, into your favorite editor. We don't need any of the automatically generated code, so delete it all and replace it with the following:

// This sets the background color of the master UIView
Titanium.UI.setBackgroundColor('#000');

// Create the application window
var win1 = Titanium.UI.createWindow({  
    backgroundImage: 'images/background.png'
});

// Create the title label for our app
var titleLabel = Titanium.UI.createLabel({
    text: 'Search Quotes',
    color: '#fff',
    height: 20,
    width: 320,
    top: 6,
    textAlign: 'center',
    font: {fontSize: 15, fontFamily: 'Helvetica', fontWeight: 'bold'}
});
win1.add(titleLabel);

//Create the scroll area, all our content goes in here
var scrollArea = Titanium.UI.createScrollView({
    top: 40,
    width: 320,
    height: 420,
    contentHeight: 'auto'
});

// Create the stock quote search box
var searchBox = Titanium.UI.createView({
    width: 300,
    left: 10,
    top: 10,
    height: 50,
    borderRadius: 5,
    backgroundImage: 'images/gradient-small.png'
});

scrollArea.add(searchBox);

// Create the quote information box
var quoteInfoBox = Titanium.UI.createView({
    width: 300,
    left: 10,
    top: 70,
    height: 200,
    borderRadius: 5,
    backgroundImage: 'images/gradient.png'
});

scrollArea.add(quoteInfoBox);

// Create the quote chart box
var quoteChartBox = Titanium.UI.createView({
    width: 300,
    left: 10,
    top: 280,
    height: 300,
    borderRadius: 5,
    backgroundImage: 'images/gradient.png'
});

scrollArea.add(quoteChartBox);

// This small view just adds 10px of padding to the bottom of 
// our scrollview (scrollArea)
var emptyView = Titanium.UI.createView({
    height: 10,
    top: 580
});

scrollArea.add(emptyView);

// Add the scrollview to the window
win1.add(scrollArea);

// Open the window
win1.open();

What we've done above is created a basic, nicely styled shell for our application. There's a space at the top to create a search field, and two more empty boxes to place our stock information and our chart. All of this has been added to a ScrollView so we can easily scroll our app to view any information that is hidden from the bounds of the screen. Run your app in the iPhone emulator and it should now look like the image below:

Step 3: Creating the Search Field

Our next step is to create the text field and search button that the user will use to interact with our application by providing a stock symbol (e.g. APPL for Apple Computers) to search upon. Enter in the following code before the line where you added your searchBox object to the scrollArea (line 39).

// This is the input textfield for our stock code
var txtStockCode = Titanium.UI.createTextField({
    hintText: 'Stock code, e.g. APPL',
    borderWidth: 0,
    width: 200,
    left: 10,
    height: 30,
    font: {fontSize: 14, fontColor: '#262626', fontFamily: 'Helvetica'},
    autoCorrect: false,
    autocapitalization: Titanium.UI.TEXT_AUTOCAPITALIZATION_ALL
});

searchBox.add(txtStockCode);

// Create the search button from our search.png image
var btnSearch = Titanium.UI.createButton({  
    backgroundImage: 'images/search.png',
    width: 80,
    height: 30,
    right: 10,
    borderRadius: 3
});

// Add the event listener for this button
btnSearch.addEventListener('click', searchYQL);

searchBox.add(btnSearch);

What we accomplished above is to create the two input components necessary for the user to input data (a stock quote in this case) and to perform an action based on that input by tapping the search button. If you hadn't noticed already, our btnSearch button object has an event listener that will fire whenever the user taps it and call a function named searchYQL. If you were to run the app in the emulator now, you would end up with a big red error screen as we haven't created this function yet. Let's do that now.

Enter in the following at the top of your app.js file, after the Titanium.UI.setBackgroundColor line:

// This function is called on search button tap, it will query YQL for our stock data
function searchYQL() {
}

If you haven't already done so, save your app.js file and run it in the emulator. You should see a screen similar to the one below:

Step 4: Searching For Stock Quotes Using Yahoo YQL

Now, before we search YQL for information about our stocks, we need to create some labels and images that will go into our quoteInfoBox and present the information to the user. This is a pretty straight-forward process. The following code should be placed before you add the quoteInfoBox to the scrollArea on line 93.

// Add the labels and images we need to show some basic stock information
var lblCompanyName = Titanium.UI.createLabel({
    width: 280,
    height: 30,
    left: 10,
    top: 10,
    color: '#003366',
    font: {fontSize: 17, fontWeight: 'bold', fontFamily: 'Helvetica'},
    text: 'No company selected'
});
quoteInfoBox.add(lblCompanyName);

var lblDaysLow = Titanium.UI.createLabel({
    width: 280,
    height: 20,
    left: 10,
    top: 50,
    color: '#000',
    font: {fontSize: 14, fontWeight: 'bold', fontFamily: 'Helvetica'},
    text: 'Days Low: '
});

quoteInfoBox.add(lblDaysLow);

var lblDaysHigh = Titanium.UI.createLabel({
    width: 280,
    height: 20,
    left: 10,
    top: 80,
    color: '#000',
    font: {fontSize: 14, fontWeight: 'bold', fontFamily: 'Helvetica'},
    text: 'Days High: '
});

quoteInfoBox.add(lblDaysHigh);

var lblLastOpen = Titanium.UI.createLabel({
    width: 280,
    height: 20,
    left: 10,
    top: 110,
    color: '#000',
    font: {fontSize: 14, fontWeight: 'bold', fontFamily: 'Helvetica'},
    text: 'Last Open: '
});

quoteInfoBox.add(lblLastOpen);

var lblLastClose = Titanium.UI.createLabel({
    width: 280,
    height: 20,
    left: 10,
    top: 140,
    color: '#000',
    font: {fontSize: 14, fontWeight: 'bold', fontFamily: 'Helvetica'},
    text: 'Last Close: '
});

quoteInfoBox.add(lblLastClose);

var lblVolume = Titanium.UI.createLabel({
    width: 280,
    height: 20,
    left: 10,
    top: 170,
    color: '#000',
    font: {fontSize: 14, fontWeight: 'bold', fontFamily: 'Helvetica'},
    text: 'Volume: '
});

quoteInfoBox.add(lblVolume);

Once your labels and our stock movement image arrow has been added, you should be able to run the emulator and end up with a screen like this one:

Now let's do something useful with this layout and fill it with stock data from Yahoo! To do that we need to expand our empty searchYQL() function and perform a search against the Yahoo YQL finance data tables using a combination of YQL syntax and Titanium's Titanium.Yahoo.yql() method.

// This function is called on search button tap. It will query YQL for our stock data
function searchYQL() {

  // Do some basic validation to ensure the user has entered a stock code value
  if(txtStockCode.value != '') 
  {
    txtStockCode.blur(); //hides the keyboard
    
    // Create the query string using a combination of YQL syntax and the value of the txtStockCode field
    var query = 'select * from yahoo.finance.quotes where symbol = "' + txtStockCode.value + '"';
    
    // Execute the query and get the results
    Titanium.Yahoo.yql(query, function(e) {
        var data = e.data;
        
        // Iff ErrorIndicationreturnedforsymbolchangedinvalid is null then we found a valid stock
        if(data.quote.ErrorIndicationreturnedforsymbolchangedinvalid == null) 
        {
            //we have some data! let's assign it to our labels etc
            lblCompanyName.text = data.quote.Name;
            lblDaysLow.text = 'Days Low: ' + data.quote.DaysLow;
            lblDaysHigh.text = 'Days High: ' + data.quote.DaysHigh;
            lblLastOpen.text = 'Last Open: ' + data.quote.Open;
            lblLastClose.text = 'Last Close: ' + data.quote.PreviousClose;   
            lblVolume.text = 'Volume: ' + data.quote.Volume;          
            lblPercentChange.text = data.quote.PercentChange;
            
            //if the previous close was equal or higher than the opening price, the 
            //stock direction is up... otherwise it went down!
            if(data.quote.PreviousClose >= data.quote.Open)  {
                imgStockDirection.image = 'images/arrow-up.png';
            }
            else  {
                imgStockDirection.image = 'images/arrow-down.png';
            }  
                                                                
        }
        else 
        {
            //show an alert dialog saying nothing could be found
            alert('No stock information could be found for ' + txtStockCode.value + '!');
        }
    });      
  } 
  else 
  {
    alert('You must provide a stock code to search upon, e.g. AAPL or YHOO');
  }
}

So, what is actually going on here within the searchYQL() function? First, we're doing a very basic validation on the text field to ensure the user has entered in a stock quote before pressing search. If a stock quote is found, we use the blur() method of the text field to ensure the keyboard becomes hidden. The meat of the code revolves around creating a Yahoo YQL query using the correct syntax and providing the text field value as the symbol parameter. This YQL query is simply a string, joined together using the + symbol much as you would do with any other string manipulation in JavaScript. We then execute our query using the Titanium.Yahoo.yql() method, which returns the results within the 'e' object of the inline function.

The data within the 'e' object is simply JSON, a common, fast data format fast becoming ubiquitous on the web and with all the major API's. Using this data is a matter of simple dot notation. In our code, we're first checking the property called data.quote.ErrorIndicationreturnedforsymbolchangedinvalid in order to ensure that the symbol the user entered was a valid stock code. If it is, we can then assign all the values to our labels! Lastly, we do a check to see whether the stock price closed higher than it opened, if so then we can set the stock movement image to a green "up" arrow, indicating it rose in value. If it fell in value, we can move the image to a red, "down" arrow.

Run the code in your emulator and enter in a code, such as AAPL. You should get the following screen with similar data returned after pressing the search button:

Next Time. . .

In the next tutorial in this series, to be published next week, I'll walk you through setting up the Raphael JS charting library, setting up a web view to display the chart, collecting historical stock data with YQL, and, of course, actually drawing a graphical representation on screen for the user! Be sure to subscribe via RSS or Twitter if you'd like to be notified when the next post is released!

Related Posts
  • Code
    ASP.NET
    Preventing Code InjectionCsrf dotnet retina preview
    Often, websites seem to exist primarily to put something into a database in order to pull it out later. While other database methods, such as NoSQL, have gained popularity in recent years, data for many websites still resides in the traditional SQL database. This data often consists of valuable personal information such as credit card numbers and other personal information of interest to identity thieves and criminals. Hackers therefore always look to get this data. One of the most common targets of these attacks is the SQL databases that lie behind many web applications through a process of SQL Injection.Read More…
  • Web Design
    HTML/CSS
    Building the Merry Christmas Web App InterfaceXmas build 2 retina
    Today we're going to build the Merry Christmas Web App Interface; a Photoshop layout from an earlier tutorial by Tomas Laurinavicius.Read More…
  • Web Design
    CMS
    Uber Aesthetics and ResponsivenessGhost rwd retina
    Welcome to the final part of our Ghost theme design tutorial series! In the previous two parts of this series we worked on the first half of styling our theme and laid the groundwork for responsive behavior. This fifth and final part finalizes our styling and completes the task of making our theme fully responsive.Read More…
  • Code
    Titanium Mobile
    Creating Titanium Mobile Modules Using CommonJSCommon js
    In this article we'll be discussing how to create your own mobile modules for Appcelerator's Titanium using just JavaScript and a bit of CommonJS knowledge.Read More…
  • Code
    JavaScript & AJAX
    Building Ribbit in MeteorRibbit meteor preview retina
    This is a continuation of the Twitter clone series with building Ribbit from scratch, this time using Meteor.Read More…
  • Code
    Titanium Mobile
    Make a Stock Quote App: Displaying Charts with Raphael JSStockquoteapp preview 2
    In this tutorial series, I will be teaching you how to build a stock quote application with Raphael JS, Titanium Mobile, and Yahoo's YQL web service. Raphael JS charts will be used to graphically present the stock quote information, Titanium Mobile will be used to cross-compile a native iOS app, and YQL data tables will actually retrieve the stock information.Read More…