Skip to content

Commit

Permalink
add support for portfolio data via bds backend
Browse files Browse the repository at this point in the history
  • Loading branch information
johnlaing committed Jun 6, 2016
1 parent acec57e commit 2eef6ed
Show file tree
Hide file tree
Showing 6 changed files with 180 additions and 7 deletions.
1 change: 1 addition & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,6 @@ export(blpConnect,
getBars,
getMultipleTicks,
getTicks,
portfolio,
subscribe
)
4 changes: 4 additions & 0 deletions R/RcppExports.R
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ bds_Impl <- function(con_, securities, field, options_, overrides_, verbose, ide
.Call('Rblpapi_bds_Impl', PACKAGE = 'Rblpapi', con_, securities, field, options_, overrides_, verbose, identity_)
}

portfolio_Impl <- function(con_, securities, field, options_, overrides_, verbose, identity_) {
.Call('Rblpapi_portfolio_Impl', PACKAGE = 'Rblpapi', con_, securities, field, options_, overrides_, verbose, identity_)
}

beqs_Impl <- function(con, screenName, screenType, group, pitdate, languageId, verbose = FALSE) {
.Call('Rblpapi_beqs_Impl', PACKAGE = 'Rblpapi', con, screenName, screenType, group, pitdate, languageId, verbose)
}
Expand Down
60 changes: 60 additions & 0 deletions R/portfolio.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@

##
## Copyright (C) 2016 Whit Armstrong and Dirk Eddelbuettel and John Laing
##
## This file is part of Rblpapi
##
## Rblpapi is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 2 of the License, or
## (at your option) any later version.
##
## Rblpapi is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with Rblpapi. If not, see <http://www.gnu.org/licenses/>.


##' This function uses the Bloomberg API to retrieve 'portfolio' queries
##'
##' @title Run 'Portfolio Data' Queries
##' @param security A character value with a single security symbol in
##' Bloomberg notation.
##' @param field A character string with a single Bloomberg query field.
##' @param options An optional named character vector with option
##' values. Each field must have both a name (designating the option
##' being set) as well as a value.
##' @param overrides An optional named character vector with override
##' values. Each field must have both a name (designating the override
##' being set) as well as a value.
##' @param verbose A boolean indicating whether verbose operation is
##' desired, defaults to \sQuote{FALSE}
##' @param identity An optional identity object.
##' @param con A connection object as created by a \code{blpConnect}
##' call, and retrieved via the internal function
##' \code{defaultConnection}.
##' @return A list with as many entries as there are entries in
##' \code{securities}; each list contains a data.frame with one row
##' per observations and as many columns as entries in
##' \code{fields}. If the list is of length one, it is collapsed into
##' a single data frame.
##' @author John Laing
## TODO: examples. Do global portfolios exist so that examples will
## work for everyone? Otherwise I don't know how to do this.
portfolio <- function(security, field, options=NULL, overrides=NULL,
verbose=FALSE, identity=NULL,
con=defaultConnection()) {
if (length(security) != 1L)
stop("more than one security submitted.", call.=FALSE)
if (length(field) != 1L)
stop("more than one field submitted.", call.=FALSE)
res <- portfolio_Impl(con, security, field, options, overrides, verbose, identity)
if (typeof(res)=="list" && length(res)==1) {
res <- res[[1]]
}
res
}

46 changes: 46 additions & 0 deletions man/portfolio.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

