question

Upvotes
Accepted
1 2 2 6

retrieve data at a specific snap time (follow up)

Hi,

I need to save live RIC values at a very specific snap time. I've got a list of RICs on different feeds, I realized (am I right ?) that the best solution is to group these RICs by feed and setup a data request for each feed.

Here is the code I'm using: (repoDico is my RICs/Fields/Feeds Dictionary)

I'm using ThomsonReuters.Desktop.SDK.DataAccess.Realtime

Can you please have a look and correct what seems wrong to you.

public void Flash(Dictionary<string, ReutersFlashObject> repoDico)
        {
            _flashed = new Dictionary<string, double>();

            List<string> feeds;
            List<string> fields;
            List<string> rics;

            var realtime = services.Realtime;
            feeds = repoDico.Values.Select(x => x.source).Distinct().ToList();

            for (int i = 0; i < feeds.Count; i++)
            {
                fields = repoDico.Values.Where(x => x.source == feeds[i]).Select(x => x.field).Distinct().ToList();
                rics = repoDico.Values.Where(x => x.source == feeds[i]).Select(x => x.ric).Distinct().ToList();

                request = realtime.SetupDataRequest()
                            .WithRics(rics)
                            .WithFields(fields)
                            .WithFeed((feeds[i] == "IDN") ? "" : feeds[i])
                            .OnError(RealTimeDataError)
                            .OnDataReceived(update => DataReceivedCallback(feeds[i], update))
                            .OnStatusReceived(StatusReceived)
                            .CreateAndSend();

                subscription = realtime.SetupDataSubscription()
                            .WithRics(rics)
                            .WithFields(fields)
                            .WithFeed((feeds[i] == "IDN") ? "" : feeds[i])
                            .OnError(RealTimeDataError)
                            .OnDataUpdated(update => DataReceivedCallback(feeds[i], update))
                            .OnStatusUpdated(StatusReceived)
                            .CreateAndStart();
                PushFrame();
            }

        }
private void DataReceivedCallback(string feed, IRealtimeUpdateDictionary updates)
        {
            string ric = "", field = "";
            for (int i = 0; i < updates.Keys.Count; i++)
            {
                ric = updates.Keys.ElementAt(i);
                for (int j = 0; j < updates[ric].Keys.Count; j++)
                {
                    //Save the data somewhere
                }
            }
            Dispatcher.CurrentDispatcher.BeginInvoke(new DispatcherOperationCallback(StopFrame), DispatcherPriority.Background, frame);
        }
