This post is a continuation of my previous post where I used jsoncpp package to fetch exchange rates from fixer.io. In this post I have reused the above code and used it to fetch stock historical price data using C++ and save the fetched data to a external CSV file. You can edit the api url(https://query.yahooapis.com) to pass parameters for stock details and start/ending dates
#include <string.h>
#include <iostream>
#include <stdio.h>
#include <jsoncpp/json/json.h>
#include <curl/curl.h>
#include<fstream>
//writing call back function for storing fetched values in memory
static size_t WriteCallback(void *contents, size_t size, size_t nmemb, void *userp)
{
((std::string*)userp)->append((char*)contents, size * nmemb);
return size * nmemb;
}
int main(void)
{
std::string readBuffer;
//global initiliation of curl before calling a function
curl_global_init( CURL_GLOBAL_ALL );
//creating session handle
CURL * myHandle;
// We’ll store the result of CURL’s webpage retrieval, for simple error checking.
CURLcode result;
// notice the lack of major error-checking, for brevity
myHandle = curl_easy_init ( ) ;
//after creating handle we ill start transfering webpage
//curl_easy_setopt is used to tell libcurl how to behave.
//By setting the appropriate options, the application can change libcurl's behavior.
//CURLOPT_URL provide the URL to use in the request. Pass in a pointer to the URL to work with.
//sample json output >> {"base":"EUR","date":"2016-07-22","rates":{"GBP":0.84108,"USD":1.1014}}
curl_easy_setopt(myHandle, CURLOPT_URL, "https://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20yahoo.finance.historicaldata%20where%20symbol%20%3D%20%22YHOO%22%20and%20startDate%20%3D%20%222009-09-11%22%20and%20endDate%20%3D%20%222010-03-10%22&format=json&diagnostics=true&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys&callback=");
//adding a user agent
curl_easy_setopt(myHandle, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows; U; Windows NT 6.1; rv:2.2) Gecko/20110201");
/* send all data to this function */
curl_easy_setopt(myHandle, CURLOPT_WRITEFUNCTION, WriteCallback);
/* we pass our 'chunk' struct to the callback function */
curl_easy_setopt(myHandle, CURLOPT_WRITEDATA, &readBuffer);
//perform a blocking file transfer
result = curl_easy_perform( myHandle );
/* check for errors */
if(result != CURLE_OK) {
fprintf(stderr, "curl_easy_perform() failed: %s\n",
curl_easy_strerror(result));
}
else {
/*
* Now, our chunk.memory points to a memory block that is chunk.size
* bytes big and contains the remote file.
*
* Do something nice with it!
*/
//std::cout << readBuffer << std::endl;
//json parsing
Json::Value root; // will contains the root value after parsing.
Json::Reader reader;
bool parsingSuccessful = reader.parse( readBuffer, root );
if(not parsingSuccessful)
{
// Report failures and their locations
// in the document.
std::cout<<"Failed to parse JSON"<<std::endl
<<reader.getFormatedErrorMessages()
<<std::endl;
return 1;
}else{
std::cout<<"\nSucess parsing json\n"<<std::endl;
//std::cout << root<< std::endl;
std::cout <<"No of Days = "<< root["query"]["count"].asInt() << std::endl;
//for opening and writng files
std::ofstream file;
//directory for saving your csv
file.open("/dir/stock.csv");
//assigning csv column names
file<<"Symbol,Date,Open,High,Low,Close,Adj Close,Volume\n";
//json value for fetching quotes
const Json::Value& quotes = root["query"]["results"]["quote"];
//looping through the Yahoo quote list
for (int i = 0; i < quotes.size(); i++){
std::cout << " Symbol: " << quotes[i]["Symbol"].asString();
std::cout << " Date: " << quotes[i]["Date"].asString();
std::cout << " Open: " << quotes[i]["Open"].asString();
std::cout << " High: " << quotes[i]["High"].asString();
std::cout << " Low: " << quotes[i]["Low"].asString();
std::cout << " Close: " << quotes[i]["Close"].asString();
std::cout << "AdjClose: " << quotes[i]["Adj_Close"].asString();
std::cout << " Volume: " << quotes[i]["Volume"].asString();
std::cout << std::endl;
file << quotes[i]["Symbol"].asString()<<","<<quotes[i]["Date"].asString()<<","\
<< quotes[i]["Open"].asString()<<","<<quotes[i]["High"].asString()<<","\
<< quotes[i]["Low"].asString()<<","<<quotes[i]["Close"].asString()<<","\
<< quotes[i]["Adj_Close"].asString()<<","<<quotes[i]["Volume"].asString()<<std::endl;
}
file.close();
}
}
//End a libcurl easy handle.This function must be the last function to call for an easy session
curl_easy_cleanup( myHandle );
return 0;
}