Important: The Google Finance Portfolio Data API v2.0 is in Labs, and its features might change unexpectedly until it graduates.
The Google Finance Portfolio Data API allows client applications to view and update Finance content in the form of Google Data Protocol feeds.
Your client application can use the Finance Data API to create new portfolio and transaction entries, request a list of entries, and edit or delete existing entries.
In addition to providing some background on the capabilities of the Finance Data API, this document provides examples of basic Finance Data API interactions using the Java client library. If you're interested in understanding more about the underlying protocol that the library uses, see the Protocol section of this developer's guide.
This document is intended for programmers who want to write Java client applications that can interact with Google Finance.
This document assumes that you understand the general ideas behind the Google Data Protocol, and that you're familiar with the Google Finance GUI.
For reference information about the classes and methods provided by the client library, see the Java client library API reference. For general Finance Data API reference information, see the Protocol reference guide.
For help setting up the client library, see the Getting Started Guide.
The Java client library requires Java 1.5. After downloading the client library, you'll find the classes you need to get started in the java/lib/gdataclient-1.0.jar file.
You may want to sign up for a Finance account for testing purposes. Finance uses Google Accounts, so if you already have a Google account, you're all set.
User accounts at Google Finance are not connected to brokerages or other financial systems. If a user's Finance account shows the user as holding a particular position, that doesn't necessarily mean the user actually holds that position in the real world.
Transactions that a client sends to Google Finance also don't have any effect on the real world. If your client sends a Buy order for 50 shares of GOOG, that doesn't cause the user to actually purchase anything; the only thing that changes is the user's position information in their Google Finance account.
Conversely, if the user performs a real-world transaction through a brokerage or other system, then their Finance account doesn't get updated until they use a client (or the GUI) to send the information about the transaction to Google Finance.
However, the market values, returns, and gains provided in Finance Data API feeds do use real-world market data, so if a user accurately records their transactions, then the performance data provided by Google Finance is accurate.
The Finance Data API provides a hierarchical set of three feed types:
For more information about these feeds, see the appropriate sections of this developer's guide, or the feed types section of the Protocol reference guide.
A full working sample client, containing all the sample code shown in this document, is available in the Java client library distribution, under the directory gdata/java/sample/finance/FinancePortfoliosClient.java. Build and execution instructions are included in the same directory in the README.txt file.
The sample client performs several operations on a Finance portfolio to demonstrate the use of the Finance Data API.
To compile the examples in this document into your own code, you'll need the following import statements:
import com.google.gdata.client.finance.FinanceService; import com.google.gdata.data.BaseEntry; import com.google.gdata.data.BaseFeed; import com.google.gdata.data.Link; import com.google.gdata.data.PlainTextConstruct; import com.google.gdata.data.extensions.Money; import com.google.gdata.data.finance.*; import com.google.gdata.util.AuthenticationException; import com.google.gdata.util.ServiceException; import java.io.IOException; import java.net.MalformedURLException; import java.net.URL; import java.util.Iterator; import java.util.Scanner;
A client must authenticate before using the Finance Data API. It can authenticate using either of two approaches: AuthSub proxy authentication or ClientLogin username/password authentication.
For more information about authentication with the Google Data Protocol in general, see the authentication documentation.
Most of the samples in subsequent sections of this document assume you have an authenticated FinanceService object.
AuthSub proxy authentication is used by web applications that need to authenticate their users to Google Accounts. The web site operator and the client code don't have access to the username and password for the Finance user; instead, the client obtains special AuthSub tokens that allow the client to act on a particular user's behalf. For more detailed information, see the AuthSub documentation.
When a user first visits your application, they have not yet been authenticated. In this case, you need to display some information and a link directing the user to a Google page to authenticate your request for access to their portfolios. The Java client library provides a function to generate the Google page's URL. The code below retrieves the URL of the AuthSubRequest page:
String next = "http://www.example.com/welcome.html"; String scope = "http://finance.google.com/finance/feeds/"; boolean secure = false; boolean session = true; String authSubLogin = AuthSubUtil.getRequestUrl(next, scope, secure, session);
The getRequestUrl method takes the following parameters (corresponding to the query parameters used by the AuthSubRequest handler):
http://finance.google.com/finance/feeds/ (URL-encoded, of course).The above example shows a call that doesn't request a secure token (the value of secure is false). The resulting request URL might look like this:
https://www.google.com/accounts/AuthSubRequest?scope=http%3A%2F%2Ffinance.google.com%2Ffinance%2Ffeeds%2F&session=1&secure=0&next=http%3A%2F%2Fwww.example.com%2Fwelcome.html
The user follows the link to Google's site and authenticates to their Google Account.
After the user authenticates, the AuthSub system redirects them to the URL you specified in the next query parameter of the AuthSubRequest URL. The AuthSub system appends an authentication token to that URL, as the value of the token query parameter. For example:
http://www.example.com/welcome.html?token=yourAuthToken
This token value represents a single-use AuthSub token. In this example, since session = true was specified, this token can be exchanged for an AuthSub session token by calling the AuthSubSessionToken service, as follows, where urlFromAuthSub is the URL that AuthSub appended the token to:
String token = AuthSubUtil.getTokenFromReply(urlFromAuthSub); String sessionToken = AuthSubUtil.exchangeForSessionToken(token, null);
That is, you pass your one-time-use token to the exchangeForSessionToken method, along with either null (for unregistered mode) or a private key (for registered mode), and the AuthSub interface returns a session token. For more information about registered applications and private keys, see the "Signing requests" section of the AuthSub documentation.
Your application can then use the session token value in subsequent interactions with Finance. The client library automatically sends the token along with requests.
Use ClientLogin authentication if your client is a standalone, single-user "installed" client (such as a desktop application). Just call the setUserCredentials method on your FinanceService object and all subsequent interactions with Finance will be authenticated:
FinanceService myService = new FinanceService("exampleCo-exampleApp-1");
myService.setUserCredentials("user@domain.com",
"secretPassword");
In the snippet above, we pass one parameter to the FinanceService constructor: the name of our application in the form companyName-applicationName-versionNumber.
For more information about ClientLogin authentication, including sample requests and responses, see the Authentication for Installed Applications documentation.
Note: Use the same token for all requests in a given session; don't acquire a new token for each Finance request.
A portfolio is a collection of positions that the user holds in various securities, plus metadata.
A portfolio feed lists all of the user's portfolios. Each portfolio entry contains the portfolio's title along with data such as currency and total market value. Each portfolio entry also contains a link to the portfolio's position feed.
You can use the Java client library to publish new portfolio entries.
First, create a PortfolioEntry object to represent the portfolio. Then you can set the title, content and other attributes of the portfolio. Finally, use the FinanceService object to insert the portfolio. Here's an example of how to publish a new portfolio:
private static PortfolioEntry makePortfolioEntry(String portfolioName, String currencyCode) {
PortfolioEntry entry = new PortfolioEntry();
entry.setTitle(new PlainTextConstruct(portfolioName));
PortfolioData data = new PortfolioData();
data.setCurrencyCode(currencyCode);
entry.setPortfolioData(data);
return entry;
}
private static void insertPortfolioEntry(FinanceService service, String feedUrl, PortfolioEntry entry)
throws IOException, MalformedURLException, ServiceException {
System.out.println("Inserting Entry at location: " + feedUrl);
service.insert(new URL(feedUrl), entry);
}
Here's an example of how these methods might be used:
public static void main(String[] args) {
FinanceService service = new FinanceService("Google-PortfoliosDemo-1.0");
Scanner sc = new Scanner(System.in);
System.out.print("Enter user ID: ");
String userEmail = sc.nextLine();
System.out.print("Enter user password: ");
String userPassword = sc.nextLine();
if(!loginUser(service, userEmail, userPassword)) System.exit(0);
System.out.println("Enter portfolio name");
String portfolioName = sc.nextLine();
System.out.println("Enter currency code");
String currencyCode = sc.nextLine();
PortfolioEntry entry = makePortfolioEntry(portfolioName, currencyCode);
String requestUrl = "http://finance.google.com/finance/feeds/default/portfolios";
try {
insertPortfolioEntry(service, requestUrl, entry);
} catch (IOException e) {
// Communication error.
System.err.println("There was a problem communicating with the service.");
e.printStackTrace();
} catch (ServiceException e) {
// Server side error.
System.err.println("The server had a problem handling your request.");
e.printStackTrace();
}
}
The insert method takes the service's post URL as a parameter. Then the method returns the entry as it was stored by Finance. The entry returned is the same one you sent, but it also contains various elements added by Finance, such as a portfolio ID.
To retrieve the user's portfolios, call the getFeed method with the portfolio feed URL:
private static void queryPortfolioFeed(FinanceService service, String feedUrl)
throws IOException, MalformedURLException, ServiceException {
PortfolioFeed portfolioFeed = service.getFeed(new URL(feedUrl), PortfolioFeed.class);
printBasicFeedDetails(portfolioFeed);
for (int i = 0; i < portfolioFeed.getEntries().size(); i++) {
PortfolioEntry portfolioEntry = portfolioFeed.getEntries().get(i);
printPortfolioEntry(portfolioEntry);
}
}
The getFeed call returns a feed containing a list of entries, one for each portfolio associated with the currently authenticated user. The list is ordered by portfolio ID.
The feedUrl parameter should be set to the portfolio feed URL:
http://finance.google.com/finance/feeds/default/portfolios
Instead of retrieving a complete portfolio feed, you can retrieve a specific individual entry.
The following method retrieves a specific portfolio entry and prints out the data associated with the entry. The print methods for the data are shown in a later section (Displaying portfolio, position, and transaction data).
private static void queryPortfolioEntry(FinanceService service, String entryUrl)
throws IOException, MalformedURLException, ServiceException {
PortfolioEntry portfolioEntry = service.getEntry(new URL(entryUrl), PortfolioEntry.class);
printPortfolioEntry(portfolioEntry);
}
The getEntry call returns the portfolio entry with the specified portfolio ID.
The entryUrl parameter should be set to the portfolio feed URL, with the portfolio ID appended, in the following form:
http://finance.google.com/finance/feeds/default/portfolios/portfolioID
The Finance Data API lets you request that additional material be included in returned feeds, such as requesting that the entries in a feed include performance data.
To do this, you build a query-parameter string manually and append it to the request URL.
For example, to request a Finance portfolio feed with performance data and financial returns included, send an HTTP request to the portfolio's feed URL, with the returns=true parameter appended:
public static void main(String[] args) {
FinanceService service = new FinanceService("Google-PortfoliosDemo-1.0");
Scanner sc = new Scanner(System.in);
System.out.print("Enter user ID: ");
String userEmail = sc.nextLine();
System.out.print("Enter user password: ");
String userPassword = sc.nextLine();
if(!loginUser(service, userEmail, userPassword)) System.exit(0);
String requestUrl = "http://finance.google.com/finance/feeds/default/portfolios";
System.out.print("Include returns in query response? (y/n) ");
String includeReturns = sc.nextLine();
if (includeReturns.toLowerCase().equals("yes") || includeReturns.toLowerCase().equals("y")) {
requestUrl += "?returns=true";
} else if (includeReturns.toLowerCase().equals("no") || includeReturns.toLowerCase().equals("n")) {
requestUrl += "?returns=false";
}
// if the parameter is left unspecified, the server will use the default value
try {
queryPortfolioFeed(service, requestUrl);
} catch (IOException e) {
// Communication error.
System.err.println("There was a problem communicating with the service.");
e.printStackTrace();
} catch (ServiceException e) {
// Server side error.
System.err.println("The server had a problem handling your request.");
e.printStackTrace();
}
}
For more information about query parameters, see the Finance Data API Reference Guide and the Google Data APIs Reference Guide.
These query parameters apply only to requests for feeds, not to requests for individual entries.
To update an existing portfolio, first you retrieve the entry you want to update, then you modify it, and then you send it to Finance using the update method. The following code snippet modifies the title of a portfolio entry, assuming that you've already retrieved the portfolio from the server.
public static Entry updatePostTitle(FinanceService myService,
Entry entryToUpdate, String newTitle)
throws ServiceException, IOException {
entryToUpdate.setTitle(new PlainTextConstruct(newTitle));
URL editUrl = new URL(entryToUpdate.getEditLink().getHref());
return myService.update(editUrl, entryToUpdate);
}
The above code returns an Entry containing the entire newly-updated portfolio. To update any other properties, simply set them in the Entry object before calling update.
To delete a portfolio, pass the portfolio's edit URL to the delete method on your FinanceService object, like this:
public static void deletePost(FinanceService myService, Entry entryToDelete)
throws ServiceException, IOException {
URL deleteUrl = new URL(entryToDelete.getEditLink().getHref());
myService.delete(deleteUrl);
}
Note: To update existing portfolios, see Updating portfolios; don't update by deleting portfolios and then re-adding them.
A position is a collection of information about a security that the user holds.
A position feed lists all of the positions in a particular portfolio. Each position entry contains the ticker symbol for a stock, mutual fund, or other security, along with the number of units of that security that the user holds. Each position entry also contains a link to the position's transaction feed.
You can't directly create, update, or delete position entries; positions are derived from transactions. For example, a GOOG position is derived from the buy and sell transactions for GOOG.
To retrieve a given portfolio's positions, call the getFeed method with the position feed URL:
private static void queryPositionFeed(FinanceService service, String feedUrl)
throws IOException, MalformedURLException, ServiceException {
PositionFeed positionFeed = service.getFeed(new URL(feedUrl), PositionFeed.class);
printBasicFeedDetails(positionFeed);
for (int i = 0; i < positionFeed.getEntries().size(); i++) {
PositionEntry positionEntry = positionFeed.getEntries().get(i);
printPositionEntry(positionEntry);
}
}
The getFeed call returns a feed containing a list of entries, one for each position associated with the portfolio given in the feed URL.
The feedUrl parameter should be set to a position feed URL, of the following form:
http://finance.google.com/finance/feeds/default/portfolios/portfolioID/positions
Instead of retrieving a complete position feed, you can retrieve a specific individual entry.
The following method retrieves a specific position entry and prints out the data associated with the entry. The print methods for the data are shown in a later section (Displaying portfolio, position, and transaction data).
private static void queryPositionEntry(FinanceService service, String entryUrl)
throws IOException, MalformedURLException, ServiceException {
PositionEntry positionEntry = service.getEntry(new URL(entryUrl), PositionEntry.class);
printPositionEntry(positionEntry);
}
The getEntry call returns the position entry with the specified ticker ID.
The entryUrl parameter should be set to the portfolio's feed URL, with the ticker ID appended, in the following form:
http://finance.google.com/finance/feeds/default/portfolios/portfolioID/positions/TICKERID
A transaction is a collection of information about an instance of buying or selling a security.
A transaction feed lists all of the transactions that have been recorded for a particular position. Each transaction entry contains a transaction type (such as buy or sell, a number of units, the price, and so on.
You can use the Java client library to publish new transaction entries.
First, create a PortfolioEntry object to represent the transaction. Then you can set the title, content and other attributes of the transaction. Finally, use the FinanceService object to insert the transaction. Here's an example of how to publish a new transaction:
private static TransactionEntry makeTransactionEntry(String type,
String date, String shares, String price, String commission,
String currency, String notes) {
TransactionEntry entry = new TransactionEntry();
TransactionData data = new TransactionData();
if (type.equals("")) type = "Buy";
data.setType(type);
if (!date.equals("")) data.setDate(DateTime.parseDateTime(date +
"T00:00:00.000Z"));
if (!shares.equals(""))
data.setShares(Double.valueOf(shares).doubleValue());
if (!price.equals("")) {
Price p = new Price();
p.addMoney(new Money(Double.valueOf(price).doubleValue(), currency));
data.setPrice(p);
}
if (!commission.equals("")) {
Commission c = new Commission();
c.addMoney(new Money(Double.valueOf(commission).doubleValue(), currency));
data.setCommission(c);
}
if (!notes.equals("")) data.setNotes(notes);
entry.setTransactionData(data);
return entry;
}
private static void insertTransactionEntry(FinanceService service,
String feedUrl, TransactionEntry entry)
throws IOException, MalformedURLException, ServiceException {
System.out.println("Inserting Entry at location: " + feedUrl);
TransactionEntry insertedEntry = service.insert(new URL(feedUrl), entry);
}
Here's an example of how these methods might be used:
public static void main(String[] args) {
FinanceService service = new FinanceService("Google-PortfoliosDemo-1.0");
Scanner sc = new Scanner(System.in);
System.out.print("Enter user ID: ");
String userEmail = sc.nextLine();
System.out.print("Enter user password: ");
String userPassword = sc.nextLine();
if(!loginUser(service, userEmail, userPassword)) System.exit(0);
System.out.print("Enter transaction type: ");
String type = sc.nextLine();
System.out.print("Enter transaction date (yyyy-mm-dd): ");
String date = sc.nextLine();
System.out.print("Enter number of shares (optional, e.g. 100.0): ");
String shares = sc.nextLine();
System.out.print("Enter price (optional, e.g. 141.14): ");
String price = sc.nextLine();
System.out.print("Enter commission (optional, e.g. 20.0): ");
String commission = sc.nextLine();
System.out.print("Enter currency (optional, e.g. USD, EUR, JPY): ");
String currency = sc.nextLine();
System.out.print("Enter any notes: ");
String notes = sc.nextLine();
System.out.println("Enter portfolio ID: ");
String portfolioID = sc.nextLine();
System.out.println("Enter ticker (EXCHANGE:SYMBOL): ");
String tickerID = sc.nextLine();
TransactionEntry entry = makeTransactionEntry(
type, date, shares, price, commission, currency, notes);
String requestUrl = "http://finance.google.com/finance/feeds/default/portfolios";
requestUrl += portfolioID;
requestUrl += "/positions/";
requestUrl += tickerID;
requestUrl += "/transactions";
try {
insertTransactionEntry(service, requestUrl, entry);
} catch (IOException e) {
// Communication error.
System.err.println("There was a problem communicating with the service.");
e.printStackTrace();
} catch (ServiceException e) {
// Server side error.
System.err.println("The server had a problem handling your request.");
e.printStackTrace();
}
}
The insert method takes the service's post URL as a parameter. Then the method returns the entry as it was stored by Finance. The entry returned is the same one you sent, but it also contains various elements added by Finance, such as a transaction ID.
To retrieve a given position's transactions, call the getFeed method with the transaction feed URL:
private static void queryTransactionFeed(FinanceService service, String feedUrl)
throws IOException, MalformedURLException, ServiceException {
TransactionFeed transactionFeed = service.getFeed(new URL(feedUrl), TransactionFeed.class);
printBasicFeedDetails(transactionFeed);
for (int i = 0; i < transactionFeed.getEntries().size(); i++) {
TransactionEntry transactionEntry = transactionFeed.getEntries().get(i);
printTransactionEntry(transactionEntry);
}
}
The getFeed call returns a feed containing a list of entries, one for each transaction associated with the portfolio and position given in the feed URL.
The feedUrl parameter should be set to a transaction feed URL, of the following form:
http://finance.google.com/finance/feeds/default/portfolios/portfolioID/positions/TICKERID/transactions
Instead of retrieving a complete transaction feed, you can retrieve a specific individual entry.
The following method retrieves a specific transaction entry and prints out the data associated with the entry. The print methods for the data are shown in a later section (Displaying portfolio, position, and transaction data).
private static void queryTransactionEntry(FinanceService service, String entryUrl)
throws IOException, MalformedURLException, ServiceException {
TransactionEntry transactionEntry =
service.getEntry(new URL(entryUrl), TransactionEntry.class);
printTransactionEntry(transactionEntry);
}
The getEntry call returns the transaction entry with the specified transaction ID.
The entryUrl parameter should be set to the position's feed URL, with the transaction ID appended, in the following form:
http://finance.google.com/finance/feeds/default/portfolios/portfolioID/positions/TICKERID/transactions/transactionID
To update an existing transaction, first you retrieve the entry you want to update, then you modify it, and then you send it to Finance using the update method. The following code snippet modifies the title of a transaction entry, assuming that you've already retrieved the transaction from the server.
public static Entry updatePostTitle(FinanceService myService,
Entry entryToUpdate, String newTitle) throws ServiceException,
IOException {
entryToUpdate.setTitle(new PlainTextConstruct(newTitle));
URL editUrl = new URL(entryToUpdate.getEditLink().getHref());
return myService.update(editUrl, entryToUpdate);
}
The above code returns an Entry containing the entire newly-updated transaction. To update any other properties, simply set them in the Entry object before calling update.
To delete a transaction, pass the transaction's edit URL to the delete method on your FinanceService object, like this:
public static void deletePost(FinanceService myService, Entry entryToDelete)
throws ServiceException, IOException {
URL deleteUrl = new URL(entryToDelete.getEditLink().getHref());
myService.delete(deleteUrl);
}
Note: To update existing transactions, see Updating transactions; don't update by deleting transactions and then re-adding them.
Accompanying the sample Java client is a complete library for using portfolio, position, and transaction data. This section illustrates several methods which print all of the information contained in a feed, and the different feed entry types.
private static void printBasicFeedDetails(BaseFeed feed){
System.out.println("\tFeed is " + (feed.getCanPost() ? "writable!" : "read-only!"));
System.out.println("\tNumber of entries: " + feed.getTotalResults());
System.out.println("\tFeed URI: " + feed.getSelfLink().getHref() + "\n");
System.out.println("\tFeed Title: " + feed.getTitle().getPlainText());
System.out.println("\tAtom ID: " + feed.getId());
System.out.println("\tLast updated: " + feed.getUpdated());
System.out.println("\tFeed Categories:");
Iterator it = feed.getCategories().iterator();
while (it.hasNext()) {
System.out.println("\t\t" + it.next().toString());
}
System.out.println("\tLinks:");
if (feed.getLinks().size() == 0) {
System.out.println("\t\t");
}
for (int i = 0; i < feed.getLinks().size(); i++) {
System.out.println("\t\t" + feed.getLinks().get(i).getHref());
}
System.out.println("\t" + "HTML Link: " + feed.getHtmlLink().getHref());
}
private static void printBasicEntryDetails(BaseEntry entry){
System.out.println("\tTitle: " + entry.getTitle().getPlainText());
System.out.println("\tAtom ID: " + entry.getId());
System.out.println("\tLast updated: " + entry.getUpdated());
System.out.println("\tEntry Categories:");
Iterator it = entry.getCategories().iterator();
while (it.hasNext()) {
System.out.println("\t\t" + it.next().toString());
}
System.out.println("\tLinks:");
if (entry.getLinks().size() == 0) {
System.out.println("\t\t");
}
for (int i = 0; i < entry.getLinks().size(); i++) {
System.out.println("\t\t" + ((Link) (entry.getLinks().get(i))).getHref());
}
}
private static void printPortfolioEntry(PortfolioEntry portfolioEntry) {
System.out.println("\tFeed Link: " + portfolioEntry.getFeedLink().getHref());
PortfolioData portfolioData = portfolioEntry.getPortfolioData();
System.out.println("\tPortfolio Data:");
System.out.println("\t\tCurrency is " + portfolioData.getCurrencyCode());
System.out.printf("\t\tPercent Gain is %.2f%%\n", portfolioData.getGainPercentage() * 100.0);
System.out.println("\t\tReturns:");
System.out.printf("\t\t\tOne week: %.2f%%\n", portfolioData.getReturn1w() * 100.0);
System.out.printf("\t\t\tFour weeks: %.2f%%\n", portfolioData.getReturn4w() * 100.0);
System.out.printf("\t\t\tThree months: %.2f%%\n", portfolioData.getReturn3m() * 100.0);
System.out.printf("\t\t\tYear-to-date: %.2f%%\n", portfolioData.getReturnYTD() * 100.0);
System.out.printf("\t\t\tOne year: %.2f%%\n", portfolioData.getReturn1y() * 100.0);
System.out.printf("\t\t\tThree years: %.2f%%\n", portfolioData.getReturn3y() * 100.0);
System.out.printf("\t\t\tFive years: %.2f%%\n", portfolioData.getReturn5y() * 100.0);
System.out.printf("\t\t\tOverall: %.2f%%\n", portfolioData.getReturnOverall() * 100.0);
if (portfolioData.getCostBasis() == null) {
System.out.println("\t\tCost Basis not specified");
} else {
for (int i = 0; i < portfolioData.getCostBasis().getMoney().size(); i++) {
Money m = portfolioData.getCostBasis().getMoney().get(i);
System.out.printf("\t\tThis portfolio cost %.2f %s.\n", m.getAmount(), m.getCurrencyCode());
}
}
if (portfolioData.getDaysGain() == null) {
System.out.println("\t\tDay's Gain not specified");
} else {
for (int i = 0; i < portfolioData.getDaysGain().getMoney().size(); i++) {
Money m = portfolioData.getDaysGain().getMoney().get(i);
System.out.printf("\t\tThis portfolio made %.2f %s today.\n", m.getAmount(), m.getCurrencyCode());
}
}
if (portfolioData.getGain() == null) {
System.out.println("\t\tTotal Gain not specified");
} else {
for (int i = 0; i < portfolioData.getGain().getMoney().size(); i++) {
Money m = portfolioData.getGain().getMoney().get(i);
System.out.printf("\t\tThis portfolio has a total gain of %.2f %s.\n", m.getAmount(), m.getCurrencyCode());
}
}
if (portfolioData.getMarketValue() == null) {
System.out.println("\t\tMarket Value not specified");
} else {
for (int i = 0; i < portfolioData.getMarketValue().getMoney().size(); i++) {
Money m = portfolioData.getMarketValue().getMoney().get(i);
System.out.printf("\t\tThis portfolio is worth %.2f %s.\n", m.getAmount(), m.getCurrencyCode());
}
}
}
private static void printPositionEntry(PositionEntry positionEntry) {
printBasicEntryDetails(positionEntry);
System.out.println("\tFeed Link: " + positionEntry.getFeedLink().getHref());
System.out.println("\tTicker:");
System.out.println("\t\tExchange: " + positionEntry.getSymbol().getExchange());
System.out.println("\t\tSymbol: " + positionEntry.getSymbol().getSymbol());
System.out.println("\t\tFull Name: " + positionEntry.getSymbol().getFullName());
PositionData positionData = positionEntry.getPositionData();
System.out.println("\tPosition Data:");
System.out.printf("\t\tShare count: %.2f\n", positionData.getShares());
System.out.printf("\t\tPercent Gain is %.2f%%\n", positionData.getGainPercentage() * 100.0);
System.out.println("\t\tReturns:");
System.out.printf("\t\t\tOne week: %.2f%%\n", positionData.getReturn1w() * 100.0);
System.out.printf("\t\t\tFour weeks: %.2f%%\n", positionData.getReturn4w() * 100.0);
System.out.printf("\t\t\tThree months: %.2f%%\n", positionData.getReturn3m() * 100.0);
System.out.printf("\t\t\tYear-to-date: %.2f%%\n", positionData.getReturnYTD() * 100.0);
System.out.printf("\t\t\tOne year: %.2f%%\n", positionData.getReturn1y() * 100.0);
System.out.printf("\t\t\tThree years: %.2f%%\n", positionData.getReturn3y() * 100.0);
System.out.printf("\t\t\tFive years: %.2f%%\n", positionData.getReturn5y() * 100.0);
System.out.printf("\t\t\tOverall: %.2f%%\n", positionData.getReturnOverall() * 100.0);
if (positionData.getCostBasis() == null) {
System.out.println("\t\tCost Basis not specified");
} else {
for (int i = 0; i < positionData.getCostBasis().getMoney().size(); i++) {
Money m = positionData.getCostBasis().getMoney().get(i);
System.out.printf("\t\tThis position cost %.2f %s.\n", m.getAmount(), m.getCurrencyCode());
}
}
if (positionData.getDaysGain() == null) {
System.out.println("\t\tDay's Gain not specified");
} else {
for (int i = 0; i < positionData.getDaysGain().getMoney().size(); i++) {
Money m = positionData.getDaysGain().getMoney().get(i);
System.out.printf("\t\tThis position made %.2f %s today.\n", m.getAmount(), m.getCurrencyCode());
}
}
if (positionData.getGain() == null) {
System.out.println("\t\tTotal Gain not specified");
} else {
for (int i = 0; i < positionData.getGain().getMoney().size(); i++) {
Money m = positionData.getGain().getMoney().get(i);
System.out.printf("\t\tThis position has a total gain of %.2f %s.\n", m.getAmount(), m.getCurrencyCode());
}
}
if (positionData.getMarketValue() == null) {
System.out.println("\t\tMarket Value not specified");
} else {
for (int i = 0; i < positionData.getMarketValue().getMoney().size(); i++) {
Money m = positionData.getMarketValue().getMoney().get(i);
System.out.printf("\t\tThis position is worth %.2f %s.\n", m.getAmount(), m.getCurrencyCode());
}
}
}
/**
* Prints detailed contents for a transaction (i.e. a Transaction Feed entry)
*
* @param transactionEntry The transaction entry of interest
*/
private static void printTransactionEntry(TransactionEntry transactionEntry) {
TransactionData transactionData = transactionEntry.getTransactionData();
System.out.println("\tTransaction Data:");
System.out.println("\t\tType: " + transactionData.getType());
System.out.println("\t\tDate: " + transactionData.getDate());
System.out.printf("\t\tShares: %.2f\n", transactionData.getShares());
if (transactionData.getPrice() == null) {
System.out.println("\t\tPrice not specified");
} else {
for (int i = 0; i < transactionData.getPrice().getMoney().size(); i++) {
Money m = transactionData.getPrice().getMoney().get(i);
System.out.printf("\t\tThis transaction had a unit price of %.2f %s\n", m.getAmount(), m.getCurrencyCode());
}
}
if (transactionData.getCommission() == null) {
System.out.println("\t\tCommission not specified");
} else {
for (int i = 0; i < transactionData.getCommission().getMoney().size(); i++) {
Money m = transactionData.getCommission().getMoney().get(i);
System.out.printf("\t\tThis transaction had a commission of %.2f %s.\n", m.getAmount(), m.getCurrencyCode());
}
}
System.out.println("\t\tNotes: " +
(null == transactionData.getNotes() ? "none" : transactionData.getNotes()));
}