Showing posts with label matrix. Show all posts
Showing posts with label matrix. Show all posts

Sunday, October 10, 2010

Java Currency Converter using Yahoo Finance API – Currency Matrix – Visual Presentation

On this post we constructed a class that can get currency information from Yahoo Finance API. We saw how we can easily construct a neat currency matrix that summarizes currency information for several currencies.
Let’s see how we can visualize the currency matrix using a Java JSP and AJAX. The currency matrix will have the following properties:
  • The currency matrix will be show as an HTML table.
  • Currency information will be refreshed every 2 seconds.
  • If currency rate is increased the updated value will be marked in greed, if currency rate is decreased the updated value will be marked in red.
  • We will some popular currencies on our currency matrix. These currencies can be easily changed to have more/less/other currencies.
Since we would like to refresh currency information every 2 seconds (or any other fixed interval), and we don’t want the whole screen to be refreshed, only our currency matrix, we will need to use AJAX. We will use JSON in order to pass currency information from server to the client. JSON is a textual way of representing data.
The file that generates the JSON currency data is called: “currency_json.jsp”. It does the following things:
Let’s see how the file “currency_json.jsp” looks like:
<%
  YahooCurrencyConverter ycc = new YahooCurrencyConverter();
  String[] currencies = new String[]{"USD", "EUR", "GBP", "JPY", "CHF", "CAD", "AUD", "MXN", "ILS"};
  CurrencyPair[][] currencyPairs = ycc.getConversionMatrix(currencies);
  int size = currencyPairs.length;
  JSONArray currencyArray = new JSONArray();
  for (int i = 0; i < size; i++) {
    JSONArray currencyRow = new JSONArray();
    for (int j = 0; j < size; j++)
    {
      CurrencyPair currencyPair = currencyPairs[i][j];
      currencyRow.add(currencyPair != null ? currencyPair.getPrice() : null);
    }
    currencyArray.add(currencyRow);
  }
  out.print(currencyArray.toJSONString());
%>
<%@ page import="com.bashan.currency.currency.CurrencyPair" %>
<%@ page import="com.bashan.currency.currency.YahooCurrencyConverter" %>
<%@ page import="org.json.simple.JSONArray" %>
<%@ page contentType="application/json;charset=UTF-8" language="java" %>
Note, that this code converts the data to JSON using the open source project named: json simple.

Let’s move the the main file: “currency.jsp”. This file does the following things:
  • Make an AJAX request to the “currency_json.jsp” file in order to get the latest currency matrix information.
  • When AJAX response is completed, get the JSON data received from server and build the currency matrix table. During the process of constructing the currency matrix, compare the currency data to the previous data. If there was a change in the currency, paint the table cell in red or green depending if currency raised or dropped.
Note, that in order to make the JSON AJAX request, we use MooTools JavaScript library. MooTools is a great and concat JavaScript framework, quite simplar to jQuery.
Let’s look at the “currency.jsp” code:
<%@ page import="org.json.simple.JSONArray" %>
<%!
 
  private static String[] currencies = new String[]{"USD", "EUR", "GBP", "JPY", "CHF", "CAD", "AUD", "MXN", "ILS"};
  private static JSONArray currencyArray = new JSONArray();
 
  static {
    for (int i = 0; i < currencies.length; i++) {
      currencyArray.add(currencies[i]);
    }
  } 
 
%>
<html>
<head>
<title>Currency Exchange Rates</title>
<link rel="stylesheet" type="text/css" href="css/css.css">
</head>
<h1>Currency Exchange Rates</h1>
<table id="tableCurrency" class="tableBorder" cellspacing="0" cellpadding="5">
<thead>
<tr>
<td class="tdBorder" style="font-weight:bold; text-align:center;">Currencies</td>
<%
  for (String currency : currencies) {
%>
<td style="font-weight:bold; text-align:center;" class="tdBorder"><%= currency %></td>
<%
  }
%>
</tr>
</thead>
<tbody id="tableBodyCurrency">
<tr>
<td class="tdBorder" colspan="<%= currencies.length + 1 %>">
Loading currencies data...
</td>
</tr>
</tbody>
</table>
<script type="text/javascript" src="js/mootools.js"></script>
<body>
<script type="text/javascript">
 
  var currencyCodes = <%= currencyArray.toJSONString() %>;
  var oldCurrencies = null;
 
  function getJSON()
  {
    var jsonRequest = new Request.JSON({url: "currency_json.jsp",
    onComplete: function(currencies) {
    if (typeof(currencies) == "undefined")
    {
      return;
    } 
 
    var table = $("tableBodyCurrency");
    var data = "";
    for (var i = 0; i < currencies.length; i++)
    {
      data = data + "<tr><td style='font-weight:bold; text-align:center;' class='tdBorder'>" + currencyCodes[i] + "</td>";
      var currencyRow = currencies[i];
      for (var j = 0; j < currencyRow.length; j++)
      {
        var currency = currencyRow[j];
        if (oldCurrencies == null || currency == null)
        {
          data = data + "<td class='tdBorder' style='text-align:center;'>" + (currency != null ? currency : "&nbsp;") + "</td>";
        }
        else
        {
          var oldCurrency = oldCurrencies[i][j];
          if (currency > oldCurrency)
          {
            data = data + "<td style='background-color:green; text-align:center;n' class='tdBorder'>" + currency + "</td>";
          }
          else if (currency < oldCurrency)
          {
            data = data + "<td style='background-color:red; text-align:center;' class='tdBorder'>" + currency + "</td>";
          }
          else
          {
            data = data + "<td class='tdBorder' style='text-align:center;'>" + currency + "</td>";
          }
        }
      }
      
      data = data + "</tr>";
    }
   
    table.set('html', data);
    oldCurrencies = currencies;
  }}).get();
}
 
