2

Looking to copy Stock options data from Barcharts.com and paste into Excel sheet.

Sub CopyTables()

    Dim ie As Object
    Dim I As Long
    I = 0
    Set ie = CreateObject("InternetExplorer.Application")
    ie.navigate "https://www.barchart.com/stocks/quotes/GOOG/options?moneyness=allRows&view=sbs&expiration=2018-02-23"
    ie.Visible = True

    Do While ie.Busy And Not ie.readyState = 4
        DoEvents
    Loop

    DoEvents

  Set tables = ie.document.getElementsByTagName("table")
  SetDataFromWebTable tables, Range("B5")
  ie.Quit
End Sub

Also how would I extract the dates from the webpage dropdown "Expiration" and paste them all into Excel as well?

I have searched for something that will work for me, no luck!

Community
  • 1
  • 1
Stotch
  • 373
  • 3
  • 10

1 Answers1

1

The webpage source HTML by the link provided

https://www.barchart.com/stocks/quotes/GOOG/options?moneyness=allRows&view=sbs&expiration=2018-02-23

doesn't contain the necessary data, it uses AJAX. The website https://www.barchart.com has an API available. Response is returned in JSON format. Navigate the page e. g. in Chrome, then open Developer Tools window (F12), Network tab, reload (F5) the page and examine logged XHRs. Most relevant data is JSON string returned by the URL:

https://core-api.barchart.com/v1/options/chain?symbol=GOOG&fields=optionType%2CstrikePrice%2ClastPrice%2CpercentChange%2CbidPrice%2CaskPrice%2Cvolume%2CopenInterest&groupBy=strikePrice&meta=field.shortName%2Cfield.description%2Cfield.type&raw=1&expirationDate=2018-02-23

XHR-preview

XHR-headers

You may use the below VBA code to retrieve info as described above. Import JSON.bas module into the VBA project for JSON processing.

Option Explicit

Sub Test48759011()

    Dim sUrl As String
    Dim sJSONString As String
    Dim vJSON As Variant
    Dim sState As String
    Dim aData()
    Dim aHeader()

    sUrl = "https://core-api.barchart.com/v1/options/chain?" & _
        Join(Array( _
            "symbol=GOOG", _
            "fields=" & _
            Join(Array( _
                "optionType", _
                "strikePrice", _
                "lastPrice", _
                "percentChange", _
                "bidPrice", _
                "askPrice", _
                "volume", _
                "openInterest"), _
            "%2C"), _
            "groupBy=", _
            "meta=" & _
            Join(Array( _
                "field.shortName", _
                "field.description", _
                "field.type"), _
            "%2C"), _
            "raw=1", _
            "expirationDate=2018-02-23"), _
        "&")
    With CreateObject("MSXML2.XMLHTTP")
        .Open "GET", sUrl, False
        .send
        sJSONString = .responseText
    End With
    JSON.Parse sJSONString, vJSON, sState
    vJSON = vJSON("data")
    JSON.ToArray vJSON, aData, aHeader
    With Sheets(1)
        .Cells.Delete
        .Cells.WrapText = False
        OutputArray .Cells(1, 1), aHeader
        Output2DArray .Cells(2, 1), aData
        .Columns.AutoFit
    End With

End Sub

Sub OutputArray(oDstRng As Range, aCells As Variant)

    With oDstRng
        .Parent.Select
        With .Resize(1, UBound(aCells) - LBound(aCells) + 1)
            .NumberFormat = "@"
            .Value = aCells
        End With
    End With

End Sub

Sub Output2DArray(oDstRng As Range, aCells As Variant)

    With oDstRng
        .Parent.Select
        With .Resize( _
                UBound(aCells, 1) - LBound(aCells, 1) + 1, _
                UBound(aCells, 2) - LBound(aCells, 2) + 1)
            .NumberFormat = "@"
            .Value = aCells
        End With
    End With

End Sub

The output for me is as follows:

output

To make output closer to Side-by-Side view on the webpage, you may slightly play with query parameters:

    sUrl = "https://core-api.barchart.com/v1/options/chain?" & _
        Join(Array( _
            "symbol=GOOG", _
            "fields=" & _
            Join(Array( _
                "optionType", _
                "strikePrice", _
                "lastPrice", _
                "percentChange", _
                "bidPrice", _
                "askPrice", _
                "volume", _
                "openInterest"), _
            "%2C"), _
            "groupBy=strikePrice", _
            "meta=", _
            "raw=0", _
            "expirationDate=2018-02-23"), _
        "&")

And also change the line

    Set vJSON = vJSON("data")

In that case the output is as follows:

output2

BTW, the similar approach applied in other answers.

omegastripes
  • 12,351
  • 4
  • 45
  • 96
  • It's a nice approach. Plus one for this. – SIM Feb 13 '18 at 11:17
  • Thank you so much @omegastripes ! that's incredible! – Stotch Feb 14 '18 at 17:56
  • @omegastripes I've been struggling all morning to find a way within your provided script to set the Call & Puts columns side by side just like in the webpage https://www.barchart.com/stocks/quotes/GOOG/options?moneyness=allRows&view=sbs&expiration=2018-02-23 . Would you be able to help with this? And I'll keep working on it, but how would I extract the expirations dates as well? Thanks to you I found the expirations available, but am no good at this type of code to extract them :( – Stotch Feb 14 '18 at 17:59
  • @Stotch Try to modify query parameters within `sUrl` (that are shown on the screenshot also).Add `expirationDate` to `fields` parameter, similar to others. – omegastripes Feb 15 '18 at 03:42
  • @omegastripes oh wow that's good! I would've never been able to do that. My hat is off to you! Thank you!!!!! – Stotch Feb 17 '18 at 03:19
  • @omegastripes And just figured out that changing "data" to "meta" scrapes the expiry dates! Thank you again! Hat is off, big time! – Stotch Feb 17 '18 at 03:31
  • @omegastripes The URL has changed and I cannot seem to get the data with any modification I have tried. Would you be able to help with this please and thank you?! https://www.barchart.com/stocks/quotes/GOOG/options – Stotch Jul 20 '18 at 09:53