Example of a Request (VB)Script

The following script demonstrates the basic mechanism needed to take advantage of the TBXDS service. The script basically retrieves the <Last> quote plus time and relative difference (or the <Close> or <Previous> value if no <Last> value is present). It stores nothing (you'll have to take care of this), but it simply echoes the data it needs to store to the console.

To use this example, simply cut and past the code into your favorite editor and change lines 5 and 6 (the TICKER_ID and EXCHANGE_ID values), and save it as tbxds-test.vbs in the same folder as where tbxds-request.xml is located. Next, use cscript tbxds-test.vbs and the script will show you it's progress:

C:\TBXDS Test Folder>cscript tbxds-test.vbs
Current: 14.18 +0.07% (5/2/2001 12:25:25)
(!) Data successfully received

C:\TBXDS Test Folder>_

The request XML file should in this case be limited to a single <Quote> request.

Requirements

You'll need pretty recent versions of VBScript and MSXML. A safe bet is VBScript 5(+) and MSXML 3.0 (Service Pack 1). This script uses no other facilities. In a production version, you'll probably need ADO or the FileSystemObject (the latter comes with VBScript), or other solutions, since this script is pretty much 'dressed down'.

The Code

tbxds-test.vbs; an example of a request in VBScript

Option Explicit

Const REQUEST_FILE   = "tbxds-request.xml"
Const REQUEST_SERVER = "http://ws.vwdservices.com/tbxds/tbxds.asp
Const TICKER_ID      = "???" ' From request
Const EXCHANGE_ID    = "???" ' Ditto
Const LAST_TEMPLATE  = "Current: {last} {diff}% ({time})"
Const CLOSE_TEMPLATE = "At closing: {last} ({time})"

' Call the Main procedure
Main

Sub Main()
' Description:
'   The main procedure. Sets up the HTTP connection and exchanges
'   data; afterwards it will call SaveQuote to store the 
'   received data.
'
    ' Helper objects
    Dim requestDOM, responseDOM, xmlHTTP
    
    Set requestDOM = CreateObject("MSXML2.DOMDocument")    
    
    ' responseDOM is later set to an automatically generated instance
    ' of MSXML2.DOMDocument
    
    Set xmlHTTP    = CreateObject("MSXML2.XMLHTTP")

    ' try to load the request message
    If requestDOM.load(REQUEST_FILE) Then
        
        ' Open HTTP connection and send request
        xmlHTTP.open "POST", REQUEST_SERVER, False
        xmlHTTP.send requestDOM
        
        ' You should check for errors here
        
        Set responseDOM = xmlHTTP.responseXML
        ' Save the quote data
        If SaveQuote(responseDOM) Then
            LogEvent 0, "Data successfully received"
        Else
            LogEvent 1, "Could not retrieve quote data"
        End If
    Else
        LogEvent 1, "Could not load request XML"
    End If
End Sub

Function SaveQuote(ByRef xmlDOM)
' Description:
'   SaveQuote extracts the most current data from the received XML.
'   It should probably check for Event nodes if it can't find any 
'   data, but this is only a prototype.
'
    Dim quoteNode, lastNode
    Dim lastValue, lastTime, lastDiff, lastDiffValue
    Dim searchXPath
    Dim saveText, saveTemplate
    
    searchXPath = "/TBMData/Sector/Organisation/Issue[@exchange='" _
                & EXCHANGE_ID & "' and Ticker[@id='" _
                & TICKER_ID & "']]/Quote"
    
    Set quoteNode = xmlDOM.selectSingleNode(searchXPath)
    
    If quoteNode Is Nothing Then
        SaveQuote = False
    Else
    
        ' Extract either Last, Close or Previous.
        ' The Close is queried fist, to indicate that
        ' the exchange has closed. (Note that Close is
        ' only available after closing and before opening.)
        ' The Last is usually present, even after closing,
        ' but in some specific circumstances it could be
        ' missing, and only a Previous will be present.
        
        Set lastNode = quoteNode.selectSingleNode("Close")
        If lastNode Is Nothing Then
            Set lastNode = quoteNode.selectSingleNode("Last")
            If lastNode Is Nothing Then
                Set lastNode = quoteNode.selectSingleNode("Previous")
            End If
        End If
        
        If lastNode Is Nothing Then
            SaveQuote = False
        Else
            Select Case lastNode.nodeName
                Case "Previous"
                    ' The Previous node contains the quotes for the
                    ' previous exchange day, so it contains its own
                    ' date attribute.
                    lastValue = ToDouble(lastNode.getAttribute("value"))
                    lastTime  = ToDate(lastNode.getAttribute("date") _
                              & " " & lastNode.getAttribute("date"))
                    lastDiff  = ""
                    saveText = CLOSE_TEMPLATE
                Case "Close"
                    lastValue = ToDouble(lastNode.getAttribute("value"))
                    ' the date for Close and Last are located at
                    ' the Quote (i.e., parent) level
                    lastTime  = ToDate(lastNode.parentNode.getAttribute("date") _
                              & " " & lastNode.getAttribute("time"))
                    lastDiff  = ""
                    saveText = CLOSE_TEMPLATE
                Case "Last"
                    lastValue = ToDouble(lastNode.getAttribute("value"))
                    ' the date for Close and Last are located at
                    ' the Quote (i.e., parent) level
                    lastTime  = ToDate(lastNode.parentNode.getAttribute("date") _
                              & " " & lastNode.getAttribute("time"))
                    lastDiffValue = _
                         ToDouble(lastNode.getAttribute("relative-difference")) _
                                  * 100
                    ' Take care we have either a + or -
                    If lastDiffValue > 0 Then
                        lastDiff = "+" & FormatNumber(lastDiffValue)
                    Else
                        lastDiff = FormatNumber(lastDiffValue)
                    End If
                    saveText = LAST_TEMPLATE
            End Select
            ' Fill in the templates. Formats the last quote to 
            ' keep the local number formatting intact, ditto for the
            ' date. lastDiff is already formatted.
            saveText = Replace(saveText, "{last}", _
                         FormatNumber(lastValue, 2, True, False, True))
            saveText = Replace(saveText, "{time}", _
                         FormatDateTime(lastTime, vbGeneralDate))
            saveText = Replace(saveText, "{diff}", lastDiff)
            ' Store the quote text somewhere
            StoreQuote saveText
            ' Regardless of the success of StoreQuote, the retrieval
            ' is successfull.
            SaveQuote = True
        End If        
    End If
End Function

Sub StoreQuote(quoteText)
' Description:
'   This StoreQuote procedure only echoes the line to the screen;
'   in actual applications, you'd save this text to a file, or
'   use a database instead.
    WScript.Echo quoteText
End Sub

Sub LogEvent(eventStatus, eventText)
' Description:
'   This procedure logs the progress of the script. In this case, it 
'   merely echoes the events to the screen.
'
'   eventStatus Indicates
'   0           Success
'   1           Error/Failure
    Select Case eventStatus
        Case 0 
            WScript.Echo "(!) " & eventText
        Case 1
            WScript.Echo "(X) " & eventText
        Case Else
            WScript.Echo "(?) " & eventText
    End Select
End Sub

Function ToDouble(someString)
' Description:
'   Parse number to double; VBScript's CDbl will convert "1.2" to 12 
'   if "," is the decimal separator, so check first, because TBXDS 
'   will deliver ".".
    If IsNumeric(someString) Then 
        ' getAttribute could return Null, and CDbl(Null) throws an
        ' error. IsNumeric will return False in this case.
        If CStr(1.2) = "1,2" Then
            ToDouble = CDbl(Replace(someString, ".", ","))
        Else
            ToDouble = CDbl(someString)
        End If
    Else
        ToDouble = 0
    End If
End Function

Function ToDate(someString)
' Description:
'   Parse date string to Variant Date; VBScript's CDate will do just 
'   fine for "yyyy/mm/dd hh:mm:ss" strings, since this format is not
'   ambiguous.
    If IsDate(someString) Then
        ToDate = CDate(someString)
    Else
        ' Bogus value in case of non-date
        ToDate = #2000/02/28#
    End If
End Function

See also

Frequently Asked Questions