library(DatastreamR) ProcessTimeseriesResponse = function(tsResponse, tsName) { if (!is.null(tsResponse)) { # Any request dealing with a single user created item returns a # DSUserObjectResponse. This has ResponseStatus property that indicates # success or failure if (tsResponse$ResponseStatus != DSUserObjectResponseStatus$UserObjectSuccess) print(paste('Request failed for timeseries', tsName, 'with error ', names(DSUserObjectResponseStatus)[tsResponse$ResponseStatus + 1], ': ', tsResponse$ErrorMessage, '\n\n')) else if (!is.null(tsResponse$UserObject)) # The timeseries item won't be returned if you set SkipItem true in CreateItem or UpdateItem { # Here we simply display the timeseries data using a dataframe. tsItem = tsResponse$UserObject metadata = c (Id = tsItem$Id, Desc = tsItem$Description, LastModified = as.character(tsItem$LastModified), StartDate = ifelse (!is.null(tsItem$DateInfo), as.character(tsItem$DateInfo$StartDate), NULL), EndDate = ifelse(!is.null(tsItem$DateInfo),as.character(tsItem$DateInfo$EndDate), NULL), Frequency = ifelse(!is.null(tsItem$DateInfo), names(DSUserObjectFrequency)[tsItem$DateInfo$Frequency + 1], NULL), NoOfValues = ifelse(!is.null(tsItem$DateRange), tsItem$DateRange$ValuesCount , 0)) df = data.frame(metadata) print(df) if (!is.null(tsItem$DateRange)) { df = data.frame(Dates = sapply(tsItem$DateRange$Dates, FUN = function(x) { return (as.character(x)) }), Values = sapply(tsItem$DateRange$Values, FUN = function(x) { ifelse (is.null(x), return (NA_character_ ), return (x) )} )) # Values if NULL, is printed as because, while # convertind list to vector either by using as.vector or sapply, # the NULL values in the list are deleted. and thus there will # be mismatch in no of rows and cannot be put in a dataframe print(df) } } } else print(paste('Timeseries ', tsName, ' successfully updated but item details not returned.')) } # we need to know which dates are supported on Datastream. # Datastream only stores the actual working weekdays for a given date range, # so, we need to provide values that match the dates supported. # GetTimeseriesDateRange method which returns a list of supported dates # for a given start date, end date and frequency. timeseriesClient = TimeSeriesClient$new("Config.ini") # Retrieving the supported dates. # This example intentionally shows two different date constructors, # requesting quarterly dates between 2016 and 2022. startDate = as.Date.character('2016-1-1', format = "%Y-%m-%d") endDate = as.Date('2022-04-01') freq = DSUserObjectFrequency$Quarterly print('Requesting GetTimeseriesDateRange to get supported dates from 2016-01-0 to 2022-04-01 at quarterly frequency.') dateRangeResp = timeseriesClient$GetTimeseriesDateRange(startDate, endDate, freq) # process the returned dates datesCount = 0 if (!is.null(dateRangeResp)) { if (dateRangeResp$ResponseStatus != DSUserObjectResponseStatus$UserObjectSuccess) { print('GetTimeseriesDateRange failed with error ', names(DSUserObjectResponseStatus)[dateRangeResp$ResponseStatus + 1], ': ', dateRangeResp$ErrorMessage) } else if (!is.null(dateRangeResp$Dates)) { df = data.frame(Dates = sapply(dateRangeResp$Dates, FUN = function(x) { return (as.character(x)) })) print(df) } } # You would normally use the returned dates to populate the timeseries # request's objects Values field with corresponding values. # Here we are just going to track how many valid dates there were within # the requested period. datesCount = length(dateRangeResp$Dates) # With the list of supported dates returned from GetTimeseriesDateRange, # you would then create an array of values associated # with the given dates from your data source. # For this example, we'll just populate an array of test values randomly # between 10.00 and 200.00 with two decimal places datesCount = ifelse (datesCount > 0, datesCount, 26) # safety: setting datesCount in case GetTimeseriesDateRange response processing was skipped over # We'll simply create an array of values datesCount long with random values between 10 and 200 with 2 decimal places to reflect data retrieved from some source values = runif(datesCount, 10.01, 200.01) # We'll use a variable to store the test ID # Note Timeseries IDs must be 8 uppercase alphanumeric characters in length # and start with TS. e.g. TSZZZ001 # Feel free to change this ID to something you prefer. testID = 'TSVVV023' # To now create the timeseries, we need a DSTimeSeriesRequestObject. # The constructor for this requires you to provide only the mandatory # properties. # There are some key parameters you need to set in a timeseries request object: # The ID, the start and end dates, the frequency of data and the data values # for the given date range and frequency # You can construct the timeseries with the key data in two ways: # First method is to use the optional parameters in the constructor # to supply the key data testTs = DSTimeSeriesRequestObject$new(testID, startDate, endDate, DSUserObjectFrequency$Quarterly, values) # Or you can construct the basic object and populate the fields directly # testTs = DSTimeSeriesRequestObject() # testTs$Id = testID # testTs$DataInput = DSTimeSeriesDataInput() # or more directly testTs$DataInput = DSTimeSeriesDataInput(startDate, endDate, DSUserObjectFrequency$Quarterly, values) # testTs$DataInput.StartDate = startDate # testTs$DataInput.EndDate = endDate # testTs$DataInput.Frequency = DSUserObjectFrequency$Quarterly # testTs$DataInput$Values = values #Set any other optional properties directly testTs$DisplayName = 'My first test timeseries' # if you don't set the DisplayName it will be set to the same as the ID in the response testTs$DecimalPlaces = 2 # we created our array of values with 2 decimal places. You can specify 0 to 8 decimal places testTs$Units = "Billions" # Leave units blank or set with any custom text (max 12 chars) testTs$DateAlignment = DSTimeSeriesDateAlignment$MidPeriod # when requested by users in data retrieval, you can specify the quarterly dates to be returned as start, middle or end of the select period (frequency) # Now we actually try and create the item. # When you create an item, the create request will normally be rejected # if the item already exists. However, there is an option to overwrite the # existing item. We will use that option here in case the item was created # in an earlier test and not subsequently deleted. print(paste('Creating a new timeseries', testID)) tsResp = timeseriesClient$CreateItem(testTs, overWrite = TRUE) # The timeseries should now be returned in the list of timeseries if you call timeseriesClient.GetAllItems() again. # It should also, after a few minutes, appear in Datastream's Navigator tool. # You should also be able to chart it using the DSChart tool in Eikon or LSEG Workstation # The raw data should also be retrievable with requests via the standard Datastream API or via Datastream For Office (DSGrid queries). # Here, we will just display the response returned from the mainframe. ProcessTimeseriesResponse(tsResp, testID)