Forum Discussion

Article43's avatar
Article43
Copper Contributor
Jan 02, 2022

How to move a cell value using an RTD formula (pulling in live updating data) when it changes?

Hi,

I am using Interactive Brokers TWS trading platform and they supply a demo excel file that has RTD formulas to pull in a list of available live data trading prices such as Bid, Ask, Last, etc.

 

The RTD connection does not allow you to pull in historical data for the trading prices mentioned above.

 

What I am want to do is the following, if possible:

 

The Last price traded for the MES Futures contract is pulled into cell F3 by using the following formula:

 

 

I am currently connected to the TWS trading platform and the value in cell F3 is 4761.25

As soon as the markets reopen this value will change continuously.

 

I want to be able to capture the price of 4671.25 that is pulled into cell F3 and move it down by one cell as it changes - for whatever number of cells I decide to capture.

 

For example, if I decide to capture the Last 20 prices, then I want to populate the range F3 to F22.

Once I can move the changing values into the cells below, I can then use conditional formatting to change the cell colors based on the criteria I use, which is my objective of the exercise.

 

Thank You.

 

 

2 Replies

  • bookstaber's avatar
    bookstaber
    Copper Contributor

    This is doable with a short event handler. Two Excel facts explain why the obvious approaches fail, then working code.

    1. RTD values arrive through recalculation, and recalculation does not fire Worksheet_Change — that event fires on edits, not recalcs. The event that fires on every RTD update is Worksheet_Calculate.
    2. Excel batches RTD updates. By default Excel updates RTD values application-wide at most once every 2,000 ms (Application.RTD.ThrottleInterval), so what you can capture is each updated value, not every tick the exchange printed. If you want finer sampling, run Application.RTD.ThrottleInterval = 250 once in the VBA Immediate window (per Microsoft the new value persists across Excel restarts).

     

    With your live RTD price in F3, the code below keeps F4:F22 as the capture history — the 19 most recent prices, newest at the top, everything shifting down one row on each new price, oldest dropped. Right-click the sheet tab → View Code → paste into that sheet's module:

    Private mLast As Variant
    
    Private Sub Worksheet_Calculate()
        Dim v As Variant
        v = Me.Range("F3").Value2
    
        If IsError(v) Or IsEmpty(v) Then Exit Sub   ' RTD not connected / no value yet
        If Not IsNumeric(v) Then Exit Sub           ' ignore text/status values
        If v = mLast Then Exit Sub                  ' this recalc didn't change the price
    
        On Error GoTo CleanUp
        Application.EnableEvents = False            ' don't re-trigger this handler
    
        ' Shift history down one row: F3:F21 -> F4:F22 (old F22 falls off)
        Me.Range("F4:F22").Value2 = Me.Range("F3:F21").Value2
    
    CleanUp:
        mLast = v
        Application.EnableEvents = True
    End Sub

    Why the guards matter:

    • Application.EnableEvents = False prevents the infinite loop: writing to F4:F22 can trigger another recalculation, which would re-fire Worksheet_Calculate. The On Error … CleanUp pattern guarantees events get re-enabled even if the write fails.
    • v = mLast makes the handler a no-op when the sheet recalculated for any other reason (some other formula, another RTD cell). It also means two successive identical prints record once. If you want every update regardless, compare a timestamp field from your feed instead of the price.
    • To timestamp each capture, keep a parallel column: add Me.Range("G5:G22").Value2 = Me.Range("G4:G21").Value2 and then Me.Range("G4").Value = Now just before CleanUp.  G4 then holds the capture time of the value in F4.

    This works with any RTD feed, including the TWS RTD sample you're using. One scope note on that sample: per IBKR's docs, "only top-level market data is supported via TWS RTD Server API" — quotes only, so account values, positions, and orders won't arrive through it. Disclosure: I develop StreamXLS (streamxls.com), a commercial RTD server for the TWS API that adds the account, position, and order layer; the capture code above works unchanged with either server.