How to listen to DDE data continuously

330 views Asked by At

Looking for either a python or R solution.


In R, I am able to retrieve DDE data into R from a third-party application using the following request:

library(tcltk2)
tk2dde.request(service = 'prortdde',topic='MNQXXXX', item='last')
"12262.75"

I'd like to continuously update this data. How can i create some kind of dde server or messaging system that would record all changes?

Including the above in a loop means losing data when updates are faster than loop execution... Thanks for any help.


In python, this is my current working code:

import win32ui
import dde

s=dde.CreateServer()
s.Create("prortdde")
c=dde.CreateConversation(s)
c.ConnectTo("prortdde", "MNQXXXX")
c.Connected()
c.Request("last")
# "12262.75"

BUT this will also miss values that are updated simultaneously (this occurs often). What I would need is some type of messaging system that would store all values, even those that are generated at the very same time, so that I can retrieve them later. Is that possible with DDE?

1

There are 1 answers

4
Bilal Qandeel On

I don't know a thing about R language. I just managed to put up this Frankenstein monster here to create a producer-consumer paradigm for your problem.

The plan is to run a non-blocking thread that would keep polling the values you are looking for and augment it to the list data_in_stock using the producer non-blocking function prortdde_produce_continuously. Then wait for you to consume the values at your ease using the function prortdde_consume_one which either returns the latest unconsumed value (if any) or the latest already consumed one old_value.

For the sake of demonstration, I made a loop of ten iterations to print the latest unconsumed value every 5 seconds. (I don't know a thing about your application and I am drawing lines in the sand as estimates of time).

Once you would like to see the infinite production loop stop, just set the flag keep_consuming to FALSE.

THIS CODE IS NOT TESTED. Sorry about that.

library(tcltk2)
library(future)

data_in_stock <- list()
old_value <- ""
keep_producing <- TRUE
last_consumed_value <- ""

prortdde_produce_continuously %<-% {
  while (keep_producing) {
    new_value <- tk2dde.request(service = 'prortdde', topic='MNQXXXX', item='last')
    if (new_value != old_value) {
      # The new value does not have to be pushed to `data_in_stock`
      data_in_stock <- append(data_in_stock, new_value)
            old_value <- new_value
    }
        # Wait for 0.1 seconds (I don't know how fast your data changes)
        sys.sleep(0.1)
  }
}

prortdde_consume_one <- function(){
    if (length(data_in_stock) > 0) {
        last_consumed_value = data_in_stock[1]
        data_in_stock[[1]] <- NULL
        return(last_consumed_value)
    }
    return(old_value)
}

# According to documentation, this line allows the non-blocking execution to happen
plan(multiprocess)

# Keeps polling and `producing` them indefinitely
prortdde_produce_continuously()

# Consumes 10 values
for (val in 1:10) {
    print(prortdde_consume_one)
    sys.sleep(5)
}

# Tells the `producing` to stop
keep_producing <- FALSE