diff --git a/.gitignore b/.gitignore index 9d609f4..e308df9 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,5 @@ script/upload* *.jar build R/bin +.Rproj.user +blpwrapper.Rproj diff --git a/java/src/org/findata/blpwrapper/BeqsDataResult.java b/java/src/org/findata/blpwrapper/BeqsDataResult.java new file mode 100644 index 0000000..f9531ea --- /dev/null +++ b/java/src/org/findata/blpwrapper/BeqsDataResult.java @@ -0,0 +1,127 @@ +package org.findata.blpwrapper; + +import com.bloomberglp.blpapi.*; + +import java.util.logging.Logger; + +public class BeqsDataResult extends DataResult { + private String[] fields; + private String[] securities; + private String[] data_types; + private String[][] result_data; + + public BeqsDataResult() { + // With BEQS we do not know the size of the result data until + // we process response, so we cannot pre initialise the output + + } + + public String[][] getData() { + return(result_data); + } + + public String[] getColumnNames() { + return(fields); + } + + public String[] getRowNames() { + return(securities); + } + + public String[] getDataTypes() { + return(data_types); + } + + public void processResponse(Element response, Logger logger, boolean throwInvalidTickerError) throws WrapperException { + logger.finest("BeqsDataResult: Processing response"); + + Element dataElement = response.getElement("data"); + Element securityDataArray = dataElement.getElement("securityData"); + + int numItems = securityDataArray.numValues(); + logger.finest("BeqsDataResult: Number of securities is " + numItems); + if (numItems == 0 ){ + logger.info("No securities in response"); + securities = new String[0]; + fields = new String[0]; + data_types = new String[0]; + result_data = new String[0][0]; + return; + } + + securities = new String[numItems]; + + // Use the number of fields in the first security to size the results_data array + Element fldData = dataElement.getElement("fieldDisplayUnits"); + int numCols = fldData.numElements(); + fields = new String[numCols]; + + data_types = new String[fields.length]; + // Because we may get data type info out of order, need to + // initialize array at start with a default value. + // get the names of each field/column from fieldDisplayUnits + + for (int i = 0; i < fields.length; i++) { + // Call this "NOT_APPLICABLE" since "NA" causes problems in R. + data_types[i] = "NOT_APPLICABLE"; + fields[i] = fldData.getElement(i).name().toString(); + } + + logger.finest("BeqsDataResult: Number of fields is " + fields.length); + + result_data = new String[securities.length][fields.length]; + + + for (int i = 0; i < numItems; i++) { +logger.finest("***"); +Element securityData = securityDataArray.getValueAsElement(i); + Element fieldData = securityData.getElement("fieldData"); + String sec = securityData.getElementAsString("security"); + + processSecurityError(securityData, logger, throwInvalidTickerError); + processFieldExceptions(securityData, logger); + + int field_data_counter = 0; + for (int j = 0; j < fields.length; j++) { + String field_name = fields[j]; + + if (field_data_counter < fieldData.numElements()) { + logger.finest("i = " + i + "\n" + " security = " + sec + "\n" + " j = " + j + "\n" + " field_data_counter = " + field_data_counter); + Element field = fieldData.getElement(field_data_counter); + + if (field.name().toString().equals(field_name)) { + // Raise an error if we're trying to read SEQUENCE data. + // Store the data type for later (if it hasn't already been stored). + if (data_types[j].equals("NOT_APPLICABLE")) { + if (field.datatype().intValue() == Schema.Datatype.Constants.SEQUENCE) { + throw new WrapperException("reference data request cannot handle SEQUENCE data in field " + field.name().toString()); + } + String data_type = field.datatype().toString(); + if (!data_type.equals("NA")) { + logger.finest("Setting field data type to " + data_type); + data_types[j] = data_type; + } + } else { + logger.finest("Field data type is " + data_types[j]); + } + + String value = field.getValueAsString(); + + logger.finest("Setting field value to " + value); + field_data_counter++; + logger.finest("field_data_counter = " + field_data_counter); + + if (value.equals("-2.4245362661989844E-14")) { + logger.info("Numeric of -2.4245362661989844E-14 encountered. Not a real value. Will be left NULL."); + } else { + result_data[i][j] = value; + } + } else { + logger.finest("Skipping field as does not match."); + } + } + + } + } + } +} diff --git a/java/src/org/findata/blpwrapper/Connection.java b/java/src/org/findata/blpwrapper/Connection.java index 03d56d3..8830b36 100644 --- a/java/src/org/findata/blpwrapper/Connection.java +++ b/java/src/org/findata/blpwrapper/Connection.java @@ -31,6 +31,7 @@ public class Connection { private String histdata_request_name = "HistoricalDataRequest"; private String intraday_tick_request_name = "IntradayTickRequest"; private String intraday_bar_request_name = "IntradayBarRequest"; + private String beqs_request_name = "BeqsRequest"; private String apifields_service_name = "//blp/apiflds"; private boolean apifields_service_open = false; @@ -47,7 +48,8 @@ public class Connection { public static final int FIELD_INFO_RESULT = 4; public static final int INTRADAY_TICK_RESULT = 5; public static final int INTRADAY_BAR_RESULT = 6; - + public static final int BEQS_RESULT = 7; + public static final int MB = 1048576; public static final String DATETIME_OPTION_NAMES[] = { @@ -163,8 +165,9 @@ public CorrelationID nextCorrelationID(int result_type, String[] securities, Str case BULK_DATA_RESULT: result = new BulkDataResult(securities, fields); break; case HISTORICAL_DATA_RESULT: result = new HistoricalDataResult(securities, fields); break; case FIELD_INFO_RESULT: result = new FieldInfoResult(securities); break; - case INTRADAY_TICK_RESULT: result = new IntradayTickDataResult(securities, fields); break; - case INTRADAY_BAR_RESULT: result = new IntradayBarDataResult(securities, fields); break; + case INTRADAY_TICK_RESULT: result = new IntradayTickDataResult(securities, fields); break; + case INTRADAY_BAR_RESULT: result = new IntradayBarDataResult(securities, fields); break; + case BEQS_RESULT: result = new BeqsDataResult(); break; default: throw new WrapperException("unknown result_type " + result_type); } if (response_cache.add(result)) { @@ -309,6 +312,47 @@ private CorrelationID sendRefDataRequest(int result_type, String request_name, S return(correlation_id); } + + private CorrelationID sendBeqsDataRequest(int result_type, String request_name, String screenName, String screenType, String languageId, String Group, String AsOfDate) throws Exception { + Service service = getRefDataService(); + Request request = service.createRequest(request_name); + + request.set("screenName", screenName); + + request.set("screenType", screenType); + + if( !languageId.equals("") ){ + request.set("languageId", languageId); + } + + if( !Group.equals("") ){ + request.set("Group", Group); + } + + if ( !AsOfDate.equals("") ) { + Element override_values_element = request.getElement("overrides"); + Element override = override_values_element.appendElement(); + override.setElement("fieldId", "PiTDate"); + override.setElement("value", AsOfDate); + logger.fine("override PiTDate set to " + AsOfDate); + } + + // BEQSRequest does not have the securities or fields elements as they are defined using the BEQS + // function on the terminal when defining a screen. But create dummy ones as nextCorrelationID expects it + + + String[] securities = new String[0]; + String[] fields = new String[0]; + + CorrelationID correlation_id = nextCorrelationID(result_type, securities, fields); + if (identity == null) { + session.sendRequest(request, correlation_id); + } else { + session.sendRequest(request, identity, correlation_id); + } + return(correlation_id); + } + private void processEventLoop() throws java.lang.InterruptedException, WrapperException { processEventLoop(0); } @@ -394,6 +438,7 @@ private void processResponseEvent(int result_type, Event event) throws WrapperEx case FIELD_INFO_RESULT: result = (FieldInfoResult)response_cache.get(response_id); break; case INTRADAY_TICK_RESULT: result = (IntradayTickDataResult)response_cache.get(response_id); break; case INTRADAY_BAR_RESULT: result = (IntradayBarDataResult)response_cache.get(response_id); break; + case BEQS_RESULT: result = (BeqsDataResult)response_cache.get(response_id); break; default: throw new WrapperException("unknown result_type " + result_type); } @@ -584,6 +629,51 @@ public DataResult bls(String security, String field, String[] override_fields, S return(data_result); } +/** + * Might have to overload this function to get it to work + * Have modelled it on blp. + * / + */ + + public DataResult beqs(String screenName) throws Exception { + String screenType = "PRIVATE"; + String languageId = "ENGLISH"; + String Group = ""; + String AsOfDate = ""; + return(beqs(screenName, screenType, languageId, Group, AsOfDate)); + } + + public DataResult beqs(String screenName, String AsOfDate) throws Exception { + String screenType = "PRIVATE"; + String languageId = "ENGLISH"; + String Group = ""; + return(beqs(screenName, screenType, languageId, Group, AsOfDate)); + } + + public DataResult beqs(String screenName, String Group, String AsOfDate) throws Exception { + String screenType = "PRIVATE"; + String languageId = "ENGLISH"; + return(beqs(screenName, screenType, languageId, Group, AsOfDate)); + } + + public DataResult beqs(String screenName, String screenType, String languageId, String Group) throws Exception { + String AsOfDate = ""; + return(beqs(screenName, screenType, languageId, Group, AsOfDate)); + } + + + public DataResult beqs(String screenName, String screenType, String languageId, String Group, String AsOfDate) throws Exception { + int response_id = (int)sendBeqsDataRequest(BEQS_RESULT, beqs_request_name, screenName, screenType, languageId, Group, AsOfDate).value(); + processEventLoop(BEQS_RESULT); + DataResult data_result = (DataResult)response_cache.get(response_id); + if (!cache_responses) { + response_cache.set(response_id, null); + } + return(data_result); + } + + + public DataResult tick(String security, String[] event_types, String start_date_time, String end_date_time) throws Exception { String[] option_names = new String[0]; String[] option_values = new String[0]; diff --git a/java/test/BeqsDataResultTest.java b/java/test/BeqsDataResultTest.java new file mode 100644 index 0000000..3797fef --- /dev/null +++ b/java/test/BeqsDataResultTest.java @@ -0,0 +1,35 @@ +import junit.framework.*; +import java.util.regex.*; +import org.findata.blpwrapper.*; + +public class ReferenceDataResultTest extends TestCase { + private Connection conn; + + public void setUp() throws Exception{ + conn = new Connection(); + } + + public void tearDown() throws Exception{ + conn.close(); + } + + + + public void testValidRequest() throws Exception { + String screenName = "Quality Screen"; + String screenType = "GLOBAL"; + BeqsDataResult result = (BeqsDataResult)conn.beqs(screenName, screenType); + + } + + public void testValidRequestWithAsOfDate() throws Exception { + String screenName = {"Quality Screen"}; + String screenType = {"GLOBAL"}; + StringAsOfDate = "20100201"; + + BeqsDataResult result = (BeqsDataResult)conn.beqs(screenName, screenType, AsOfDate); + + } + + +} diff --git a/rbloomberg/DESCRIPTION b/rbloomberg/DESCRIPTION index 7d358f3..2ffbf06 100644 --- a/rbloomberg/DESCRIPTION +++ b/rbloomberg/DESCRIPTION @@ -1,6 +1,6 @@ Package: Rbbg -Version: 0.5.3 -Date: 2014-09-03 +Version: 0.6.1 +Date: 2015-10-21 Title: R/bbg Author: Robert Sams , Ana Nelson Maintainer: John Laing diff --git a/rbloomberg/R/blp.R b/rbloomberg/R/blp.R index 8a72e46..1cb88f4 100644 --- a/rbloomberg/R/blp.R +++ b/rbloomberg/R/blp.R @@ -235,6 +235,22 @@ tick <- function(conn, security, fields, start_date_time, end_date_time, return(process.result(result)) } + +### @export "beqs-definition" +beqs <- function(conn, screenName, screenType="PRIVATE", languageId="ENGLISH", Group = "", asOfDate=NULL) +### @end +{ + if(is.null(asOfDate)){ + result <- conn$beqs(screenName, screenType, languageId, Group) + } else { + dAsOfDate = format(asOfDate, format="%Y%m%d") + result <- conn$beqs(screenName, screenType, languageId, Group, dAsOfDate) + } + + return(process.result(result)) +} + + process.result <- function(result, row.name.source = "none") { matrix.data <- .jevalArray(result$getData(), simplify = TRUE) if (is.null(matrix.data)) return(NULL) diff --git a/rbloomberg/man/beqs.Rd b/rbloomberg/man/beqs.Rd new file mode 100644 index 0000000..c35e8e4 --- /dev/null +++ b/rbloomberg/man/beqs.Rd @@ -0,0 +1,36 @@ +\name{beqs} +\alias{beqs} +\title{Get Bloomberg Equity Screen Data} +\description{ + This is the primary user-level function for retrieving Bloomberg Equity Screen data created using the EQS function in Bloomberg. +} +\usage{ +blp(conn, securities, fields, start_date, end_date = NULL, override_fields = NULL, overrides NULL) +} +\arguments{ + \item{conn}{Connection object} + \item{screenName}{The name of the Equity Screen listed on EQS.} + \item{screenType}{string with the location of the screen either PRIVATE for user defined screen or GLOBAL for a Bloomberg EQS screen.} + \item{languageId}{string with the language eg ENGLISH, KANJI, FRENCH, GERMAN, SPANISH, PORTUGUESE, ITALIAN, CHINESE_TRA, KOREAN, CHINESE_SIM, THAI, SWED, FINNISH, DUTCH, MALAY, RUSSIAN, GREEK, POLISH, DANISH, FLEMISH, ESTONIAN, TURKISH, NORWEGIAN, LATVIAN, LITHUANIAN, INDONESIAN } + \item{Group}{Screen folder name as defined in EQS.} + \item{asOfDate}{As Of date for data retrieved, either as a YYYYMMDD format string or a date object of any class which responds correctly to format().} +} +\details{ +an equivalent to the beqs() function in Bloomberg Excel. Returns as a dataframe with the contents of an Equity Screen set up using the EQS page on Bloomberg. The data can be as of a date. +} +\keyword{math} +\examples{ +# Please consult unit tests for more examples. +\dontrun{ +library(RBloomberg) +conn <- blpConnect() + +beqs(conn, "Global Volume Surges", "GLOBAL") + + +blpDisconnect(conn) + +} +} +\author{Charles Cara \email{charles.cara@absolute-strategy.com}} +