From b3ad421c762b2e5c3130758bed070fdae981895f Mon Sep 17 00:00:00 2001 From: Alek Kim Date: Tue, 28 Jul 2026 12:25:24 +0900 Subject: [PATCH] feat(loader): make Load idempotent and expose TA-Lib version API - guard library initialization with sync.Once to avoid duplicate registrations - refactor loading logic into internalLoad() - register TA_GetVersionString and expose Version() - document Version() usage and API behavior in README --- README.md | 5 ++++- loader.go | 26 ++++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 6cd34a1..3b8c205 100644 --- a/README.md +++ b/README.md @@ -48,7 +48,7 @@ This package does **not** bundle TA-Lib itself. You must install the native libr ## How library loading works -Call `talib.Load()` once before using any indicator function. The loader looks for the platform-specific library name: +Call `talib.Load()` once before using any indicator function. After loading, you can call `talib.Version()` to read the native TA-Lib version string. The loader looks for the platform-specific library name: - macOS: `libta-lib.dylib` - Linux: `libta-lib.so` @@ -103,6 +103,8 @@ func main() { log.Fatal(err) } + fmt.Println("TA-Lib version:", talib.Version()) + var series []float64 for i := 0; i < 100; i++ { series = append(series, math.Sin(float64(i)/7)*4.5+math.Cos(float64(i)/19)*1.75) @@ -122,6 +124,7 @@ func main() { ## API notes - Indicator functions return `nil` when the underlying TA-Lib call fails. +- `Version()` returns the TA-Lib version string exposed by `TA_GetVersionString` (call after `Load()`). - Native TA-Lib functions are exposed with Go-style exported names such as `Add`, `Div`, `Max`, and `Sum`. - Functions accepting a moving-average type use the `MAType` constant (`MA_SMA`, `MA_EMA`, `MA_WMA`, `MA_DEMA`, `MA_TEMA`, `MA_TRIMA`, `MA_KAMA`, `MA_MAMA`, `MA_T3`). - Functions returning multiple outputs (e.g. `Aroon`, `MACD`, `Stoch`) return multiple slices; all are `nil` on failure. diff --git a/loader.go b/loader.go index ce66ef5..ccf8d7e 100644 --- a/loader.go +++ b/loader.go @@ -1,16 +1,40 @@ package talib +import "C" import ( "fmt" "log/slog" "os" "path/filepath" "runtime" + "sync" "github.com/ebitengine/purego" ) +var ( + internalVersion func() string + once sync.Once +) + +func Version() string { + return internalVersion() +} + func Load() (uintptr, error) { + var ( + ptr uintptr + err error + ) + + once.Do(func() { + ptr, err = internalLoad() + }) + + return ptr, err +} + +func internalLoad() (uintptr, error) { var ( path string ptr uintptr @@ -26,6 +50,8 @@ func Load() (uintptr, error) { return 0, err } + purego.RegisterLibFunc(&internalVersion, ptr, "TA_GetVersionString") + // Register the functions we need from the TA-Lib library purego.RegisterLibFunc(&ht_dcperiod, ptr, "TA_HT_DCPERIOD") purego.RegisterLibFunc(&ht_dcphase, ptr, "TA_HT_DCPHASE")