Thomas Russell: Programmer & Designer
Have a browse of my thoughts!

Getting stock price in C++

It seems to be a common problem that people wish to be able to get the current price of a particular stock/share, so I figured it would be a good idea to write a brief article on the easiest way to get the current stock price using native C++.

In this article, I will be making extensive use of the C++REST SDK, also known as Casablanca. It is an open-source, cross-platform SDK initially developed by Microsoft. I will also be using the Yahoo! Finance query engine as the data-source for our query.

I will be working with Visual Studio, which makes Casablanca trivial to install and use; simply right-click on your project and select “Manage NuGet Packages…”, then search for cpprestsdk and install it. If you are not using Visual Studio, you can find comprehensive installation instructions here.

Once the C++REST SDK is installed, we can begin writing our stock price retriever. We will be using the http_client class to send our HTTP request to the Yahoo! query engine, we do this by constructing an http_client object with the URI in the constructor:

#include <cpprest\http_client.h>

double GetStockPrice( const utility::string_t& stockTicker ) noexcept(false)
{
	web::http::client::http_client webClient( U( "http://query.yahooapis.com/v1/public/" ) );
}

It is useful to note that the U macro appears often in the C++REST SDK, and is used to construct platform independent strings from string literals.

Now we have created our HTTP client, we need to construct our query; we can use the YQL Console to determine the right syntax for our query and how to parse the response. If we wished to get the price of say the YHOO ticker; we can run the following SQL query and analyze the response in the console:

SELECT * FROM yahoo.finance.quote WHERE symbol = "YHOO"

And the JSON response is:

{
  "query": {
    "count": 1,
    "created": "2015-08-23T17:44:51Z",
    "lang": "en-US",
    "results": {
      "quote": {
        "symbol": "YHOO",
        "AverageDailyVolume": "12296700",
        "Change": "-1.17",
        "DaysLow": "32.91",
        "DaysHigh": "34.02",
        "YearLow": "32.91",
        "YearHigh": "52.62",
        "MarketCapitalization": "31.00B",
        "LastTradePriceOnly": "32.93",
        "DaysRange": "32.91 - 34.02",
        "Name": "Yahoo! Inc.",
        "Symbol": "YHOO",
        "Volume": "18373641",
        "StockExchange": "NMS"
      }
    }
  }
}

From this we can see that the main field that we care about is the “LastTradePriceOnly” key, so we can narrow down our SQL query even further:

SELECT LastTradePriceOnly FROM yahoo.finance.quote WHERE symbol = "YHOO"

If we test this query using the YQL Console, we can see that it helpfully provides the full URI for the REST query:

https://query.yahooapis.com/v1/public/yql?q=SELECT%20LastTradePriceOnly%20FROM%20yahoo.finance.quote%20WHERE%20symbol%20%3D%20%22YHOO%22&format=json&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys

Now it is a simple matter of building this in the C++REST SDK; using the uri_builder class, and then sending the request via the http_client:

// Build the query URI:
web::uri_builder uriBuilder( U( "/yql" ) );
	
utility::string_t query = U("SELECT LastTradePriceOnly FROM yahoo.finance.quote WHERE symbol = \"");
query += stockTicker + U("\"");

uriBuilder.append_query( U( "q" ), query );
uriBuilder.append_query( U( "format" ), U( "json" ) );
uriBuilder.append_query( U( "env" ), U( "store://datatables.org/alltableswithkeys" ) );

web::http::http_response response = webClient.request( web::http::methods::GET, uriBuilder.to_string() ).get();

We now need to decompose our JSON result using the objects and methods in the web::json namespace. However, first we need to check that our HTTP response was successful (code 200):

switch( response.status_code() )
{
	case 200:
	{
		// HTTP Success Code:
		try {
			web::json::object jsonResponse = response.extract_json().get().as_object();

			web::json::object queryResults = jsonResponse.at( U( "query" ) ).as_object().at( U("results") ).as_object();
			web::json::object quoteObject = queryResults.at( U( "quote" ) ).as_object();
			web::json::value quotePrice = quoteObject.at( U( "LastTradePriceOnly" ) );

			// Get rid of the quote marks around the price; 
			// for some reason the YAHOO! API sends it as
			// a string:
			utility::string_t priceString = quotePrice.serialize();
			priceString.pop_back();
			priceString = priceString.substr( 1U );

			return std::stod( priceString );
		}
		catch( web::json::json_exception& exception )
		{
			// We couldn't find the correct path within
			// our JSON object, so return NaN:
			return std::numeric_limits<double>::quiet_NaN();
		}
		catch( ... )
		{
			// Something very bad happened, we should
			// probably deal with this further up
			// the call-chain:
			throw;
		}

		break;
	}
	default:
	{
		// The response failed, so return NaN:
		return std::numeric_limits<double>::quiet_NaN();
	}
}

That’s it! We have written a fully functioning method to retrieve the stock price of a specified ticker. We can test it using the following:

int main()
{
	std::cout << "YHOO: " << GetStockPrice( U( "YHOO" ) ) << std::endl;
	std::cout << "GOOG: " << GetStockPrice( U( "GOOG" ) ) << std::endl;
}

And we should get something like the following:

Stock Price test results

ZIP containing .cpp file: StockPriceRetriever

Leave a Reply

Your email address will not be published. Required fields are marked *

Designed and Produced by Thomas Russell © 2014-2017

Log-in | Register