window.addEvent('domready', function() {
getJSON();
getJSON.periodical(2000);
 
});
</script>
</body>
</html>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
Also note, that the we use a style shit file named: “css.css” to make the table a bit nicer.
Now, let’s have a look how the currency matrix looks like when the page is first loaded:

And after we receive currency information, we can see the full matrix. Some of the cells are painted in green or red, indicating if currency increased or decreased:



You can see the currency matrix in action by simply dropping the currency.war file on Tomcat webapps folder. The war file also contains the java source files.

Monday, March 23, 2009

Java Currency Converter using Yahoo Finance API – Currency Matrix

On the post Basic Java Currency converter using Yahoo Finance API I showed how currency exchange rate information can be easily acquired.

Getting a single exchange rate between two currencies is a nice thing, but it can be inefficient, if one would like to get several currencies exchange rate information. Since the Acquiring the information requires a request to Yahoo servers, making multiple requests in order to get several exchange rates is an expensive operation. Luckily, Yahoo API allows getting more than one exchange rate information on a single request.

The structure for getting more than one currency information at a single request is pretty straight forward and can be easily deduced from the basic request I was showing on the previous post:

http://download.finance.yahoo.com/d/quotes.csv?s=[From Currency][To Currency]=X&...&s=[From Currency][To Currency]=X&f=l1&e=.cs

For example, getting 3 currencies information on a single request for the following currency pairs:

  • USD, ILS
  • USD, JPY
  • USD, GBP

Looks like:

http://download.finance.yahoo.com/d/quotes.csv?s=USDILS=X&s=USDJPY=X&s=USDGBP=X&f=l1&e=.cs

Extending our YahooCurrencyConverter from the previous post, to get currency information of more than one currency pair, is quite easy and therefore, I will jump directly to the main goal of this post: Getting currencies matrix information. Currency matrix information is a neat way of showing currency exchange rates of several currencies on a single table. Currency matrix can be illustrated easily by example. Currency matrix for the currencies: ILS, USD, GBP looks like:

         ILS     USD     GBP
ILS            0.247   0.170
USD    4.044           0.686
GBP    5.893   1.457        
In order to add currency matrix information, we will first do 2 things:
  • Add a new class named: CurrencyPair. This class represents the relation between 2 currencies.
  • Add a new method to the interface CurrencyConverter. This method defines a way of getting exchange rate information for several currencies.

Note, that the code in this post relies on the code from the post: Basic Java Currency converter using Yahoo Finance API.

This is the code of CurrencyPair class:
public class CurrencyPair {
    private String from;
    private String to;
    float price;
    public CurrencyPair(String from, String to)
    {
      this.from = from;
      this.to = to;
    }
    public String getFrom() {
        return from;
    }
    public void setFrom(String from) {
        this.from = from;
    }
    public String getTo() {
        return to;
    }
    public void setTo(String to) {
        this.to = to;
    }
    public float getPrice()
    {
        return price;
    }
}

This is the code of CurrencyConverter interface:
public interface CurrencyConverter {
    public float convert(String currencyFrom, String currencyTo) throws Exception;
    public void convert(CurrencyPair[] currencyPairs) throws Exception;
}


Now, we will add a new abstract class that will do the currency matrix calculations. Note that the currency matrix calculations relays on the new convert method added to CurrencyConverter interface:

public abstract class BaseCurrencyConverter implements CurrencyConverter {
    public CurrencyPair[][] getConversionMatrix(String... currencies) throws Exception {
        // Build pair combinations
        int size = currencies.length;
        CurrencyPair[] currencyPairs = new CurrencyPair[size * size];
        int index = 0;
        for (int i = 0; i < size; i++) {
            for (int j = 0; j < size; j++) {
                currencyPairs[index++] = new CurrencyPair(currencies[i], currencies[j]);
            }
        }
        // Get currencies information
        convert(currencyPairs);
        // Build matrix
        CurrencyPair[][] matrix = new CurrencyPair[size][size];
        index = 0;
        for (int i = 0; i < size; i++) {
            for (int j = 0; j < size; j++) {
                matrix[i][j] = i != j ? currencyPairs[index] : null;
                index++;
            }
        }
        return matrix;
    }
}

