Hi Aaron,
You might find the files below useful as a starting point if you want to add
this functionality (you’ll also have to add beqs and bport to NAMESPACE). This
unfinished implementation can retrieve data from Bloomberg, but it still has to
be converted properly to R data frames (or whatever structure makes sense
depending on the type of response).
Best regards,
Carlos
> bport("U1234567-1 Client")
PortfolioDataResponse = {
securityData[] = {
securityData = {
security = "U1234567-1 Client"
eidData[] = {
}
fieldExceptions[] = {
}
sequenceNumber = 0
fieldData = {
PORTFOLIO_MEMBERS[] = {
PORTFOLIO_MEMBERS = {
Security = "..... Equity"
}
...... ...... ...... ...... ...... ...... ......
Error: Unsupported datatype: BLPAPI_DATATYPE_SEQUENCE.
> beqs("Insider Buyers","GLOBAL","Popular")
BeqsResponse = {
data = {
fieldDisplayUnits = {
Ticker = ""
Short Name = ""
Market Cap = ""
GICS Sector = ""
Cntry = ""
}
securityData[] = {
securityData = {
security = "AAPL US"
fieldExceptions[] = {
}
fieldData = {
Ticker = "AAPL US"
Short Name = "APPLE INC"
Market Cap = 667446607872.000000
GICS Sector = "Information Technology"
Cntry = "United States"
}
}
...... ...... ...... ...... ...... ...... ......
[1] Cntry GICS Sector Market Cap Short Name Ticker
<0 rows> (or 0-length row.names)
========
R/bport.R
========
bport <- function(portid, fields="MEMBERS", date=NULL, identity=NULL,
con=.pkgenv$con) {
if (!(fields %in% c("MEMBERS","MPOSITION","MWEIGHT","DATA"))) stop("Fields
should be one of MEMBERS, MPOSITION, MWEIGHT, DATA.", call.=FALSE)
bport_Impl(con, portid, paste("PORTFOLIO_",fields,sep=""), date, identity)
}
========
R/beqs.R
========
beqs <- function(name, type="PRIVATE", group=NULL, languageId=NULL,
identity=NULL, con=.pkgenv$con) {
if (!(type %in% c("PRIVATE","GLOBAL"))) stop("Type should be PRIVATE or
GLOBAL.", call.=FALSE)
beqs_Impl(con, name, type, group, languageId, identity)
}
========
src/bport.cpp
========
#include <iostream>
#include <vector>
#include <string>
#include <blpapi_session.h>
#include <blpapi_service.h>
#include <blpapi_request.h>
#include <blpapi_event.h>
#include <blpapi_message.h>
#include <blpapi_element.h>
#include <Rcpp.h>
#include <blpapi_utils.h>
using BloombergLP::blpapi::Session;
using BloombergLP::blpapi::Service;
using BloombergLP::blpapi::Request;
using BloombergLP::blpapi::Event;
using BloombergLP::blpapi::Element;
using BloombergLP::blpapi::Message;
using BloombergLP::blpapi::MessageIterator;
void getPortfolioDataResult(Event& event, LazyFrameT& lazy_frame) {
Rcpp::List ans;
MessageIterator msgIter(event);
if (!msgIter.next()) {
throw std::logic_error("Not a valid MessageIterator.");
}
Message msg = msgIter.message();
msg.print(Rcpp::Rcerr);
Element response = msg.asElement();
if (std::strcmp(response.name().string(),"PortfolioDataResponse")) {
throw std::logic_error("Not a valid PortfolioDataResponse.");
}
Element securityData = response.getElement("securityData");
for (size_t i = 0; i < securityData.numValues(); ++i) {
Element this_security = securityData.getValueAsElement(i);
Element fieldData = this_security.getElement("fieldData");
for(size_t j = 0; j < fieldData.numElements(); ++j) {
Element e = fieldData.getElement(j);
LazyFrameIteratorT iter =
assertColumnDefined(lazy_frame,e,securityData.numValues());
populateDfRow(iter->second,i,e);
}
}
}
// Simpler interface with std::vector<std::string> thanks to Rcpp::Attributes
//
// [[Rcpp::export]]
SEXP bport_Impl(SEXP con_, std::vector<std::string> securities,
std::vector<std::string> fields,
SEXP date_, SEXP identity_) {
// via Rcpp Attributes we get a try/catch block with error propagation to R
"for free"
Session* session =
reinterpret_cast<Session*>(checkExternalPointer(con_,
"blpapi::Session*"));
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");
request.getElement("securities").appendValue(securities[0].c_str());
request.getElement("fields").appendValue(fields[0].c_str());
if (date_ != R_NilValue) {
Element overrides = request.getElement("overrides");
Element override = overrides.appendElement();
override.setElement("fieldId","REFERENCE_DATE");
override.setElement("value", Rcpp::as<std::string>(date_).c_str());
}
sendRequestWithIdentity(session, request, identity_);
LazyFrameT lazy_frame;
while (true) {
Event event = session->nextEvent();
//REprintf("%d\n",event.eventType());
switch (event.eventType()) {
case Event::RESPONSE:
case Event::PARTIAL_RESPONSE:
getPortfolioDataResult(event, lazy_frame);
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 buildDataFrame(lazy_frame, false, false);
}
========
src/beqs.cpp
========
#include <iostream>
#include <vector>
#include <string>
#include <blpapi_session.h>
#include <blpapi_service.h>
#include <blpapi_request.h>
#include <blpapi_event.h>
#include <blpapi_message.h>
#include <blpapi_element.h>
#include <Rcpp.h>
#include <blpapi_utils.h>
using BloombergLP::blpapi::Session;
using BloombergLP::blpapi::Service;
using BloombergLP::blpapi::Request;
using BloombergLP::blpapi::Event;
using BloombergLP::blpapi::Element;
using BloombergLP::blpapi::Message;
using BloombergLP::blpapi::MessageIterator;
void getBeqsResult(Event& event, LazyFrameT& lazy_frame) {
MessageIterator msgIter(event);
if (!msgIter.next()) {
throw std::logic_error("Not a valid MessageIterator.");
}
Message msg = msgIter.message();
msg.print(Rcpp::Rcerr);
Element response = msg.asElement();
if (std::strcmp(response.name().string(),"BeqsResponse")) {
throw std::logic_error("Not a valid BeqsResponse.");
}
if (msg.hasElement("responseError")){
msg.print(Rcpp::Rcerr);
}
Element securityData =
response.getElement("data").getElement("securityData");
for (size_t i = 0; i < securityData.numValues(); ++i) {
Element this_security = securityData.getValueAsElement(i);
Element fieldData = this_security.getElement("fieldData");
for(size_t j = 0; j < fieldData.numElements(); ++j) {
Element e = fieldData.getElement(j);
LazyFrameIteratorT iter =
assertColumnDefined(lazy_frame,e,securityData.numValues());
populateDfRow(iter->second,i,e);
}
}
}
// Simpler interface with std::vector<std::string> thanks to Rcpp::Attributes
//
// [[Rcpp::export]]
SEXP beqs_Impl(SEXP con_, std::string name, std::string type,
SEXP group_, SEXP languageId_, SEXP identity_) {
// via Rcpp Attributes we get a try/catch block with error propagation to R
"for free"
Session* session =
reinterpret_cast<Session*>(checkExternalPointer(con_,
"blpapi::Session*"));
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("BeqsRequest");
request.set ("screenName", name.c_str());
request.set ("screenType", type.c_str());
if (group_ != R_NilValue) {
request.set ("Group", Rcpp::as<std::string>(group_).c_str());
}
if (languageId_ != R_NilValue) {
request.set ("languageId", Rcpp::as<std::string>(languageId_).c_str());
}
sendRequestWithIdentity(session, request, identity_);
LazyFrameT lazy_frame;
while (true) {
Event event = session->nextEvent();
//REprintf("%d\n",event.eventType());
switch (event.eventType()) {
case Event::RESPONSE:
case Event::PARTIAL_RESPONSE:
getBeqsResult(event, lazy_frame);
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 buildDataFrame(lazy_frame, false, false);
}
> On 17 Aug 2015, at 23:49, Aaron Goldenberg <[email protected]> wrote:
>
> This is incredibly helpful! Thank you! Are there plans to include portfolio
> calls in future releases? Is this something you would like help
> implementing?
>
> [[alternative HTML version deleted]]
>
> _______________________________________________
> [email protected] mailing list
> https://stat.ethz.ch/mailman/listinfo/r-sig-finance
> -- Subscriber-posting only. If you want to post, subscribe first.
> -- Also note that this is not the r-help list where general R questions
> should go.
_______________________________________________
[email protected] mailing list
https://stat.ethz.ch/mailman/listinfo/r-sig-finance
-- Subscriber-posting only. If you want to post, subscribe first.
-- Also note that this is not the r-help list where general R questions should
go.