17 changes: 17 additions & 0 deletions src/RcppExports.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,23 @@ BEGIN_RCPP
return __result;
END_RCPP
}
// portfolio_Impl
Rcpp::List portfolio_Impl(SEXP con_, std::vector<std::string> securities, std::string field, SEXP options_, SEXP overrides_, bool verbose, SEXP identity_);
RcppExport SEXP Rblpapi_portfolio_Impl(SEXP con_SEXP, SEXP securitiesSEXP, SEXP fieldSEXP, SEXP options_SEXP, SEXP overrides_SEXP, SEXP verboseSEXP, SEXP identity_SEXP) {
BEGIN_RCPP
Rcpp::RObject __result;
Rcpp::RNGScope __rngScope;
Rcpp::traits::input_parameter< SEXP >::type con_(con_SEXP);
Rcpp::traits::input_parameter< std::vector<std::string> >::type securities(securitiesSEXP);
Rcpp::traits::input_parameter< std::string >::type field(fieldSEXP);
Rcpp::traits::input_parameter< SEXP >::type options_(options_SEXP);
Rcpp::traits::input_parameter< SEXP >::type overrides_(overrides_SEXP);
Rcpp::traits::input_parameter< bool >::type verbose(verboseSEXP);
Rcpp::traits::input_parameter< SEXP >::type identity_(identity_SEXP);
__result = Rcpp::wrap(portfolio_Impl(con_, securities, field, options_, overrides_, verbose, identity_));
return __result;
END_RCPP
}
// beqs_Impl
DataFrame beqs_Impl(SEXP con, std::string screenName, std::string screenType, std::string group, std::string pitdate, std::string languageId, bool verbose);
RcppExport SEXP Rblpapi_beqs_Impl(SEXP conSEXP, SEXP screenNameSEXP, SEXP screenTypeSEXP, SEXP groupSEXP, SEXP pitdateSEXP, SEXP languageIdSEXP, SEXP verboseSEXP) {
Expand Down
59 changes: 52 additions & 7 deletions src/bds.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ Rcpp::List bulkArrayToDf(Element& fieldData) {
return buildDataFrame(lazy_frame);
}

Rcpp::List BulkDataResponseToDF(Event& event, std::string& requested_field, bool verbose) {
Rcpp::List BulkDataResponseToDF(Event& event, std::string& requested_field, std::string response_type, bool verbose) {
MessageIterator msgIter(event);
if(!msgIter.next()) {
throw std::logic_error("Not a valid MessageIterator.");
Expand All @@ -222,8 +222,8 @@ Rcpp::List BulkDataResponseToDF(Event& event, std::string& requested_field, bool
Message msg = msgIter.message();
Element response = msg.asElement();
if (verbose) response.print(Rcpp::Rcout);
if(std::strcmp(response.name().string(),"ReferenceDataResponse")) {
throw std::logic_error("Not a valid ReferenceDataResponse.");
if(std::strcmp(response.name().string(),response_type.c_str())) {
throw std::logic_error("Not a valid " + response_type + ".");
}
Element securityData = response.getElement("securityData");

Expand All @@ -247,11 +247,11 @@ Rcpp::List BulkDataResponseToDF(Event& event, std::string& requested_field, bool

// only allow one field for bds in contrast to bdp
// [[Rcpp::export]]
Rcpp::List bds_Impl(SEXP con_, std::vector<std::string> securities,
Rcpp::List bds_Impl(SEXP con_, std::vector<std::string> securities,
std::string field, SEXP options_, SEXP overrides_,
bool verbose, SEXP identity_) {

Session* session =
Session* session =
reinterpret_cast<Session*>(checkExternalPointer(con_, "blpapi::Session*"));

std::vector<std::string> field_types;
Expand All @@ -269,15 +269,60 @@ Rcpp::List bds_Impl(SEXP con_, std::vector<std::string> securities,
request.getElement("fields").appendValue(field.c_str());
appendOptionsToRequest(request,options_);
appendOverridesToRequest(request,overrides_);


sendRequestWithIdentity(session, request, identity_);

while (true) {
Event event = session->nextEvent();
switch (event.eventType()) {
case Event::RESPONSE:
case Event::PARTIAL_RESPONSE:
return BulkDataResponseToDF(event, field, "ReferenceDataResponse", verbose);
break;
default:
MessageIterator msgIter(event);
while (msgIter.next()) {
Message msg = msgIter.message();
//FIXME:: capture messages here for debugging
}
}
if (event.eventType() == Event::RESPONSE) { break; }
}
return R_NilValue;
}

// [[Rcpp::export]]
Rcpp::List portfolio_Impl(SEXP con_, std::vector<std::string> securities,
std::string field, SEXP options_, SEXP overrides_,
bool verbose, SEXP identity_) {

Session* session =
reinterpret_cast<Session*>(checkExternalPointer(con_, "blpapi::Session*"));

std::vector<std::string> field_types;

const std::string rdsrv = "//blp/refdata";
if (!session->openService(rdsrv.c_str())) {
Rcpp::stop("Failed to open " + rdsrv);
}

Service refDataService = session->getService(rdsrv.c_str());
Request request = refDataService.createRequest("PortfolioDataRequest");
for (size_t i = 0; i < securities.size(); i++) {
request.getElement("securities").appendValue(securities[i].c_str());
}
request.getElement("fields").appendValue(field.c_str());
appendOptionsToRequest(request,options_);
appendOverridesToRequest(request,overrides_);

sendRequestWithIdentity(session, request, identity_);

while (true) {
Event event = session->nextEvent();
switch (event.eventType()) {
case Event::RESPONSE:
case Event::PARTIAL_RESPONSE:
return BulkDataResponseToDF(event, field, verbose);
return BulkDataResponseToDF(event, field, "PortfolioDataResponse", verbose);
break;
default:
MessageIterator msgIter(event);
Expand Down

0 comments on commit 2eef6ed

Please sign in to comment.