Disconnect from DataServices.Instance
Hello,
I just recently taught myself to code, so please bear with me. I created a plug-in to a 3rd party app that pulls time-series data from the Eikon API. It works successfully when I first attempt to retrieve data. On a subsequent attempt, it seems to get hung up on the request. The request is an ITimeSeriesDataRequest.
My theory is that the application stays "connected" or "initiated" to the DataServices.Instance and DataServices.Instance.TimeSeries, and for some reason when I try to initiate a second request, something goes wrong.
I believe this can be solved if I can somehow disconnect/reset from the IDataServices and ITimeSeriesDataService objects. That way, when I run the second request, the entire process starts fresh with a new initialization. Is there a way to do this?
Thank you,
Steven
Best Answer
-
I have modified the code to use in the console application. From my test, the application can run properly. Please the attached code and output file.
0
Answers
-
@StevenH unless you receive a StatusChange event from DataServices.Instance that says that the service went down, everything should be good.
Could you share more details on what you are trying to achieve? E.g.
- project type;
- name of the third-party software;
- a sample of the request.
the .NET API is coupled with a COM event loop, so I suspect there might be an issue there.
0 -
The part where it gets hung up is on a subsequent request (as below). The software is called RightEdge (rightedgesystems.com). Let me know if there's something else I can provide, and thank you in advance!
public void Launch(string symbol)
{
request = timeSeries.SetupDataRequest(symbol)
.WithView("BID")
.WithAllFields()
.WithInterval(CommonInterval.Daily)
.WithNumberOfPoints(10)
.OnDataReceived(DataReceivedCallback)
.CreateAndSend();
}
public void DataReceivedCallback(DataChunk chunk)
{
foreach (IBarData bar in chunk.Records.ToBarRecords())
{
if (bar.Open.HasValue && bar.High.HasValue && bar.Low.HasValue && bar.Close.HasValue && bar.Timestamp.HasValue)
{
Common.BarData reBar = new Common.BarData();
reBar.BarStartTime = bar.Timestamp.Value;
reBar.Open = bar.Open.Value;
reBar.High = bar.High.Value;
reBar.Low = bar.Low.Value;
reBar.Close = bar.Close.Value;
if (bar.Volume.HasValue)
{
reBar.Volume = Convert.ToUInt64(bar.Volume.Value);
}
ReutersRetrieval.bars.Add(reBar);
}
}
if (!chunk.IsLast) return;
request = null;
ReutersRetrieval.StopMessagePump();
}0 -
Thank you Zhenya- more details (and some code) are in the reply below. I believe the real issue is that the subsequent data request is not receiving any data, so the DataReceivedCallback method is never entered. This prevents the DispatcherFrame's "Continue" being set to false, as the StopMessagePump() method which does that is never reached. I checked the States of the IDataServices and ITimeSeriesDataService objects, and they are both connected/up and running. For some reason though, the SetupDataRequest is not receiving any data on a second run though..
0 -
You should call OnStatusUpdated() to register the status callback. If there is a problem, it may be notified via the status callback.
Moreover, please provide the code in StartMessagePump() and StopMessagePump().
0 -
To completely clarify- here is the entire code that is relevant.
When I first click the button in the app to retrieve data, this is called:
InitReuters.InitializeDataServices("RightEdge");
Here is the entire InitReuters class:
public class InitReuters
{
public static IDataServices Services { get; set; }
public static void InitializeDataServices(string appName)
{
Services = DataServices.Instance;
Services.StateChanged += ServicesOnStateChanged;
Services.Initialize(appName);
InitializeTimeSeries();
}
private static void ServicesOnStateChanged(object sender, DataServicesStateChangedEventArgs dataServicesStateChangedEventArgs)
{
//
}
public static ITimeSeriesDataService timeSeries;
private static void InitializeTimeSeries()
{
timeSeries = DataServices.Instance.TimeSeries;
timeSeries.ServiceInformationChanged += timeSeries_ServiceInformationChanged;
}
private static void timeSeries_ServiceInformationChanged(object sender, ServiceInformationChangedEventArgs e)
{
Debug.Print("{0}: {1}", e.Information.State, e.Information.Message);
}
}Then the code will run through the actual retrieval portion, which is the RetrieveData method below:
public static DispatcherFrame Frame;
public static void StopMessagePump()
{
Frame.Continue = false;
}
public static List<Common.BarData> bars;
public List<Common.BarData> RetrieveData(Symbol symbol, int frequency, DateTime startDate, DateTime endDate, BarConstructionType barConstruction)
{
if (frequency != (int)BarFrequency.Daily)
{
return new List<Common.BarData>();
}
if (startDate == DateTime.MinValue)
{
startDate = new DateTime(1900, 1, 2);
}
if (endDate == DateTime.MaxValue)
{
endDate = DateTime.Now;
}
string RIC = symbol.SymbolInformation.CustomHistoricalData;
bars = new List<Common.BarData>();
Frame = new DispatcherFrame();
(new TSRequest(InitReuters.timeSeries)).Launch(RIC, startDate);
Dispatcher.PushFrame(Frame);
Frame = null;
return bars;
}.. and here is the TSRequest class that contains the actual code for requesting the data:
public class TSRequest
{
public ITimeSeriesDataService timeSeries;
public static ITimeSeriesDataRequest request;
public TSRequest(ITimeSeriesDataService timeSeries)
{
this.timeSeries = timeSeries;
}
public void Launch(string RIC, DateTime startDate)
{
request = timeSeries.SetupDataRequest(RIC)
.WithView("BID")
.WithAllFields()
.WithInterval(CommonInterval.Daily)
.From(startDate)
.OnDataReceived(DataReceivedCallback)
.CreateAndSend();
}
public void DataReceivedCallback(DataChunk chunk)
{
foreach (IBarData bar in chunk.Records.ToBarRecords())
{
if (bar.Open.HasValue && bar.High.HasValue && bar.Low.HasValue && bar.Close.HasValue && bar.Timestamp.HasValue)
{
Common.BarData reBar = new Common.BarData();
reBar.BarStartTime = bar.Timestamp.Value;
reBar.Open = bar.Open.Value;
reBar.High = bar.High.Value;
reBar.Low = bar.Low.Value;
reBar.Close = bar.Close.Value;
if (bar.Volume.HasValue)
{
reBar.Volume = Convert.ToUInt64(bar.Volume.Value);
}
ReutersRetrieval.bars.Add(reBar);
}
}
if (!chunk.IsLast) return;
request = null;
ReutersRetrieval.StopMessagePump();
}
}0 -
Thank you, I included all of the relevant code in the post below (including the DispatcherFrame related stuff). I just added this as well, but it doesn't seem to ever be called:
public static IRequestStatus requestStatus;
public void StatusUpdatedCallback(IRequestStatus iRequestStatus)
{
requestStatus = iRequestStatus;
MessageBox.Show(iRequestStatus.State.ToString());
}0 -
i have noticed two things:
1. i was under the impression that you are using a console application, hence the message pump routine is required. If you are building a wpf or a informs application, you should be good;
2. The API is async, so it looks like the following call becomes out of scope:
(new TSRequest(InitReuters.timeSeries)).Launch(RIC, startDate);
you can do two things: either keep it in scope by having a class level object or a list that contains your request objects, or convert the ```Launch``` routine into a function that returns a Task.
0 -
Thank you again, and it works for me as well. My code works as well in the 3rd party app- the issue is the second time I click the button in the 3rd party app's GUI that calls the RetreiveData() method. That's when it hangs up at this code:
public void Launch(string RIC, DateTime startDate)
{
request = timeSeries.SetupDataRequest(RIC)
.WithView("BID")
.WithAllFields()
.WithInterval(CommonInterval.Daily)
.From(startDate)
.OnDataReceived(DataReceivedCallback)
.CreateAndSend();
}0 -
Thank you again- I'm a little confused by your suggestion. Do you mean the RIC and startDate are out of scope? They are all included in the RetrieveData() method (which is where the Launch is called as well).
Keep in mind that everything here works on the first click of the 3rd party app's button that calls the RetrieveData(), but not on a subsequent click. The Reuter's services remain connected in b/w runs though. So the issue I'm thinking has something to do w/ my use of the DispatcherFrame or the connection somehow going stale but still having a state that is "connected"?
0 -
Steve, would you please drop me an email about this, as I do not have your contact details. We can schedule a support session, and I will try to figure out what might be the reason for this.
my address is evgenij.kovalev(at)tr.com
0
Categories
- All Categories
- 6 AHS
- 37 Alpha
- 161 App Studio
- 4 Block Chain
- 4 Bot Platform
- 16 Connected Risk APIs
- 47 Data Fusion
- 30 Data Model Discovery
- 608 Datastream
- 1.3K DSS
- 577 Eikon COM
- 4.9K Eikon Data APIs
- 7 Electronic Trading
- Generic FIX
- 7 Local Bank Node API
- Trading API
- 2.7K Elektron
- 1.3K EMA
- 236 ETA
- 519 WebSocket API
- 33 FX Venues
- 10 FX Market Data
- 1 FX Post Trade
- 1 FX Trading - Matching
- 12 FX Trading – RFQ Maker
- 5 Intelligent Tagging
- 2 Legal One
- 20 Messenger Bot
- 2 Messenger Side by Side
- 9 ONESOURCE
- 7 Indirect Tax
- 59 Open Calais
- 264 Open PermID
- 39 Entity Search
- 2 Org ID
- PAM
- PAM - Logging
- 8.4K Private Comments
- 6 Product Insight
- Project Tracking
- ProView
- ProView Internal
- 20 RDMS
- 1.4K Refinitiv Data Platform
- 367 Refinitiv Data Platform Libraries
- 3 Refinitiv Due Diligence
- LSEG Due Diligence Portal API
- 3 Refinitiv Due Dilligence Centre
- Rose's Space
- 1.1K Screening
- 18 Qual-ID API
- 13 Screening Deployed
- 23 Screening Online
- 10 World-Check Customer Risk Screener
- 990 World-Check One
- 44 World-Check One Zero Footprint
- 45 Side by Side Integration API
- Test Space
- 3 Thomson One Smart
- 1.2K TR Internal
- Global Hackathon 2015
- 2 Specialists Who Code
- 10 TR Knowledge Graph
- 150 Transactions
- 142 REDI API
- 1.7K TREP APIs
- 4 CAT
- 21 DACS Station
- 117 Open DACS
- 1.1K RFA
- 103 UPA
- 172 TREP Infrastructure
- 224 TRKD
- 886 TRTH
- 5 Velocity Analytics
- 5 Wealth Management Web Services
- 59 Workspace SDK
- 9 Element Framework
- 5 Grid
- 13 World-Check Data File
- Yield Book Analytics
- 46 中文论坛