' Class Module: Client Option Explicit Private appKey As String Private appSecret As String Private callbackURL As String Private tokensFile As String Private timeout As Integer Private verbose As Boolean Private showLinked As Boolean Private accessToken As String Private refreshToken As String Private idToken As String Private accessTokenIssued As Date Private refreshTokenIssued As Date Private accessTokenTimeout As Long Private refreshTokenTimeout As Long Private Const baseURL As String = "https://api.schwabapi.com" Public Sub Init(Optional ByVal timeout_seconds As Integer = 5, _ Optional ByVal is_verbose As Boolean = False, _ Optional ByVal show_linked_accounts As Boolean = False) appKey = ThisWorkbook.Sheets("Settings").range("B9").Value appSecret = ThisWorkbook.Sheets("Settings").range("B10").Value callbackURL = ThisWorkbook.Sheets("Settings").range("B11").Value If Len(appKey) <> 32 Or Len(appSecret) <> 16 Then MsgBox "App key or app secret invalid length.", vbCritical Exit Sub End If timeout = timeout_seconds verbose = is_verbose showLinked = show_linked_accounts accessTokenTimeout = 1800 ' 30 minutes refreshTokenTimeout = 7 ' 7 days ' Try to load tokens from the tokens file Dim atIssued As String, rtIssued As String, tokenDict As Object atIssued = ThisWorkbook.Sheets("Settings").range("B15").Value rtIssued = ThisWorkbook.Sheets("Settings").range("B16").Value If atIssued <> "" And rtIssued <> "" Then ' Check if tokens need to be updated accessTokenIssued = atIssued refreshTokenIssued = rtIssued Call UpdateTokens Else Call UpdateRefreshToken End If If verbose Then MsgBox "Initialization Complete", vbInformation End Sub Public Function GetAccountHash() As String Dim accountNumber As String accountNumber = ThisWorkbook.Sheets("Settings").range("B8").Value accountNumber = Replace(accountNumber, "-", "") accountNumber = Replace(accountNumber, " ", "") Dim resp As Object Set resp = AccountLinked() Dim accounts As Object, account As Object Set accounts = JsonConverter.ParseJson(resp.responseText) Dim hashValue As String Dim x As Integer For x = 1 To accounts.Count Set account = accounts(x) If account("accountNumber") = accountNumber Then hashValue = account("hashValue") Exit For End If Next x If hashValue = "" Then MsgBox "Could not get account hashValue for your AccountNumber. Check your Settings:B8 Cell", vbCritical End If GetAccountHash = hashValue End Function Public Sub UpdateTokens() If DateDiff("d", refreshTokenIssued, now) >= (refreshTokenTimeout - 1) Then Call UpdateRefreshToken ElseIf DateDiff("s", accessTokenIssued, now) >= (accessTokenTimeout - 61) Then If verbose Then MsgBox "The access token has expired, updating automatically.", vbInformation Call UpdateAccessToken Else accessToken = ThisWorkbook.Sheets("Settings").range("B12").Value refreshToken = ThisWorkbook.Sheets("Settings").range("B13").Value End If End Sub Private Sub UpdateAccessToken() Dim tokenDict As Object Dim response As Object Dim responseText As String Set tokenDict = New dictionary accessToken = ThisWorkbook.Sheets("Settings").range("B12").Value refreshToken = ThisWorkbook.Sheets("Settings").range("B13").Value Set response = PostOAuthToken("refresh_token", refreshToken) responseText = response.responseText If response.status = 200 Then accessTokenIssued = now refreshTokenIssued = refreshTokenIssued Set tokenDict = JsonConverter.ParseJson(response.responseText) accessToken = tokenDict("access_token") refreshToken = tokenDict("refresh_token") idToken = tokenDict("id_token") ' Call WriteTokensFile(accessTokenIssued, refreshTokenIssued, tokenDict) ThisWorkbook.Sheets("Settings").range("B12").Value = accessToken ThisWorkbook.Sheets("Settings").range("B13").Value = refreshToken ThisWorkbook.Sheets("Settings").range("B14").Value = idToken ThisWorkbook.Sheets("Settings").range("B15").Value = now ThisWorkbook.Sheets("Settings").range("B16").Value = now If verbose Then MsgBox "Access token updated: " & accessTokenIssued, vbInformation Else MsgBox "Could not get new access token. Check credentials.", vbCritical End If End Sub Private Function GetUrlParameter(url As String, paramName As String) As String Dim startPos As Long Dim endPos As Long Dim paramValue As String Dim paramLength As Long Dim param As String ' Construct the parameter string to search for param = paramName & "=" paramLength = Len(param) ' Find the start position of the parameter value startPos = InStr(url, param) If startPos = 0 Then GetUrlParameter = "" ' Parameter not found Exit Function End If ' Move startPos to the end of the parameter name startPos = startPos + paramLength ' Find the end position of the parameter value endPos = InStr(startPos, url, "&") If endPos = 0 Then ' Parameter value goes until the end of the string paramValue = Mid(url, startPos) Else ' Parameter value ends at the next "&" paramValue = Mid(url, startPos, endPos - startPos) End If ' Return the parameter value GetUrlParameter = paramValue End Function Private Sub UpdateRefreshToken() Dim authURL As String Dim responseURL As String Dim code As String Dim response As Object Dim responseText As String authURL = "https://api.schwabapi.com/v1/oauth/authorize?client_id=" & appKey & "&redirect_uri=" & callbackURL MsgBox "Please authorize this program to access your Schwab account.", vbInformation ThisWorkbook.FollowHyperlink authURL responseURL = InputBox("After authorizing, wait for it to load (<1min) and paste the WHOLE URL here:") code = GetUrlParameter(responseURL, "code") Set response = PostOAuthToken("authorization_code", code) responseText = response.responseText If response.status = 200 Then accessTokenIssued = now refreshTokenIssued = now Dim tokenDict As Object Set tokenDict = JsonConverter.ParseJson(response.responseText) accessToken = tokenDict("access_token") refreshToken = tokenDict("refresh_token") idToken = tokenDict("id_token") ' Call WriteTokensFile(accessTokenIssued, refreshTokenIssued, tokenDict) ThisWorkbook.Sheets("Settings").range("B12").Value = accessToken ThisWorkbook.Sheets("Settings").range("B13").Value = refreshToken ThisWorkbook.Sheets("Settings").range("B14").Value = idToken ThisWorkbook.Sheets("Settings").range("B15").Value = now ThisWorkbook.Sheets("Settings").range("B16").Value = now MsgBox "Refresh and Access tokens updated", vbInformation Else MsgBox "Could not get new refresh and access tokens. Check app status, credentials, and URL expiration.", vbCritical End If End Sub Private Function PostOAuthToken(ByVal grant_type As String, ByVal code As String) As Object Dim xmlHttp As Object Dim postData As String Set xmlHttp = CreateObject("MSXML2.XMLHTTP") If grant_type = "authorization_code" Then postData = "grant_type=authorization_code&code=" & code & "&redirect_uri=" & callbackURL ElseIf grant_type = "refresh_token" Then postData = "grant_type=refresh_token&refresh_token=" & code Else MsgBox "Invalid grant type", vbCritical Exit Function End If xmlHttp.Open "POST", "https://api.schwabapi.com/v1/oauth/token", False xmlHttp.setRequestHeader "Authorization", "Basic " & Base64Encode(appKey & ":" & appSecret) xmlHttp.setRequestHeader "Content-Type", "application/x-www-form-urlencoded" xmlHttp.send postData Set PostOAuthToken = xmlHttp End Function Private Function Base64Encode(text As String) As String Dim arrData() As Byte Dim objXML As Object Dim objNode As Object ' Convert the string to a byte array arrData = StrConv(text, vbFromUnicode) ' Create an XML document and add a node Set objXML = CreateObject("MSXML2.DOMDocument") Set objNode = objXML.createElement("Base64Data") objNode.DataType = "bin.base64" objNode.nodeTypedValue = arrData objXML.appendChild objNode ' Return the base64-encoded string Base64Encode = objNode.text ' Clean up Set objNode = Nothing Set objXML = Nothing End Function Public Function AccountLinked() As Object Dim xmlHttp As Object Set xmlHttp = CreateObject("MSXML2.XMLHTTP") xmlHttp.Open "GET", baseURL & "/trader/v1/accounts/accountNumbers", False xmlHttp.setRequestHeader "Authorization", "Bearer " & accessToken xmlHttp.send Set AccountLinked = xmlHttp Set xmlHttp = Nothing End Function ' Add more methods as needed following the above examples Public Function AccountDetailsAll(Optional ByVal fields As String = "") As Object Dim xmlHttp As Object Dim url As String Dim token As String Dim params As String token = "Bearer " & accessToken ' Ensure accessToken is set appropriately url = baseURL & "/trader/v1/accounts/" If fields <> "" Then params = "?fields=" & fields End If Set xmlHttp = CreateObject("MSXML2.XMLHTTP") xmlHttp.Open "GET", url & params, False xmlHttp.setRequestHeader "Authorization", token xmlHttp.setRequestHeader "Content-Type", "application/x-www-form-urlencoded" xmlHttp.send Set AccountDetailsAll = JsonConverter.ParseJson(xmlHttp.responseText) Set xmlHttp = Nothing End Function Public Function accountDetails(accountHash As String, Optional ByVal fields As String = "") As Object Dim xmlHttp As Object Dim url As String Dim token As String Dim params As String token = "Bearer " & accessToken ' Ensure accessToken is set appropriately url = baseURL & "/trader/v1/accounts/" & accountHash If fields <> "" Then params = "?fields=" & fields End If Set xmlHttp = CreateObject("MSXML2.XMLHTTP") xmlHttp.Open "GET", url & params, False xmlHttp.setRequestHeader "Authorization", token xmlHttp.setRequestHeader "Content-Type", "application/x-www-form-urlencoded" xmlHttp.send Set accountDetails = JsonConverter.ParseJson(xmlHttp.responseText) Set xmlHttp = Nothing End Function Public Function AccountOrders(accountHash As String, fromEnteredTime As String, toEnteredTime As String, Optional ByVal maxResults As Long = 1000, Optional ByVal status As String = "") As Object Dim xmlHttp As Object Dim url As String Dim token As String Dim params As String token = "Bearer " & accessToken ' Ensure accessToken is set appropriately url = baseURL & "/trader/v1/accounts/" & accountHash & "/orders" params = "?fromEnteredTime=" & fromEnteredTime & "&toEnteredTime=" & toEnteredTime If maxResults > 0 Then params = params & "&maxResults=" & maxResults End If If status <> "" Then params = params & "&status=" & status End If Set xmlHttp = CreateObject("MSXML2.XMLHTTP") xmlHttp.Open "GET", url & params, False xmlHttp.setRequestHeader "Authorization", token xmlHttp.setRequestHeader "Content-Type", "application/x-www-form-urlencoded" xmlHttp.send Set AccountOrders = JsonConverter.ParseJson(xmlHttp.responseText) Set xmlHttp = Nothing End Function Public Function OrderPlace(accountHash As String, order As String) As String Dim xmlHttp As Object Dim url As String Dim token As String token = "Bearer " & accessToken ' Ensure accessToken is set appropriately url = baseURL & "/trader/v1/accounts/" & accountHash & "/orders" Set xmlHttp = CreateObject("MSXML2.XMLHTTP") xmlHttp.Open "POST", url, False xmlHttp.setRequestHeader "Authorization", token xmlHttp.setRequestHeader "Content-Type", "application/json" xmlHttp.setRequestHeader "Accept", "application/json" xmlHttp.send order OrderPlace = xmlHttp.responseText Set xmlHttp = Nothing End Function Public Function OrderDetails(accountHash As String, orderId As String) As Object Dim xmlHttp As Object Dim url As String Dim token As String token = "Bearer " & accessToken ' Ensure accessToken is set appropriately url = baseURL & "/trader/v1/accounts/" & accountHash & "/orders/" & orderId Set xmlHttp = CreateObject("MSXML2.XMLHTTP") xmlHttp.Open "GET", url, False xmlHttp.setRequestHeader "Authorization", token xmlHttp.setRequestHeader "Content-Type", "application/x-www-form-urlencoded" xmlHttp.send Set OrderDetails = JsonConverter.ParseJson(xmlHttp.responseText) Set xmlHttp = Nothing End Function Public Function OrderCancel(accountHash As String, orderId As String) As Object Dim xmlHttp As Object Dim url As String Dim token As String token = "Bearer " & accessToken ' Ensure accessToken is set appropriately url = baseURL & "/trader/v1/accounts/" & accountHash & "/orders/" & orderId Set xmlHttp = CreateObject("MSXML2.XMLHTTP") xmlHttp.Open "DELETE", url, False xmlHttp.setRequestHeader "Authorization", token xmlHttp.setRequestHeader "Content-Type", "application/x-www-form-urlencoded" xmlHttp.send Set OrderCancel = JsonConverter.ParseJson(xmlHttp.responseText) Set xmlHttp = Nothing End Function Public Function OrderReplace(accountHash As String, orderId As String, order As String) As Object Dim xmlHttp As Object Dim url As String Dim token As String token = "Bearer " & accessToken ' Ensure accessToken is set appropriately url = baseURL & "/trader/v1/accounts/" & accountHash & "/orders/" & orderId Set xmlHttp = CreateObject("MSXML2.XMLHTTP") xmlHttp.Open "PUT", url, False xmlHttp.setRequestHeader "Authorization", token xmlHttp.setRequestHeader "Content-Type", "application/json" xmlHttp.setRequestHeader "Accept", "application/json" xmlHttp.send order Set OrderReplace = JsonConverter.ParseJson(xmlHttp.responseText) Set xmlHttp = Nothing End Function Public Function AccountOrdersAll(fromEnteredTime As String, toEnteredTime As String, Optional ByVal maxResults As Long = 0, Optional ByVal status As String = "") As Object Dim xmlHttp As Object Dim url As String Dim token As String Dim params As String token = "Bearer " & accessToken ' Ensure accessToken is set appropriately url = baseURL & "/trader/v1/orders" params = "?fromEnteredTime=" & fromEnteredTime & "&toEnteredTime=" & toEnteredTime If maxResults > 0 Then params = params & "&maxResults=" & maxResults End If If status <> "" Then params = params & "&status=" & status End If Set xmlHttp = CreateObject("MSXML2.XMLHTTP") xmlHttp.Open "GET", url & params, False xmlHttp.setRequestHeader "Authorization", token xmlHttp.setRequestHeader "Content-Type", "application/x-www-form-urlencoded" xmlHttp.send Set AccountOrdersAll = JsonConverter.ParseJson(xmlHttp.responseText) Set xmlHttp = Nothing End Function Public Function Transactions(accountHash As String, startDate As String, endDate As String, types As String, Optional ByVal symbol As String = "") As Object Dim xmlHttp As Object Dim url As String Dim token As String Dim params As String token = "Bearer " & accessToken ' Ensure accessToken is set appropriately url = baseURL & "/trader/v1/accounts/" & accountHash & "/transactions" params = "?startDate=" & startDate & "&endDate=" & endDate & "&types=" & types If symbol <> "" Then params = params & "&symbol=" & symbol End If Set xmlHttp = CreateObject("MSXML2.XMLHTTP") xmlHttp.Open "GET", url & params, False xmlHttp.setRequestHeader "Authorization", token xmlHttp.setRequestHeader "Content-Type", "application/x-www-form-urlencoded" xmlHttp.send Transactions = JsonConverter.ParseJson(xmlHttp.responseText) Set xmlHttp = Nothing End Function Public Function TransactionDetails(accountHash As String, transactionId As String) As Object Dim xmlHttp As Object Dim url As String Dim token As String token = "Bearer " & accessToken ' Ensure accessToken is set appropriately url = baseURL & "/trader/v1/accounts/" & accountHash & "/transactions/" & transactionId Set xmlHttp = CreateObject("MSXML2.XMLHTTP") xmlHttp.Open "GET", url, False xmlHttp.setRequestHeader "Authorization", token xmlHttp.setRequestHeader "Content-Type", "application/x-www-form-urlencoded" xmlHttp.send Set TransactionDetails = JsonConverter.ParseJson(xmlHttp.responseText) Set xmlHttp = Nothing End Function Public Function Preferences() As Object Dim xmlHttp As Object Dim url As String Dim token As String token = "Bearer " & accessToken ' Ensure accessToken is set appropriately url = baseURL & "/trader/v1/userPreference" Set xmlHttp = CreateObject("MSXML2.XMLHTTP") xmlHttp.Open "GET", url, False xmlHttp.setRequestHeader "Authorization", token xmlHttp.setRequestHeader "Content-Type", "application/x-www-form-urlencoded" xmlHttp.send Set Preferences = JsonConverter.ParseJson(xmlHttp.responseText) Set xmlHttp = Nothing End Function Public Function Quotes(symbols As String, Optional fields As String = "", Optional indicative As Boolean = False) As Object Dim xmlHttp As Object Dim url As String Dim token As String Dim params As String token = "Bearer " & accessToken ' Ensure accessToken is set appropriately url = baseURL & "/marketdata/v1/quotes" params = "?symbols=" & symbols If fields <> "" Then params = params & "&fields=" & fields End If params = params & "&indicative=" & IIf(indicative, "true", "false") Set xmlHttp = CreateObject("MSXML2.XMLHTTP") xmlHttp.Open "GET", url & params, False xmlHttp.setRequestHeader "Authorization", token xmlHttp.setRequestHeader "Content-Type", "application/x-www-form-urlencoded" xmlHttp.send Set Quotes = JsonConverter.ParseJson(xmlHttp.responseText) Set xmlHttp = Nothing End Function Public Function Quote(symbol_id As String, Optional fields As String = "") As Object Dim xmlHttp As Object Dim url As String Dim token As String Dim params As String token = "Bearer " & accessToken ' Ensure accessToken is set appropriately url = baseURL & "/marketdata/v1/" & symbol_id & "/quotes" If fields <> "" Then params = "?fields=" & fields End If Set xmlHttp = CreateObject("MSXML2.XMLHTTP") xmlHttp.Open "GET", url & params, False xmlHttp.setRequestHeader "Authorization", token xmlHttp.setRequestHeader "Content-Type", "application/x-www-form-urlencoded" xmlHttp.send If xmlHttp.status = 200 Then Set Quote = JsonConverter.ParseJson(xmlHttp.responseText) Else Set Quote = Nothing End If Set xmlHttp = Nothing End Function Public Function OptionChains(symbol As String, Optional contractType As String = "", Optional strikeCount As Long = 0, Optional includeUnderlyingQuote As Boolean = False, Optional strategy As String = "", Optional interval As String = "", Optional strike As Double = 0, Optional range As String = "", Optional fromDate As String = "", Optional toDate As String = "", Optional volatility As Double = 0, Optional underlyingPrice As Double = 0, Optional interestRate As Double = 0, Optional daysToExpiration As Long = 0, Optional expMonth As String = "", Optional optionType As String = "", Optional entitlement As String = "") As Object Dim xmlHttp As Object Dim url As String Dim token As String Dim params As String token = "Bearer " & accessToken ' Ensure accessToken is set appropriately url = baseURL & "/marketdata/v1/chains" params = "?symbol=" & symbol If contractType <> "" Then params = params & "&contractType=" & contractType End If If strikeCount > 0 Then params = params & "&strikeCount=" & strikeCount End If params = params & "&includeUnderlyingQuote=" & IIf(includeUnderlyingQuote, "true", "false") If strategy <> "" Then params = params & "&strategy=" & strategy End If If interval <> "" Then params = params & "&interval=" & interval End If If strike > 0 Then params = params & "&strike=" & strike End If If range <> "" Then params = params & "&range=" & range End If If fromDate <> "" Then params = params & "&fromDate=" & fromDate End If If toDate <> "" Then params = params & "&toDate=" & toDate End If If volatility > 0 Then params = params & "&volatility=" & volatility End If If underlyingPrice > 0 Then params = params & "&underlyingPrice=" & underlyingPrice End If If interestRate > 0 Then params = params & "&interestRate=" & interestRate End If If daysToExpiration > 0 Then params = params & "&daysToExpiration=" & daysToExpiration End If If expMonth <> "" Then params = params & "&expMonth=" & expMonth End If If optionType <> "" Then params = params & "&optionType=" & optionType End If If entitlement <> "" Then params = params & "&entitlement=" & entitlement End If Set xmlHttp = CreateObject("MSXML2.XMLHTTP") xmlHttp.Open "GET", url & params, False xmlHttp.setRequestHeader "Authorization", token xmlHttp.setRequestHeader "Content-Type", "application/x-www-form-urlencoded" xmlHttp.send Set OptionChains = JsonConverter.ParseJson(xmlHttp.responseText) Set xmlHttp = Nothing End Function Public Function OptionExpirationChain(symbol As String) As Object Dim xmlHttp As Object Dim url As String Dim token As String Dim params As String token = "Bearer " & accessToken ' Ensure accessToken is set appropriately url = baseURL & "/marketdata/v1/expirationchain" params = "?symbol=" & symbol Set xmlHttp = CreateObject("MSXML2.XMLHTTP") xmlHttp.Open "GET", url & params, False xmlHttp.setRequestHeader "Authorization", token xmlHttp.setRequestHeader "Content-Type", "application/x-www-form-urlencoded" xmlHttp.send Set OptionExpirationChain = JsonConverter.ParseJson(xmlHttp.responseText) Set xmlHttp = Nothing End Function Public Function PriceHistory(symbol As String, Optional periodType As String = "", Optional period As Long = 0, Optional frequencyType As String = "", Optional frequency As Long = 0, Optional startDate As String = "", Optional endDate As String = "", Optional needExtendedHoursData As Boolean = False, Optional needPreviousClose As Boolean = False) As Object Dim xmlHttp As Object Dim url As String Dim token As String Dim params As String token = "Bearer " & accessToken ' Ensure accessToken is set appropriately url = baseURL & "/marketdata/v1/pricehistory" params = "?symbol=" & symbol If periodType <> "" Then params = params & "&periodType=" & periodType End If If period > 0 Then params = params & "&period=" & period End If If frequencyType <> "" Then params = params & "&frequencyType=" & frequencyType End If If frequency > 0 Then params = params & "&frequency=" & frequency End If If startDate <> "" Then params = params & "&startDate=" & startDate End If If endDate <> "" Then params = params & "&endDate=" & endDate End If params = params & "&needExtendedHoursData=" & IIf(needExtendedHoursData, "true", "false") params = params & "&needPreviousClose=" & IIf(needPreviousClose, "true", "false") Set xmlHttp = CreateObject("MSXML2.XMLHTTP") xmlHttp.Open "GET", url & params, False xmlHttp.setRequestHeader "Authorization", token xmlHttp.setRequestHeader "Content-Type", "application/x-www-form-urlencoded" xmlHttp.send Set PriceHistory = JsonConverter.ParseJson(xmlHttp.responseText) Set xmlHttp = Nothing End Function Public Function Movers(symbol As String, Optional sort As String = "", Optional frequency As Long = 0) As Object Dim xmlHttp As Object Dim url As String Dim token As String Dim params As String token = "Bearer " & accessToken ' Ensure accessToken is set appropriately url = baseURL & "/marketdata/v1/movers/" & symbol params = "?" If sort <> "" Then params = params & "sort=" & sort & "&" End If If frequency > 0 Then params = params & "frequency=" & frequency End If Set xmlHttp = CreateObject("MSXML2.XMLHTTP") xmlHttp.Open "GET", url & params, False xmlHttp.setRequestHeader "Authorization", token xmlHttp.setRequestHeader "Content-Type", "application/x-www-form-urlencoded" xmlHttp.send Set Movers = JsonConverter.ParseJson(xmlHttp.responseText) Set xmlHttp = Nothing End Function Public Function MarketHours(symbols As String, Optional ddate As String = "") As Object Dim xmlHttp As Object Dim url As String Dim token As String Dim params As String token = "Bearer " & accessToken ' Ensure accessToken is set appropriately url = baseURL & "/marketdata/v1/markets" params = "?markets=" & symbols If Date <> "" Then params = params & "&date=" & ddate End If Set xmlHttp = CreateObject("MSXML2.XMLHTTP") xmlHttp.Open "GET", url & params, False xmlHttp.setRequestHeader "Authorization", token xmlHttp.setRequestHeader "Content-Type", "application/x-www-form-urlencoded" xmlHttp.send Set MarketHours = JsonConverter.ParseJson(xmlHttp.responseText) Set xmlHttp = Nothing End Function Public Function MarketHour(market_id As String, Optional ddate As String = "") As Object Dim xmlHttp As Object Dim url As String Dim token As String Dim params As String token = "Bearer " & accessToken ' Ensure accessToken is set appropriately url = baseURL & "/marketdata/v1/markets/" & market_id If Date <> "" Then params = "?date=" & ddate End If Set xmlHttp = CreateObject("MSXML2.XMLHTTP") xmlHttp.Open "GET", url & params, False xmlHttp.setRequestHeader "Authorization", token xmlHttp.setRequestHeader "Content-Type", "application/x-www-form-urlencoded" xmlHttp.send Set MarketHour = JsonConverter.ParseJson(xmlHttp.responseText) Set xmlHttp = Nothing End Function Public Function Instruments(symbol As String, projection As String) As Object Dim xmlHttp As Object Dim url As String Dim token As String Dim params As String token = "Bearer " & accessToken ' Ensure accessToken is set appropriately url = baseURL & "/marketdata/v1/instruments" params = "?symbol=" & symbol & "&projection=" & projection Set xmlHttp = CreateObject("MSXML2.XMLHTTP") xmlHttp.Open "GET", url & params, False xmlHttp.setRequestHeader "Authorization", token xmlHttp.setRequestHeader "Content-Type", "application/x-www-form-urlencoded" xmlHttp.send Set Instruments = JsonConverter.ParseJson(xmlHttp.responseText) Set xmlHttp = Nothing End Function Public Function InstrumentCusip(cusip_id As String) As Object Dim xmlHttp As Object Dim url As String Dim token As String token = "Bearer " & accessToken ' Ensure accessToken is set appropriately url = baseURL & "/marketdata/v1/instruments/" & cusip_id Set xmlHttp = CreateObject("MSXML2.XMLHTTP") xmlHttp.Open "GET", url, False xmlHttp.setRequestHeader "Authorization", token xmlHttp.setRequestHeader "Content-Type", "application/x-www-form-urlencoded" xmlHttp.send Set InstrumentCusip = JsonConverter.ParseJson(xmlHttp.responseText) Set xmlHttp = Nothing End Function