...any errors thrown.
I wrote a .Net C# wrapper to request and return historical time series data via Eikon .Net API. I can connect to Reuters servers, and can request 2, sometimes 3 time series but then the application hangs indefinitely (the problem 100% does not originate from the request content itself as I only request each time 1 day worth of 1 minute compressed fx data).
One complication is that I must access the Reuters API from within a console app thread and hence had to run a separate message pump. Please see below code :
Helper Methods:
private void PushDispatcherFrame(Action action)
{
_dispatcher.Invoke(() =>
{
//execute action
action();
//push frame
_frame = new DispatcherFrame();
Dispatcher.PushFrame(_frame);
});
}
private void ReleaseFrame(bool isContinue)
{
_dispatcher.Invoke(() =>
{
_frame.Continue = isContinue;
});
}
Connection code:
PushDispatcherFrame(() =>
{
_dataServices = DataServices.Instance;
_dataServices.StateChanged += DataServicesOnStateChanged;
_dataServices.Initialize("ReutersMarketDataPlugin");
});
//wait until service state changes (with timeout)
var startDt = DateTime.UtcNow;
var timeoutDt = startDt + TimeSpan.FromSeconds(40);
while (DateTime.UtcNow < timeoutDt && _serviceState != DataServicesState.Up)
{
Task.Delay(200).Wait();
}
if (_serviceState == DataServicesState.Up)
return true;
else
return false;
}
private void DataServicesOnStateChanged(object sender, DataServicesStateChangedEventArgs args)
{
_serviceState = args.State;
ReleaseFrame(false);
}
Here is the data request (and after 2-3 successful requests the app hangs after executing "request.CreateAndSend();"
//structure request
PushDispatcherFrame(() =>
{
var subscription = new TaggableTimeseriesSubscription(dto, OnSubscriptionDataReceived, OnSubscriptionDataUpdated);
_historicalSubscriptions.Add(subscription.SubscriptionId, subscription);
ITimeSeriesDataRequestSetup request = _dataServices.TimeSeries.SetupDataRequest();
request.WithRic(GetRic(dto.SymbolId));
request.From(dto.DateTimeFrom);
request.To(dto.DateTimeTo);
request.WithFields(GetHistoricalDataRequestFields(dto.QuoteType));
request.WithTimeZone(TimezoneType.GMT);
request.WithInterval(GetTimeSeriesInterval(dto.Compression));
request.OnDataReceived(subscription.RegisterDataReceivedCallback);
request.OnStatusUpdated(status =>
{
//error captured
SendSystemMessage(new SystemMessage(SystemMessageType.Info, _properties.PluginName, dto.SubscriberId,
"Status: " + status.State + " - Message: " + status.Error));
//return request
_historicalDataCallback(subscription.HistoricalRequest);
});
//create and send
subscription.ReutersHistoricalTimeSeriesRequest = request.CreateAndSend();
});
And here the callback:
private void OnSubscriptionDataReceived(string subscriptionId, DataChunk chunk)
{
// chunk.Records provides access to a dictionary of field -> value, so that
// developpers can access values from field names and cast them in the proper type like in:
// double open = (double) chunk.Records.First()["OPEN"];
// In addition, for convenience Time Series API exposes shortcuts that allow developers
// to code against strongly typed accessors. This is done through conversion methods
// such as ToBarRecords(), ToQuoteRecords(), ToTickRecords(), ToTradeRecords() and ToTradeAndQuoteRecords().
// The full dictionary is still exposed in the resulting strongly-typed classes.
// In this sample we know that records are typical "bar" records (open, close, high, low, volume)
// because we ask for a daily interval. So we can use ToBarRecords() helper method:
if (_historicalSubscriptions.ContainsKey(subscriptionId))
{
//add quotes to request
var request = _historicalSubscriptions[subscriptionId].HistoricalRequest;
var quotes = RecordsToQuotes(request, chunk.Records);
request.Quotes.AddRange(quotes);
//return data if request is completed
if (chunk.IsLast)
{
//filter and sort quotes and update request
request.Quotes = request.Quotes.Where(x => x.TimeStamp >= request.DateTimeFrom && x.TimeStamp <= request.DateTimeTo).OrderBy(x => x.TimeStamp).Distinct().ToList();
//remove request
_historicalSubscriptions.Remove(subscriptionId);
//ReleaseFromMessagePump();
//return data
if (_historicalDataCallback != null)
{
_historicalDataCallback(request);
}
ReleaseFrame(false);
}
else
{
ReleaseFrame(true);
}
}
}