Using Scheduled Apex jobs to retrieve stock quotes.

Spring '10 saw the GA of Scheduled Apex Jobs. This post provides a real-world example of retrieving stock quotes from the web using Scheduled Apex to automatically run the job every hour.

Spring '10 saw the general availability of one of my favorite new features of the platform: the Apex Scheduler. 

With the Apex Scheduler, developers can now schedule cron style jobs to run any Apex classes which implement the Schedulable interface.  The Schedule Apex page, available from Setup | Develop | Apex Classes, lets you define the how often your particular job will run.

 One of things which you may notice is that you are can only schedule jobs to run up to once a day using the Schedule Apex page. Never fear, however, for with a little bit of code you can schedule your jobs to run every hour.  Let's look at a real world example:

Suppose that every hour I wanted to retrieve the current stock quote for an account using the very handy, but often overlooked Yahoo stock API. 

global class getStockPrice implements Schedulable
global void execute(SchedulableContext ctx)
//call a future method so we can do callouts within a schedule

You will notice that I have implemented the Schedulable interface and overriden the execute method in my Apex class. That is all I need to do to take advantage of Apex Scheduling. Pretty cool, huh. In this example I also used the @future annotation to allow me to do a callout from within a Scheduled Job. Here is the code which does the actual retrieval of stock price information from Yahoo's service:

global class CallYahooQuotes
    public static void getQuotes()
    {   //for our simple example we are going to just update the quotes on one Account
       Account acct = [select id, TickerSymbol, stock_price__c from account where name = ''];
       //where f stands for the fields to be displayed (in this case: s - symbol; l1 - last price; c1 - change; d1 = last date)
       // String url = ''+acct.TickerSymbol+'&f=sl1c1d1&e=.csv';
     String url = ''+acct.TickerSymbol+'&f=l1&e=.csv';
    Http h = new Http();
    HttpRequest req = new HttpRequest();
    HttpResponse res = h.send(req);
    //omitting error handling for example
    acct.stock_price__c = decimal.valueOf(res.getBody().trim());  
    update acct;  


 Next, I want to schedule my job to run every hour.

A best practice I like to follow is to create a wrapper Schedule class with a static start method. This way I can either call my class from, say a custom Visualforce page after a user clicks a button, or via  the execute function in the System Log.

global class StockPriceJobScheduler
global void StockPriceJobScheduler() {}
public static void start()
//Seconds Minutes Hours Day_of_month Month Day_of_week optional_year
System.schedule('Stock Price Update', '0 0 1-23 * * ?', new getStockPrice());

The System.schedule method takes three parameters: a job name, a cron expression, and the name of the schedulable class. The only tricky parameter is the cron expression. Take some time to read the docs to fully understand the syntax of cron expressions as they are a handy tool to have in your developer toolbox.

One thing that you will discover as you try out scheduling is that, although it is possible to schedule a job to run more frequently than every hour, the platform will assign a minimum frequency of 1 hour. 

Let's go ahead and use the System Log (click on the System Log link at the top of your screen) to start our new Scheduled Job:

Finally, navigate to Setup |   Monitoring | Scheduled Jobs and you should see our new job with the name we gave it during the scheduling process.

That's it. With less than 30 lines of code (a some of those are comments!) we just created a scheduled job to receive stocks quotes from the web and updated our Account. 

Spring is certainly here!

Leave your comments...

Using Scheduled Apex jobs to retrieve stock quotes.