nas08-scripts/Stocks/WebService/libreoffice_macro.txt

521 lines
10 KiB
Text
Raw Normal View History

2026-07-27 20:31:33 -04:00
' =========================================================================
'
2026-07-27 20:31:33 -04:00
' StockFunctions.bas
2026-07-27 20:35:27 -04:00
' Collabora / LibreOffice Basic
2026-07-27 20:31:33 -04:00
'
' FUNDTIME returns Yahoo's latest market update date/time
' converted from UTC to U.S. Eastern Time.
'
' Example:
'
' stockproxy UTC:
' 2026-07-27 19:58:00
'
' FUNDTIME:
' 2026-07-27 15:58:00
'
' Eastern Time automatically observes:
2026-07-27 20:31:33 -04:00
'
' EDT = UTC-4
' EST = UTC-5
'
2026-07-27 20:31:33 -04:00
' =========================================================================
2026-07-27 20:31:33 -04:00
Option Explicit
2026-07-27 20:31:33 -04:00
' ---- Config -------------------------------------------------------------
Function PROXY_BASE() As String
2026-07-27 20:35:27 -04:00
PROXY_BASE = "https://stocks.kingdezigns.com"
2026-07-27 20:31:33 -04:00
End Function
2026-07-27 20:31:33 -04:00
Function PROXY_SECRET() As String
2026-07-27 20:35:27 -04:00
PROXY_SECRET = "90c2528e9b5221c110f7c2c9cd6c65dc"
2026-07-27 20:31:33 -04:00
End Function
2026-07-27 20:35:27 -04:00
' ---- Public spreadsheet functions --------------------------------------
2026-07-27 20:31:33 -04:00
Function FUNDPRICE(ticker As String) As Variant
2026-07-27 20:35:27 -04:00
Dim sUrl As String
Dim sJson As String
Dim vPrice As Variant
2026-07-27 20:35:27 -04:00
sUrl = PROXY_BASE() & "/current?ticker=" & EncodeUrl(ticker) & _
"&key=" & PROXY_SECRET()
2026-07-27 20:35:27 -04:00
sJson = HttpGetText(sUrl)
2026-07-27 20:35:27 -04:00
If sJson = "" Then
FUNDPRICE = "#ERROR"
Exit Function
End If
2026-07-27 20:35:27 -04:00
vPrice = JsonNumber(sJson, "price")
2026-07-27 20:35:27 -04:00
If IsNull(vPrice) Then
FUNDPRICE = "#N/A"
Else
FUNDPRICE = vPrice
End If
2026-07-27 20:31:33 -04:00
End Function
2026-07-27 20:35:27 -04:00
Function FUNDPRICE_HIST(ticker As String, dateStr As String) As Variant
2026-07-27 20:35:27 -04:00
Dim sUrl As String
Dim sJson As String
Dim vPrice As Variant
2026-07-27 20:35:27 -04:00
sUrl = PROXY_BASE() & "/historical?ticker=" & EncodeUrl(ticker) & _
"&date=" & EncodeUrl(dateStr) & _
"&key=" & PROXY_SECRET()
2026-07-27 20:35:27 -04:00
sJson = HttpGetText(sUrl)
2026-07-27 20:35:27 -04:00
If sJson = "" Then
FUNDPRICE_HIST = "#ERROR"
Exit Function
End If
2026-07-27 20:35:27 -04:00
vPrice = JsonNumber(sJson, "price")
2026-07-27 20:35:27 -04:00
If IsNull(vPrice) Then
FUNDPRICE_HIST = "#N/A"
Else
FUNDPRICE_HIST = vPrice
End If
2026-07-27 20:31:33 -04:00
End Function
2026-07-27 20:35:27 -04:00
' ---- Yahoo market update date/time --------------------------------------
'
' stockproxy supplies the Yahoo timestamp in UTC.
'
' FUNDTIME converts that UTC timestamp to U.S. Eastern Time.
'
' During daylight saving time:
'
' EDT = UTC - 4 hours
'
' During standard time:
'
' EST = UTC - 5 hours
'
' Example:
'
' UTC:
' 2026-07-27 19:58:00
'
' Eastern:
' 2026-07-27 15:58:00
2026-07-27 20:35:27 -04:00
'
Function FUNDTIME(ticker As String) As String
2026-07-27 20:35:27 -04:00
Dim sUrl As String
Dim sJson As String
Dim sDate As String
Dim sTime As String
Dim iYear As Integer
Dim iMonth As Integer
Dim iDay As Integer
Dim iHour As Integer
Dim iMinute As Integer
Dim iSecond As Integer
Dim dUTC As Date
Dim dMarch As Date
Dim dNovember As Date
Dim dDSTStart As Date
Dim dDSTEnd As Date
Dim iMarchSunday As Integer
Dim iNovemberSunday As Integer
Dim iOffset As Integer
' ---------------------------------------------------------------
' Get current stock data from stockproxy
' ---------------------------------------------------------------
2026-07-27 20:35:27 -04:00
sUrl = PROXY_BASE() & "/current?ticker=" & EncodeUrl(ticker) & _
"&key=" & PROXY_SECRET()
2026-07-27 20:35:27 -04:00
sJson = HttpGetText(sUrl)
2026-07-27 20:35:27 -04:00
If sJson = "" Then
FUNDTIME = "#ERROR"
Exit Function
End If
' ---------------------------------------------------------------
' Get UTC date and time from JSON
' ---------------------------------------------------------------
2026-07-27 20:35:27 -04:00
sDate = JsonString(sJson, "date")
sTime = JsonString(sJson, "time")
2026-07-27 20:35:27 -04:00
If sDate = "" Or sTime = "" Then
FUNDTIME = "#N/A"
Exit Function
End If
' ---------------------------------------------------------------
' Parse date
'
' Expected:
' YYYY-MM-DD
' ---------------------------------------------------------------
iYear = CInt(Left(sDate, 4))
iMonth = CInt(Mid(sDate, 6, 2))
iDay = CInt(Right(sDate, 2))
' ---------------------------------------------------------------
' Parse time
'
' Expected:
' HH:MM:SS
' ---------------------------------------------------------------
iHour = CInt(Left(sTime, 2))
iMinute = CInt(Mid(sTime, 4, 2))
iSecond = CInt(Right(sTime, 2))
' ---------------------------------------------------------------
' Create UTC date/time
' ---------------------------------------------------------------
dUTC = DateSerial(iYear, iMonth, iDay)
dUTC = dUTC + TimeSerial(iHour, iMinute, iSecond)
' ---------------------------------------------------------------
' Find second Sunday in March
' ---------------------------------------------------------------
dMarch = DateSerial(iYear, 3, 8)
iMarchSunday = 8 - WeekDay(dMarch)
If iMarchSunday < 0 Then
iMarchSunday = iMarchSunday + 7
End If
dDSTStart = dMarch + iMarchSunday
' 2:00 AM EST = 07:00 UTC
dDSTStart = dDSTStart + TimeSerial(7, 0, 0)
' ---------------------------------------------------------------
' Find first Sunday in November
' ---------------------------------------------------------------
dNovember = DateSerial(iYear, 11, 1)
iNovemberSunday = 8 - WeekDay(dNovember)
If iNovemberSunday < 0 Then
iNovemberSunday = iNovemberSunday + 7
End If
dDSTEnd = dNovember + iNovemberSunday
' 2:00 AM EDT = 06:00 UTC
dDSTEnd = dDSTEnd + TimeSerial(6, 0, 0)
' ---------------------------------------------------------------
' Determine Eastern Time offset
' ---------------------------------------------------------------
If dUTC >= dDSTStart And dUTC < dDSTEnd Then
' Eastern Daylight Time
iOffset = 4
Else
' Eastern Standard Time
iOffset = 5
End If
' ---------------------------------------------------------------
' Convert UTC to Eastern Time
' ---------------------------------------------------------------
dUTC = dUTC - TimeSerial(iOffset, 0, 0)
' ---------------------------------------------------------------
' Return:
'
' YYYY-MM-DD HH:MM:SS
' ---------------------------------------------------------------
FUNDTIME = Format(dUTC, "YYYY-MM-DD HH:MM:SS")
2026-07-27 20:31:33 -04:00
End Function
2026-07-27 20:35:27 -04:00
' ---- Internal helpers ---------------------------------------------------
2026-07-27 20:31:33 -04:00
' Synchronous HTTP GET, returns response body as text, "" on failure.
2026-07-27 20:31:33 -04:00
Function HttpGetText(sUrl As String) As String
2026-07-27 20:35:27 -04:00
Dim oSFA As Object
Dim oStream As Object
Dim oTextStream As Object
Dim sResult As String
2026-07-27 20:35:27 -04:00
On Error GoTo ErrHandler
2026-07-27 20:35:27 -04:00
oSFA = createUnoService("com.sun.star.ucb.SimpleFileAccess")
oStream = oSFA.openFileRead(sUrl)
2026-07-27 20:35:27 -04:00
oTextStream = createUnoService("com.sun.star.io.TextInputStream")
oTextStream.setInputStream(oStream)
oTextStream.setEncoding("UTF-8")
2026-07-27 20:35:27 -04:00
sResult = ""
2026-07-27 20:35:27 -04:00
Do While Not oTextStream.isEOF()
2026-07-27 20:35:27 -04:00
sResult = sResult & oTextStream.readLine() & Chr(10)
2026-07-27 20:35:27 -04:00
Loop
2026-07-27 20:35:27 -04:00
oTextStream.closeInput()
2026-07-27 20:35:27 -04:00
HttpGetText = sResult
2026-07-27 20:35:27 -04:00
Exit Function
2026-07-27 20:31:33 -04:00
2026-07-27 20:31:33 -04:00
ErrHandler:
2026-07-27 20:35:27 -04:00
HttpGetText = ""
2026-07-27 20:31:33 -04:00
End Function
2026-07-27 20:35:27 -04:00
2026-07-27 20:31:33 -04:00
' Pulls a numeric value out of a flat JSON string for a given key.
2026-07-27 20:31:33 -04:00
Function JsonNumber(sJson As String, sKey As String) As Variant
2026-07-27 20:35:27 -04:00
Dim iPos As Integer
Dim iStart As Integer
Dim iEnd As Integer
Dim sNum As String
Dim cChar As String
2026-07-27 20:31:33 -04:00
2026-07-27 20:35:27 -04:00
iPos = InStr(sJson, Chr(34) & sKey & Chr(34))
2026-07-27 20:31:33 -04:00
2026-07-27 20:35:27 -04:00
If iPos = 0 Then
2026-07-27 20:35:27 -04:00
JsonNumber = Null
Exit Function
2026-07-27 20:35:27 -04:00
End If
2026-07-27 20:35:27 -04:00
iPos = InStr(iPos, sJson, ":")
2026-07-27 20:35:27 -04:00
If iPos = 0 Then
2026-07-27 20:35:27 -04:00
JsonNumber = Null
Exit Function
2026-07-27 20:35:27 -04:00
End If
2026-07-27 20:35:27 -04:00
iStart = iPos + 1
Do While iStart <= Len(sJson) And _
Mid(sJson, iStart, 1) = " "
2026-07-27 20:35:27 -04:00
iStart = iStart + 1
2026-07-27 20:35:27 -04:00
Loop
2026-07-27 20:35:27 -04:00
iEnd = iStart
2026-07-27 20:35:27 -04:00
Do While iEnd <= Len(sJson)
2026-07-27 20:35:27 -04:00
cChar = Mid(sJson, iEnd, 1)
2026-07-27 20:35:27 -04:00
If (cChar >= "0" And cChar <= "9") Or _
cChar = "." Or cChar = "-" Then
2026-07-27 20:35:27 -04:00
iEnd = iEnd + 1
2026-07-27 20:35:27 -04:00
Else
2026-07-27 20:35:27 -04:00
Exit Do
2026-07-27 20:35:27 -04:00
End If
2026-07-27 20:35:27 -04:00
Loop
2026-07-27 20:31:33 -04:00
2026-07-27 20:35:27 -04:00
sNum = Mid(sJson, iStart, iEnd - iStart)
2026-07-27 20:35:27 -04:00
If Len(sNum) = 0 Then
2026-07-27 20:35:27 -04:00
JsonNumber = Null
2026-07-27 20:31:33 -04:00
Else
2026-07-27 20:35:27 -04:00
JsonNumber = CDbl(sNum)
2026-07-27 20:31:33 -04:00
End If
2026-07-27 20:35:27 -04:00
End Function
2026-07-27 20:35:27 -04:00
' Pulls a quoted string value out of a flat JSON string.
2026-07-27 20:35:27 -04:00
Function JsonString(sJson As String, sKey As String) As String
2026-07-27 20:35:27 -04:00
Dim iPos As Integer
Dim iColon As Integer
Dim iQuoteStart As Integer
Dim iQuoteEnd As Integer
2026-07-27 20:35:27 -04:00
iPos = InStr(sJson, Chr(34) & sKey & Chr(34))
2026-07-27 20:31:33 -04:00
2026-07-27 20:35:27 -04:00
If iPos = 0 Then
2026-07-27 20:35:27 -04:00
JsonString = ""
Exit Function
2026-07-27 20:35:27 -04:00
End If
2026-07-27 20:31:33 -04:00
2026-07-27 20:35:27 -04:00
iColon = InStr(iPos, sJson, ":")
2026-07-27 20:31:33 -04:00
2026-07-27 20:35:27 -04:00
If iColon = 0 Then
2026-07-27 20:35:27 -04:00
JsonString = ""
Exit Function
2026-07-27 20:35:27 -04:00
End If
2026-07-27 20:35:27 -04:00
iQuoteStart = InStr(iColon, sJson, Chr(34))
2026-07-27 20:35:27 -04:00
If iQuoteStart = 0 Then
2026-07-27 20:35:27 -04:00
JsonString = ""
Exit Function
2026-07-27 20:35:27 -04:00
End If
2026-07-27 20:35:27 -04:00
iQuoteEnd = InStr(iQuoteStart + 1, sJson, Chr(34))
2026-07-27 20:35:27 -04:00
If iQuoteEnd = 0 Then
2026-07-27 20:35:27 -04:00
JsonString = ""
Exit Function
2026-07-27 20:35:27 -04:00
End If
2026-07-27 20:31:33 -04:00
2026-07-27 20:35:27 -04:00
JsonString = Mid(sJson, iQuoteStart + 1, _
iQuoteEnd - iQuoteStart - 1)
2026-07-27 20:31:33 -04:00
End Function
2026-07-27 20:35:27 -04:00
' Minimal percent-encoder.
2026-07-27 20:35:27 -04:00
Function EncodeUrl(s As String) As String
2026-07-27 20:35:27 -04:00
Dim i As Integer
Dim c As String
Dim sOut As String
2026-07-27 20:35:27 -04:00
sOut = ""
2026-07-27 20:35:27 -04:00
For i = 1 To Len(s)
2026-07-27 20:35:27 -04:00
c = Mid(s, i, 1)
2026-07-27 20:35:27 -04:00
If (c >= "A" And c <= "Z") Or _
(c >= "a" And c <= "z") Or _
(c >= "0" And c <= "9") Or _
c = "-" Or c = "_" Or c = "." Or c = "~" Then
2026-07-27 20:35:27 -04:00
sOut = sOut & c
2026-07-27 20:35:27 -04:00
Else
sOut = sOut & "%" & _
Right("0" & Hex(Asc(c)), 2)
2026-07-27 20:35:27 -04:00
End If
2026-07-27 20:35:27 -04:00
Next i
2026-07-27 20:35:27 -04:00
EncodeUrl = sOut
2026-07-27 20:31:33 -04:00
End Function
2026-07-27 20:35:27 -04:00
' ---- Snapshot ------------------------------------------------------------
2026-07-27 20:31:33 -04:00
2026-07-27 20:35:27 -04:00
Sub RefreshPriceSnapshot
2026-07-27 20:35:27 -04:00
Dim oDoc As Object
Dim oSheet As Object
Dim i As Integer
2026-07-27 20:35:27 -04:00
oDoc = ThisComponent
oSheet = oDoc.Sheets.getByIndex(0)
2026-07-27 20:35:27 -04:00
' Copy P3:Q53 -> R3:S53 as values only
2026-07-27 20:35:27 -04:00
For i = 2 To 4
2026-07-27 20:35:27 -04:00
oSheet.getCellByPosition(17, i).setValue( _
oSheet.getCellByPosition(15, i).getValue())
2026-07-27 20:35:27 -04:00
oSheet.getCellByPosition(18, i).setValue( _
oSheet.getCellByPosition(16, i).getValue())
2026-07-27 20:31:33 -04:00
2026-07-27 20:35:27 -04:00
Next i
2026-07-27 20:35:27 -04:00
MsgBox "Price snapshot refreshed."
2026-07-27 20:35:27 -04:00
End Sub