The method getConversionMatrix in the abstract class BaseCurrencyConverter builds currency matrix information for any class implementing the convert method. It does not care about how the convert method is implemented. The method receives a list of currencies for which we would like to build the matrix. From the list it builds all combinations between any 2 currencies. After building list of combinations, the abstract convert method is activated, to get the actual currency information. The final part of the class arranges the results in a 2 dimensional array, for easier data access.


Finally, after laying the structure, we can go back to the main implementing class: YahooCurrencyConverter. We don’t really have much more work to do, since the matrix creation is done on the abstract class. We just have to implement the new added convert method, to allow getting currency information for several currencies at a single request. In addition the class contains a small main program showing how the currency matrix can be used:
public class YahooCurrencyConverter extends BaseCurrencyConverter {
    public float convert(String currencyFrom, String currencyTo) throws IOException {
        HttpClient httpclient = new DefaultHttpClient();
        HttpGet httpGet = new HttpGet("http://quote.yahoo.com/d/quotes.csv?s=" + currencyFrom + currencyTo + "=X&f=l1&e=.csv");
        ResponseHandler<String> responseHandler = new BasicResponseHandler();
        String responseBody = httpclient.execute(httpGet, responseHandler);
        httpclient.getConnectionManager().shutdown();
        return Float.parseFloat(responseBody);
    }
    public void convert(CurrencyPair[] currencyPairs) throws IOException {
        HttpClient httpclient = new DefaultHttpClient();
        StringBuffer sb = new StringBuffer();
        for (CurrencyPair currencyPair : currencyPairs) {
            sb.append("s=").append(currencyPair.getFrom()).append(currencyPair.getTo()).append("=X&");
        }
        HttpGet httpGet = new HttpGet("http://quote.yahoo.com/d/quotes.csv?" + sb + "f=l1&e=.csv");
        ResponseHandler<String> responseHandler = new BasicResponseHandler();
        String responseBody = httpclient.execute(httpGet, responseHandler);
        httpclient.getConnectionManager().shutdown();
        String[] lines = responseBody.split("\n");
        if (lines.length != currencyPairs.length) {
            throw new IllegalStateException("Currency data mismatch");
        }
        int i = 0;
        for (String line : lines) {
            CurrencyPair currencyPair = currencyPairs[i++];
            currencyPair.price = Float.parseFloat(line);
        }
    }
    public static void main(String[] args) {
        YahooCurrencyConverter ycc = new YahooCurrencyConverter();
        try {
            String[] currencies = new String[] { "USD", "EUR", "GBP", "JPY", "CHF", "CAD", "AUD", "MXN", "ILS" };
            CurrencyPair[][] currencyPairs = ycc.getConversionMatrix(currencies);
            System.out.print("    ");
            for (int i = 0; i < currencyPairs.length; i++)
            {
                System.out.print("     " + currencies[i]);
            }
            System.out.println();
            for (int i = 0; i < currencyPairs.length; i++)
            {
                for (int j = 0; j < currencyPairs.length; j++)
                {
                    if (j == 0)
                    {
                        System.out.print(currencies[i] + " ");
                    }
                    CurrencyPair currencyPair = currencyPairs[i][j];
                    if (currencyPair != null)
                    {
                        System.out.printf("%8.3f", currencyPair.price);
                    }
                    else
                    {
                        System.out.print("        ");
                    }
                }
                System.out.println();
            }
        }
        catch (Exception e) {
            e.printStackTrace();
        }
    }
}

This is how the output for the currency matrix looks like:

         USD     EUR     GBP     JPY     CHF     CAD     AUD     MXN     ILS
USD            0.733   0.686  96.940   1.125   1.223   1.419  14.275   4.041
EUR    1.363           0.936 132.178   1.534   1.668   1.935  19.464   5.510
GBP    1.457   1.069         141.246   1.639   1.782   2.068  20.799   5.888
JPY    0.010   0.008   0.007           0.012   0.013   0.015   0.147   0.042
CHF    0.889   0.652   0.610  86.177           1.087   1.262  12.690   3.592
CAD    0.817   0.600   0.561  79.245   0.920           1.160  11.669   3.303
AUD    0.705   0.517   0.484  68.309   0.793   0.862          10.059   2.848
MXN    0.070   0.051   0.048   6.791   0.079   0.086   0.099           0.283
ILS    0.248   0.182   0.170  23.989   0.278   0.303   0.351   3.533        

I hope this code will help you to easily build your own custom currency matrices. This information may be useful to currency traders or applications that need to show the latest exchange rate between currencies.

As stated for the previous post, this class is making use of the Apache open source project: Http Client. You will need to put in your project the proper jar files for this class to work properly.