private static void PushFrame()
        {
            Dispatcher.ExitAllFrames();
            frame = new DispatcherFrame();
            Dispatcher.PushFrame(frame);
        }
        private static object StopFrame(object f)
        {
            ((DispatcherFrame)f).Continue = false;
         
eikonc#eikon-app-studiosubscriptiondispatcher
icon clock
10 |1500

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

is there a reason you use the subscription object along side the request object? Subscription will send you subsequent updates, while the request just makes a snapshot of the requested data.

Hi Zhenya,

Thanks for your quick answer. I've already submitted this before and I was told to do so. Let me try not to subscribe and get back to you.

Mohammed

Hi again Zhenya,

I'm using only the request object now. I'm still having trouble and I think it comes from the way i'm using the Dispatcher to catch all the updates.
Can you please send me an example of a good practice for a snap.

Thanks
Mohammed

Upvotes
Accepted
47.2k 109 44 60

From the snippet code, the frame has been stopped after the DataReceivedCallback function is called. From my test, the DataReceivedCallback function may be called multiple times for each request. For example, if the application specifies three RICs in the request, the DataReceivedCallback function can be called twice.

The best practice is that the frame shouldn't be stopped. It should be dispatched forever until the application exits.

Can you share the full code so I can modify and test it in my environment?

icon clock
10 |1500

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.


Hi @

jirapongse.phuriphanvichai,

Here's the full code. Can you please share a working sample code if you have it.
Thanks

programcs.txt (3.7 KiB)
Upvotes
1 2 2 6
        #region Dispatcher
        private static void PushFrame()
        {
            DispatcherFrame frame = new DispatcherFrame();
            Dispatcher.CurrentDispatcher.BeginInvoke(new DispatcherOperationCallback(StopFrame), DispatcherPriority.Background, frame);
            Dispatcher.PushFrame(frame);
        }
        private static object StopFrame(object f)
        {
            ((DispatcherFrame)f).Continue = false;
            return null;
        }
        #endregion

        #region RealTime Events

        private void DataReceivedCallback(string feed, string ric, int expectedDataCount, IRealtimeUpdateDictionary updates)
        {

            foreach (string ricKey in updates.Keys)
            {
                foreach (string field in updates[ricKey].Keys)
                {
                    if (!_flashed.ContainsKey(ReutersFlashObject.GetKey(feed, ricKey, field)))
                    {
                        _flashed.Add(ReutersFlashObject.GetKey(feed, ricKey, field), updates[ricKey][field].Value.ToDouble());
                        _flashedTime.Add(ReutersFlashObject.GetKey(feed, ricKey, field), DateTime.Now);
                    }
                    else
                    {
                        Logger.Instance.Log("We have it already: " + ReutersFlashObject.GetKey(feed, ricKey, field));
                    }
                }
            }
        }
        private void RealTimeDataError(RealtimeDataError error)
        {
            Logger.Instance.Log(error.Message, Logger.LogType.Fatal);
        }
        private void StatusReceived(InstrumentStateUpdate statusUpdate)
        {
            Logger.Instance.Log("status update on " + statusUpdate.Ric + ": " + statusUpdate.InstrumentState); 
        }

        #endregion

        public void Flash(Dictionary<string, ReutersFlashObject> repoDico)
        {
            _flashed = new Dictionary<string, double>();
            _flashedTime = new Dictionary<string, DateTime>();

            List<string> feeds;
            List<string> fields;
            List<string> rics;

            var realtime = services.Realtime;
            feeds = repoDico.Values.Select(x => x.source).Distinct().ToList();

            for (int i = 0; i < feeds.Count; i++)
            {                
                rics = repoDico.Values.Where(x => x.source == feeds[i]).Select(x => x.ric).Distinct().ToList();

                for (int j = 0; j < rics.Count; j++)
                {
                    fields = repoDico.Values.Where(x => x.source == feeds[i] && x.ric == rics[j]).Select(x => x.field).Distinct().ToList();

                    //Logger.Instance.Log("request on " + feeds[i] + ";" + rics[j]);

                    request = realtime.SetupDataRequest()
                            .WithRics(rics[j])
                            .WithFields(fields)
                            .WithFeed((feeds[i] == "IDN") ? "" : feeds[i])
                            .OnError(RealTimeDataError)
                            .OnDataReceived(update => DataReceivedCallback(feeds[i],rics[j], fields.Count, update))
                            .OnStatusReceived(StatusReceived)
                            .CreateAndSend();

                    PushFrame();
                }
            }

            //for (int i = 0; i < feeds.Count; i++)
            //{
            //    fields = repoDico.Values.Where(x => x.source == feeds[i]).Select(x => x.field).Distinct().ToList();
            //    rics = repoDico.Values.Where(x => x.source == feeds[i]).Select(x => x.ric).Distinct().ToList();

            //    request = realtime.SetupDataRequest()
            //                .WithRics(rics)
            //                .WithFields(fields)
            //                .WithFeed((feeds[i] == "IDN") ? "" : feeds[i])
            //                .OnError(RealTimeDataError)
            //                .OnDataReceived(update => DataReceivedCallback(feeds[i], repoDico.Values.Where(x => x.source == feeds[i]).Count(), update))
            //                .OnStatusReceived(StatusReceived)
            //                .CreateAndSend();

            //    //subscription = realtime.SetupDataSubscription()
            //    //            .WithRics(rics)
            //    //            .WithFields(fields)
            //    //            .WithFeed((feeds[i] == "IDN") ? "" : feeds[i])
            //    //            .OnError(RealTimeDataError)
            //    //            .OnDataUpdated(update => DataReceivedCallback(feeds[i], update))
            //    //            .OnStatusUpdated(StatusReceived)
            //    //            .CreateAndStart();

            //    PushFrame();
            //}

            Dispatcher.ExitAllFrames();

        }
icon clock
10 |1500

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.