Datastream Web Service
This document outlines steps to build a client application to reference and make calls to DSWS service using Visual Studio.
Getting started
Open Visual Studio and create a windows\web\console application as per your preference. We are going to create a windows application for the demonstration.
In the solution explorer, right click on References node and select Add Service Reference option.
In the Add Service Reference dialog, enter service URL (http://product.datastream.com/dswsclient/V1/DSService.svc?wsdl) in Address textbox and click on Go. If successful, you should see the dialog as below.
On clicking OK, this will create a proxy class, which will allow you to call DSWS service using the proxy class object. If the service reference is added successfully, you will see the service reference under Solution explorer as below.
This step also adds DSWS service configuration details to the application configuration file. You can change service behaviors using these configurations.
Note that you have to use HTTPS protocol and add a Security node as shown below. This ensures secure communication between client and the service. Also, notice the recommended binding configuration about message size and timeout, which can help in cases of large requests.
We are now ready to make calls to the DSWS service. The first step is token retrieval.
Token retrival
A secure token is needed in order to retrieve data from DSWS. You can obtain a token by calling the 'GetToken()' method. As part of this method, you have to pass your DSWS user account credentials (Datastream Child ID and password). You will get back a secure token as part of the response and you can use this token for subsequent data access. The following code snippet shows an example token request and response:
public string GetToken()
{
if (!string.IsNullOrEmpty(token))
return token;
// Create a token request
var tokenRequest = new DSGetTokenRequest()
{
UserName = "", //add your Datastream credentials here
Password = "",
};
string tokenValue = null;
DateTime tokenExpiry = default(DateTime);
// Instantiate a client object to make the request
using (var dsClient = new DSServiceClient())
{
// Issue a call to get the token
try
{
var tokenResponse = dsClient.GetToken(tokenRequest);
// Read the token from the response
tokenValue = tokenResponse.TokenValue;
tokenExpiry = tokenResponse.TokenExpiry;
}
catch (Exception e)
{
// Something went wrong with our request
// process the error message in e.Message
}
}
this.token = tokenValue;
return tokenValue;
}
Note: The tokens have an expiry time and the response contains the timestamp (in UTC) when the token will expire. This is currently 24 hours. You can cache the token until this expiry time and use it for data requests. You need to obtain the token again if it has expired.
Once you have a token, you can call the service to get data using the token. Before that, you need to understand data requests.
Understanding data requests
A data request in DSWS consists of an instrument (e.g. VOD.L - Vodafone Group RIC), data types (e.g. PH - the highest price achieved on the day), date information (Start/End dates of a time series) and optional request properties. An instrument is generally a symbol (such as RIC, Ticker, Datastream Mnemonic, ISIN, etc.) but it can also be a complex expression. You can specify properties for the instrument (e.g. are they a set of instruments rather than a single instrument). The data types contain the field codes for which you want to retrieve the data. You can look up the instruments and browse the available data types from here.
DSWS supports point-in-time data (snapshot) as well as time series data retrieval. For a snapshot date, you will specify a single date, while for a time series date the start date, end date and frequency information will be specified. Note that the DateKind must be populated appropriately. You can use absolute dates (eg. 2018-01-24), relative dates (e.g. -30D) or certain literals (e.g. BDATE) as dates.
You can also specify additional request properties to customize your responses (e.g. return expanded instrument name). If you need to specify the type of the instrument, you can use the special SYM# function. For example SYM#(VOD.L,RIC) specifies that the instrument type is a RIC. The following code snippet provides an example data request:
public void GetData()
{
var request = new DSGetDataRequest()
{
TokenValue = GetToken(),
DataRequest = new DSDataRequest()
{
Instrument = new DSInstrument() { Value = "VOD" },
DataTypes = new[] { new DSDataType() { Value = "PL" } },
Date = new DSDate()
{
Kind = DSDateKind.TimeSeries,
Start = "-30D",
End = "-10D",
Frequency = DSDateFrequencyNames.D.ToString()
}
}
};
// Get the data
DSDataResponse response = null;
try
{
using (var dsclient = new DSServiceClient())
response = dsclient.GetData(request).DataResponse;
}
catch (Exception e)
{
// Something went wrong with our request
// process the error message in e.Message
}
// Process the response
foreach (var datatypeValue in response.DataTypeValues)
{
// This is the datatype requested
string requestedDataType = datatypeValue.DataType;
// Access the symbols for the datatype
// If the requested instrument was a list, there will be multiple symbols
foreach (var symbolVal in datatypeValue.SymbolValues)
{
string symbol = symbolVal.Symbol;
if (symbolVal.Type == DSSymbolResponseValueType.Error)
{
// The symbol value is an error - perhaps there is no data
string errorMessage = symbolVal.Value.ToString();
}
else if (symbolVal.Type == DSSymbolResponseValueType.DoubleArray)
{
// The symbol value is a double array
double[] values = (double[])symbolVal.Value;
}
}
}
}
Note: If you know that your request contains a symbol that is a RIC, it is better to pass the symbol decorated with <symbol>. For example, VOD.L can be passed as <VOD.L>. Alternatively, you can use the verbose syntax SYM#(VOD.L,RIC). This usually speeds up the operation in the backend.
Understanding data responses
Let us understand the response object.
A data response in DSWS contains all the requested data types and for each data type, the values corresponding to instruments. Note that even though you ask for a single instrument, if the instrument is a list symbol (eg. LFTSE100), you will get back multiple instruments in the response.
The response value is contained inside symbol response value. You can access the Value property to get the appropriate data. For example if you asked for a time series closing price, this property will contain an array of doubles.
A request failure (e.g. invalid arguments) would result in a SOAP error with appropriate fault details. Further, you have to check the Type property of a symbol response to see if a specific data type has errors (e.g. time series information not available for requested data type).
You can also check additional response properties such as expanded symbol names etc. provided you had asked them during your request.