Last update | Nov 2023 |
Environment | Windows |
Language | C# |
Compilers | Microsoft Visual Studio 2019 |
Prerequisites | DSS login, internet access, having done the previous tutorials |
Source code | Download .Net SDK Tutorials Code |
This is the seventh tutorial in a series of .Net SDK tutorials. It is assumed that the reader has acquired the knowledge delivered in the previous tutorials before following this one.
In this tutorial we build on the previous two by overcoming the limit on the number of instrument identifiers:
Extraction limits vary depending on the type of requested data, from 500 to 150000 instruments. This code example is for an End of Day request where the limit is 75000 instruments (150000 after chain expansion). Refer to the DataScope User Guide for all the details on the limits that apply by extraction type, or see them online.
In the tutorial we do not actually use such a large list of instruments; instead we simulate a lower limit, to avoid consuming too much (billable) data. For more information, refer to section: Important warning on data usage.
The code installation was done in Tutorial 1.
Opening the solution is similar to what was done in the previous tutorials:
Before anything else, you must reference the DSS REST API .Net SDK in the Microsoft Visual Studio project.
Important: this must be done for every single tutorial, for both the learning and refactored versions.
This was explained in the tutorial 2; please refer to it for instructions.
In Microsoft Visual Studio, in the Solution Explorer, double click on Program.cs and on DssClient.cs to display both file contents. Each file will be displayed in a separate tab.
Before running the code, you must replace YourUserId with your DSS user name, and YourPassword with your DSS password, in these 2 lines of Program.cs:
private static string dssUserName = "YourUserId";
private static string dssUserPassword = "YourPassword";
Important reminder: this must be done for every single tutorial, for both the learning and refactored versions.
Failure to do so will result in an error at run time (see Tutorial 1 for more details).
DSS accounts have a quota of instruments that can be requested during a defined time period. The DSS subscription fees are proportional to the size of the quota. If the quota is reached, excess fees will be due. That situation must be avoided !
Data usage can be displayed in the DSS web GUI:
Contact your local account manager or sales specialist if you have queries on your DSS account quota or usage.
This tutorial (and the previous one) handle large instrument lists, read from a file.
Care must be exercised when running these tutorials, to avoid over consuming data.
For this reason, several files are delivered with the tutorials code:
The first one contains 1500 valid instrument identifiers, the second one 60, the last one only contains 10.
The text and illustrations that follow use the larger file. To avoid consuming too much data, we recommend you use the smaller file for your own tests, which will deliver similar results.
We shall only describe what is new versus the previous tutorials.
This is the same as the refactored version of Tutorial 6, except for the leading comment.
No additional explanations are required as the rest of the code was described in the previous tutorial.
We add one declaration, the maximum size of an instrument identifier list DSS can handle in one request:
private static int maxDssIdentifiersListSize = 75000;
Extraction limits vary depending on the type of requested data, from 500 to 150000 instruments. This code example is for an End of Day request where the limit is 75000 instruments (150000 after chain expansion). Refer to the DataScope User Guide for all the details on the limits that apply by extraction type.
As stated in the previous tutorial, to avoid consuming too much data for tests, we recommend you use a small input file:
private static string instrumentIdentifiersInputFile = inputDirectory + "DSS_API_10_input_file.csv";
For an explanation why, refer to the previous section: Important warning on data usage.
The purpose of this tutorial is to manage very large instrument lists. To test the algorithm without consuming huge amounts of data, simulate a lower limit by setting a lower value for maxDssIdentifiersListSize, smaller than the number of instruments in the input file, like:
private static int maxDssIdentifiersListSize = 7;
For production code set the value back to 75000 !
Like in the previous tutorial’s learning version we first create a list for the instrument identifiers, and populate it from the input file. This list will contain all the instrument identifiers, even if there are more than the 75000 DSS can handle in one request:
List<InstrumentIdentifier> instrumentIdentifiersList =
PopulateInstrumentIdentifiersListFromFile(instrumentIdentifiersInputFile, errorOutputFile);
Later in the code we will extract slices of 75000 instrument identifiers from this full list. As in C# it is easier to create sub-lists from a large list than sub-arrays from a large array, we don’t want to convert the list to an array at this stage. That is why our helper method returns a list, contrary to the helper method in the previous tutorial’s refactored version, which returned an array. Apart from this small difference, the methods are the same:
static List<InstrumentIdentifier> PopulateInstrumentIdentifiersListFromFile(
string instrumentIdentifiersInputFile, string errorOutputFile)
{
//Open the input file:
StreamReader sr = new StreamReader(instrumentIdentifiersInputFile);
//Initialise the error output file:
StreamWriter sw = new StreamWriter(errorOutputFile, true);
sw.WriteLine("List of errors found in input file: " + instrumentIdentifiersInputFile + "\n");
//Instead of an array (of defined length), create a list for the instrument identifiers.
//We do this because:
// we don't know how many instruments are in the file,
// we filter the file entries, to only keep the validated ones.
//Create the empty instrument identifiers list:
List<InstrumentIdentifier> instrumentIdentifiersList = new List<InstrumentIdentifier> ();
//Populate the list, reading one line at a time from the file:
int fileLineNumber = 0;
string fileLine = string.Empty;
bool commaExistsInFileLine = false;
string identifierTypeString = string.Empty;
string identifierCodeString = string.Empty;
IdentifierType identifierType;
int i = 0;
//Loop through all lines until we get to the end of the file:
bool endOfFile = false;
while (!endOfFile)
{
Errors errorCode = Errors.NoError;
//Read one line of the file, test if end of file:
fileLine = sr.ReadLine();
endOfFile = (fileLine == null);
if (endOfFile && fileLineNumber == 0) { errorCode = Errors.EmptyFile; };
fileLineNumber++;
//Parse the file line to extract the comma separated instrument type and code:
if (errorCode == Errors.NoError && !endOfFile)
{
commaExistsInFileLine = (fileLine.IndexOf(",") >= 0);
if (commaExistsInFileLine)
{
string[] splitLine = fileLine.Split(new char[] { ',' });
identifierTypeString = splitLine[0];
identifierCodeString = splitLine[1];
}
else
{
errorCode = Errors.BadLineFormat; //Missing comma
identifierTypeString = string.Empty;
identifierCodeString = string.Empty;
}
}
if (identifierTypeString == string.Empty && errorCode == Errors.NoError)
{ errorCode = Errors.EmptyType; }
if (identifierCodeString == string.Empty && errorCode == Errors.NoError)
{ errorCode = Errors.EmptyCode; }
identifierType = IdentifierType.NONE;
if (errorCode == Errors.NoError && !endOfFile)
{
//DSS can handle many types, here we only handle a subset:
switch (identifierTypeString)
{
case "CHR": identifierType = IdentifierType.ChainRIC; break;
case "CIN": identifierType = IdentifierType.Cin; break;
case "COM": identifierType = IdentifierType.CommonCode; break;
case "CSP": identifierType = IdentifierType.Cusip; break;
case "ISN": identifierType = IdentifierType.Isin; break;
case "RIC": identifierType = IdentifierType.Ric; break;
case "SED": identifierType = IdentifierType.Sedol; break;
case "VAL": identifierType = IdentifierType.Valoren; break;
case "WPK": identifierType = IdentifierType.Wertpapier; break;
default: errorCode = Errors.UnknownIdentifier; break;
}
}
if (errorCode == Errors.NoError && !endOfFile)
{
//Add validated instrument identifier into our list:
instrumentIdentifiersList.Add(new InstrumentIdentifier
{
IdentifierType = identifierType,
Identifier = identifierCodeString
});
Console.WriteLine("Line " + fileLineNumber + ": " +
identifierTypeString + " " + identifierCodeString + " loaded into array [" + i + "]");
i++;
}
if (errorCode != Errors.NoError)
{
DebugPrintAndWriteToFileErrorMessage(
errorCode, fileLineNumber, fileLine, identifierTypeString, sw);
}
} //End of while loop
sr.Close();
sw.Close();
return instrumentIdentifiersList;
}
The outputs of this method, for successfully added instrument identifiers, are exactly the same as for the previous tutorial:
...
Line 1500: RIC ALVG.DE loaded into array [1497]
Line 1501: RIC IBM.N loaded into array [1498]
Line 1502: RIC 0001.HK loaded into array [1499]
...
The outputs of this method, for invalid lines in the input file, are exactly the same as for the previous tutorial:
...
ERROR line 1506: unknown identifier type: Junk
ERROR line 1507: missing identifier type in line: ,Junk
ERROR line 1508: missing identifier code in line: Junk,
ERROR line 1509: bad line format: Junk
ERROR line 1510: missing identifier type in line: ,
ERROR line 1511: missing identifier code in line: CSP,,
...
Same goes for the error file which contains all the ERROR messages.
Similarly to the previous tutorial, this is followed with a check on the number of valid instrument identifiers:
int validIdentifiersCount = instrumentIdentifiersList.Count();
if (validIdentifiersCount == 0)
{
DebugPrintAndWaitForEnter("Exit program due to no identifiers in the list.");
return; //Exit main program
}
Console.WriteLine("\n" + validIdentifiersCount +
" valid instruments were loaded into an array, outside of DSS,\n" +
"for use in the extraction.");
Result:
...
1500 valid instruments were loaded into an array, outside of DSS,
for use in the extraction.
...
To create the field name array we proceed just like in the previous tutorials, calling the helper method we created in Tutorial 2:
string[] requestedFieldNames = CreateRequestedFieldNames();
We will use this array when we define the extraction.
Like in the previous tutorial, we do not create a:
This section explains how we code a loop to process all the instruments in several chunks.
We create a big loop, inside which we run one or more On Demand extractions, each immediately followed by whatever data processing or treatment the use case requires. DSS has a limit on the number of instruments in a list. That limit is 75000, we set it in variable maxDssIdentifiersListSize. If the file contains more, we split the list into:
We run an extraction and process the data for each sub-list, inside a big loop. At each iteration of the loop we:
Let us look at the code ...
Determine the number of loops of 75000 instruments:
int loopsToRun = validIdentifiersCount / maxDssIdentifiersListSize;
Determine the number of instruments in the remainder loop:
int sizeOfInstrumentIdentifiersRemainder = validIdentifiersCount % maxDssIdentifiersListSize;
Add a loop for the eventual remainder:
if (sizeOfInstrumentIdentifiersRemainder > 0) { loopsToRun++; }
For testing purposes, display the calculated numbers:
Console.WriteLine("Next we will launch " + loopsToRun +
" on demand EOD pricing extraction(s),\n" +
"each followed by data treatment.\n" +
"The " + loopsToRun + " iteration(s) take into account the " +
maxDssIdentifiersListSize + " instruments limit.");
if (sizeOfInstrumentIdentifiersRemainder > 0)
{
DebugPrintAndWaitForEnter("The last iteration has " + sizeOfInstrumentIdentifiersRemainder +
" instruments.\n");
}
else
{
DebugPrintAndWaitForEnter("The last iteration has " + maxDssIdentifiersListSize + " instruments.\n");
}
As our sample instrument lists have less than 75000 instruments, there will only be 1 iteration of the loop.
To test this part of the code without using an instrument identifier list of more than 75000 instruments, we can change the value of maxDssIdentifiersListSize (do not do this in production).
Setting it to 1000, with an input file of 1500 instruments, we get:
...
1500 valid instruments were loaded into a list, outside of DSS,
for use in the extraction.
We also created an array of field names, outside of DSS.
Next we will launch 2 on demand EOD pricing extraction(s),
each followed by data treatment.
The 2 iteration(s) take into account the 1000 instruments limit.
The last iteration has 500 instruments.
Setting it to 7, with an input file of 10 instruments, we get:
...
10 valid instruments were loaded into a list, outside of DSS,
for use in the extraction.
We also created an array of field names, outside of DSS.
Next we will launch 2 on demand EOD pricing extraction(s),
each followed by data treatment.
The 2 iteration(s) take into account the 7 instruments limit.
The last iteration has 3 instruments.
Before the loop, declare some helper variables:
IDssEnumerable<ExtractionRow> extractionDataRows;
int bigLoopIteration = 1;
int firstListElementIndex = 0;
int numberOfListElements = 0;
To extract slices of 75000 instrument identifiers from our full list we use 2 variables:
At the start of the loop, determine the values of these 2 variables for the current iteration:
while (bigLoopIteration <= loopsToRun)
{
//Fill the instrument identifiers subset array with a set of instruments,
//either 75000, or less if it is the remainder:
firstListElementIndex = (bigLoopIteration - 1) * maxDssIdentifiersListSize;
if (bigLoopIteration < loopsToRun || sizeOfInstrumentIdentifiersRemainder == 0)
{ numberOfListElements = maxDssIdentifiersListSize; }
else
{ numberOfListElements = sizeOfInstrumentIdentifiersRemainder; }
Extract the sub-list of instrument indentifiers from the full list (this is much easier using lists than arrays):
List<InstrumentIdentifier> instrumentIdentifiersSubList =
instrumentIdentifiersList.GetRange(firstListElementIndex, numberOfListElements);
Convert this list to an array, as this is what the On Demand extraction API call requires:
InstrumentIdentifier[] instrumentIdentifiersSubArray = instrumentIdentifiersSubList.ToArray();
For testing purposes, display the relevant numbers:
Console.WriteLine("Loaded identifiers into a sub array, iteration number: " + bigLoopIteration +
"\nFirst element index: " + firstListElementIndex + " - Number of elements: " +
numberOfListElements);
Going back to the test with a value of 1000 for maxDssIdentifiersListSize, we get a first iteration:
...
Loaded identifiers into a sub array, iteration number: 1
First element index: 0 - Number of elements: 1000
Please be patient and wait for the extraction to complete ...
And at second iteration:
...
Loaded identifiers into a sub array, iteration number: 2
First element index: 1000 - Number of elements: 500
Please be patient and wait for the extraction to complete ...
Extract and treat JSON data
Like in the previous tutorial, we shall run 2 extraction variants:
In real life you would only run one of these, chosen depending on your use case.
To run the extraction we call our helper method, like in the previous tutorial:
ExtractionResult extractionResult =
dssClient.CreateAndRunEodPricingExtraction(instrumentIdentifiersSubArray, requestedFieldNames);
extractionDataRows = extractionResult.Contents;
Finally we process the data from this extraction, using the helper method from the previous tutorial:
if (bigLoopIteration == 1)
{ DisplayAndLogExtractedDataFieldNames(dataOutputFile, extractionDataRows); }
DisplayAndLogExtractedDataFieldValues(dataOutputFile, extractionDataRows);
Note we only display the field names at the first iteration, as they will always be the same.
The results on screen are the same as in the previous tutorial (except that they may come in one or several iterations, depending on the instrument identifier list size, and the value of maxDssIdentifiersListSize).
Extract and treat compressed data
To run the extraction for compressed CSV data, we call our helper method, like in the previous tutorial:
RawExtractionResult rawExtractionResult =
dssClient.CreateAndRunEodPricingRawExtraction(instrumentIdentifiersSubArray, requestedFieldNames);
Then we process the data from this extraction, using the helper method from the previous tutorial:
dssClient.SaveCompressedData(rawExtractionResult, gzipDataOutputFile);
DisplayAndLogAndAnalyzeRawExtractionNotes(gzipNotesOutputFile, errorOutputFile, rawExtractionResult);
Post extraction code
After the extractions, the loop ends:
//Increment the big while loop to process the next set of identifiers:
bigLoopIteration++;
}
A final message signals that all extractions were completed:
DebugPrintAndWaitForEnter("All extractions completed.");
...
All extractions completed.
Press Enter to continue
As stated in the 2 previous tutorials, cleanup on the DSS server is not required, as there is nothing to delete in this case.
The full code can be displayed by opening the appropriate solution file in Microsoft Visual Studio.
List of the main steps in the code:
We do not create a report template or schedule, and there is no need to cleanup.
Don’t forget to reference the DSS SDK, and to set your user account in Program.cs !
The following is a run using the largest input file, with maxDssIdentifiersListSize set to 1000. Remember this is only for testing, in production maxDssIdentifiersListSize would be set to its real value of 75000. Remember: 75000 is the limit for End of Day requests. Refer to the DataScope User Guide for all the details on the limits that apply by extraction type.
After running the program, and pressing the Enter key when prompted, the final result should look like this:
Returned session token: <token>
Press Enter to continue
Cleared data output file C:\DSS REST API\DSS_API_tutorial_7l_output.txt
Cleared notes output file C:\DSS REST API\DSS_API_tutorial_7l_notes.txt
Cleared error output file C:\DSS REST API\DSS_API_tutorial_7l_errors.txt
Cleared compressed data output file C:\DSS REST API\DSS_API_tutorial_7l_gzipOutput.csv.gz
Cleared compressed data notes output file C:\DSS REST API\DSS_API_tutorial_7l_gzipNotes.txt
Press Enter to continue
ERROR line 1: unknown identifier type: Identifier Type
Line 2: CSP 911760HW9 loaded into array [0]
Line 3: CSP 911760JQ0 loaded into array [1]
Line 4: CSP 911760JR8 loaded into array [2]
Line 5: CSP 911760HP4 loaded into array [3]
Line 6: CSP 31359KUL9 loaded into array [4]
Line 7: CSP 31359KUJ4 loaded into array [5]
Line 8: CSP 31359KUK1 loaded into array [6]
Line 9: CSP 232928AE1 loaded into array [7]
Line 10: CSP 79548KHM3 loaded into array [8]
Line 11: CSP 911760JT4 loaded into array [9]
Line 12: CSP 911760KF2 loaded into array [10]
Line 13: CSP 911760KG0 loaded into array [11]
Line 14: CSP 92260MAP8 loaded into array [12]
Line 15: CSP 31359KGH4 loaded into array [13]
Line 16: CSP 31359KGJ0 loaded into array [14]
Line 17: CSP 31359KGK7 loaded into array [15]
Line 18: CSP 911760KT2 loaded into array [16]
Line 19: CSP 911760KU9 loaded into array [17]
Line 20: CSP 911760LB0 loaded into array [18]
...
This goes on with the next instruments of the file ...
The instrument identifiers import messages end like this, with quite a few errors generated by the wrongly formatted lines we included in the input file to test the error handling:
...
Line 1495: CSP 31352DCM0 loaded into array [1493]
Line 1496: CSP 31352DCN8 loaded into array [1494]
Line 1497: CSP 31352DCR9 loaded into array [1495]
Line 1498: CSP 31352JRV1 loaded into array [1496]
ERROR line 1499: bad line format: #RICs:
Line 1500: RIC ALVG.DE loaded into array [1497]
Line 1501: RIC IBM.N loaded into array [1498]
Line 1502: RIC 0001.HK loaded into array [1499]
ERROR line 1503: bad line format:
ERROR line 1504: bad line format: #Lines for error handling tests:
ERROR line 1505: unknown identifier type: Junk
ERROR line 1506: unknown identifier type: Junk
ERROR line 1507: missing identifier type in line: ,Junk
ERROR line 1508: missing identifier code in line: Junk,
ERROR line 1509: bad line format: Junk
ERROR line 1510: missing identifier type in line: ,
ERROR line 1511: missing identifier code in line: CSP,,
ERROR line 1512: missing identifier code in line: CSP,
ERROR line 1513: missing identifier type in line: ,CSP
ERROR line 1514: bad line format: CSP
ERROR line 1515: unknown identifier type: Junk
ERROR line 1516: unknown identifier type: Junk
ERROR line 1517: missing identifier code in line: RIC,,
ERROR line 1518: missing identifier code in line: RIC,
ERROR line 1519: missing identifier type in line: ,RIC
ERROR line 1520: bad line format: RIC
ERROR line 1521: unknown identifier type: Junk
ERROR line 1522: unknown identifier type: Junk
1500 valid instruments were loaded into a list, outside of DSS,
for use in the extraction.
We also created an array of field names, outside of DSS.
...
This is followed by the first iteration of the big loop, and the display of the returned field names:
...
Next we will launch 2 on demand EOD pricing extraction(s),
each followed by data treatment.
The 2 iteration(s) take into account the 1000 instruments limit.
The last iteration has 500 instruments.
Press Enter to continue
Loaded identifiers into a sub array, iteration number: 1
First element index: 0 - Number of elements: 1000
Please be patient and wait for the extraction to complete ...
Returned list of field names:
Instrument ID,Security Description,Universal Close Price Date,Universal Close Price,
Press Enter to continue
...
Next come the data values for this first set of 1000 instruments:
...
Returned field values:
======================
911760HW9, VNDE 963 1Z Z Fix, 6/8/2022 12:00:00 AM, 102.929810999
911760JQ0, VNDE 963 3 Vari, 6/8/2022 12:00:00 AM, 103.652327784
911760JR8, VNDE 963 4 Vari, ,
911760HP4, VNDE 963 IO Excess Vari IONtl, ,
31359KUL9, FN 96W3 X Excess Vari IONtl, ,
31359KUJ4, FN 96W3 A6 Seq Vari, ,
31359KUK1, FN 96W3 AL Seq Vari, ,
232928AE1, DRFC 94K1 A3 Fix, ,
79548KHM3, SBMSI7 936A B2 Sub Vari, 6/8/2022 12:00:00 AM, 99.227791996
911760JT4, VNDE 971A 1A Vari, 6/8/2022 12:00:00 AM, 102.071886385
...
This goes on with all the returned data for the first iteration, followed by the statistics and messages for this first slice:
...
31358H5N1, FN 91115 MM Supp Lottery Fix, ,
31358H5P6, FN 91115 N Strip Fix Ioette, ,
31358JRQ6, FN 91116 E PAC Fix, ,
31358JSJ1, FN 91116 V Supp Fix Ioette, ,
31358JCH2, FN 91118 LL Supp Lottery Fix C, ,
31358JCJ8, FN 91118 M Supp PO Cmpnt, ,
31358JBP5, FN 91119 N Strip Fix Ioette, ,
31358JBJ9, FN 91119 Z Supp Z Fix, ,
31358FM55, FN 9112 H PAC1 Fix, ,
31358FM63, FN 9112 J PAC1 Fix Ioette, ,
Extraction completed.
Number of data rows: 1000
Number of valid (non empty) data rows: 987
Output was also written to file.
Press Enter to continue
...
After that, the extraction notes for this extraction are displayed, followed by their analysis results.
The second extraction is then performed, and the compressed data saved to file. After that, the extraction notes for the second extraction are displayed, followed by their analysis results.
This is followed by the next iteration of the big loop, and the display of the data values (field names are not displayed):
...
Loaded identifiers into a sub array, iteration number: 2
First element index: 1000 - Number of elements: 500
Please be patient and wait for the extraction to complete ...
Returned field values:
======================
31358JDZ1, FN 91120 K Strip Fix Ioette, ,
31358JEA5, FN 91120 Z Supp Z Fix, ,
31358JEQ0, FN 91122 N PAC1 Fix, ,
31358JER8, FN 91122 O PAC1 Fix Ioette, ,
31358JSN2, FN 91123 EB PAC1 Fix, ,
31358JGN5, FN 91123 G PAC1 Fix Ioette, ,
31358JGY1, FN 91123 Q Strip Fix Ioette, ,
...
This goes on with all the returned data for that iteration, followed by the statistics, messages and notes for that slice.
The program ends after the last slice.
We can then check out the output files; their contents reflect what was displayed on screen, and is the same as what was generated by the previous tutorial (except that data values will have changed if you ran it on a different day).
If the user name and password were not set properly, an error will be returned. See Tutorial 1 for details.
The maxDssIdentifiersListSize declaration has been moved here (from Program.cs), as it is specific to DSS, and not likely to change:
public int maxDssIdentifiersListSize = 75000;
There are no other changes.
As the maxDssIdentifiersListSize declaration has been moved to the DssClient.cs class, we expose it here:
int maxDssIdentifiersListSize = dssClient.maxDssIdentifiersListSize;
Comments that explicitly mentioned the number 75000 (for readability) were modified to mention the variable name maxDssIdentifiersListSize.
Inside the big loop, we call a helper method to populate the instrument identifiers sub-array:
InstrumentIdentifier[] instrumentIdentifiersSubArray =
PopulateInstrumentIdentifiersSubArray(
bigLoopIteration, loopsToRun,
maxDssIdentifiersListSize, sizeOfInstrumentIdentifiersRemainder,
instrumentIdentifiersList);
This helper method is declared in Program.cs, after the main code:
static InstrumentIdentifier[] PopulateInstrumentIdentifiersSubArray(
int bigLoopIteration, int loopsToRun,
int maxDssIdentifiersListSize, int sizeOfInstrumentIdentifiersRemainder,
List<InstrumentIdentifier> instrumentIdentifiersList)
{
//Fill the instrument identifiers subset array with a set of instruments,
//either maxDssIdentifiersListSize, or less if it is the remainder:
int firstListElementIndex = (bigLoopIteration - 1) * maxDssIdentifiersListSize;
int numberOfListElements = 0;
if (bigLoopIteration < loopsToRun || sizeOfInstrumentIdentifiersRemainder == 0)
{ numberOfListElements = maxDssIdentifiersListSize; }
else
{ numberOfListElements = sizeOfInstrumentIdentifiersRemainder; }
List<InstrumentIdentifier> instrumentIdentifiersSubList =
instrumentIdentifiersList.GetRange(firstListElementIndex, numberOfListElements);
Console.WriteLine("Loaded identifiers into a sub array, iteration number: " + bigLoopIteration +
"\nFirst element index: " + firstListElementIndex +
" - Number of elements: " + numberOfListElements);
//Convert the sublist to an array, as that is what the API needs.
InstrumentIdentifier[] instrumentIdentifiersSubArray = instrumentIdentifiersSubList.ToArray();
return instrumentIdentifiersSubArray;
}
Note also that this helper method includes the list conversion to an array.
The full code can be displayed by opening the appropriate solution file in Microsoft Visual Studio.
Don’t forget to reference the DSS SDK, and to set your user account in Program.cs !
This tutorial showed how very large instrument identifiers lists can be easily handled inside a loop, to manage the maximum extraction size supported by the DSS servers.
Extraction limits vary depending on the type of requested data, from 500 to 150000 instruments. This code example is for an End of Day request where the limit is 75000 instruments (150000 after chain expansion). Refer to the DataScope User Guide for all the details on the limits that apply by extraction type.
For large instrument lists, using an endpoint that delivers compressed data, like was illustrated in the second extraction in this sample, can be an advantage.