How to Access the Underlying Data Array in a BanTA Series
To access the underlying data array in a BanTA Series, use the exported accessor methods Get(), Range(), or RangeValid() defined in core.go, as the raw Data slice is unexported for encapsulation.
The banbox/banta library provides a Series type for handling time-series financial data in algorithmic trading applications. While the raw numeric values are stored internally in a private slice, the library exposes several safe methods to read this data. Understanding how to access the underlying data array in a BanTA Series is essential for building custom indicators or analyzing price history without breaking the library's encapsulation.
Understanding the Series Data Structure
In types.go, the Series struct defines an unexported field Data []float64 that stores the actual numeric values. Because this field is lowercase (private), external packages cannot access it directly. This design prevents accidental modification of the internal state while allowing the library to maintain data integrity and handle memory management internally.
Accessor Methods for Reading Series Data
The core.go file implements three primary methods for reading the underlying data without breaking encapsulation. These functions operate on the private Data slice internally while providing safe, read-only access to external callers.
Get(): Retrieve a Single Value
The Get(i int) float64 method returns the i-th most recent value, where index 0 represents the latest bar. This is the fastest way to access a single data point when you only need the current or a specific historical value by position.
Range(): Extract a Window of Values
The Range(start, stop int) []float64 method returns a slice containing values from start (most recent) up to but not including stop. The returned slice is ordered from newest to oldest, making it ideal for calculations requiring a sliding window of recent bars.
RangeValid(): Filter Out NaN Values
The RangeValid(start, stop int) ([]float64, []int) method functions like Range() but excludes NaN (Not a Number) values. It returns two slices: the valid values and their corresponding original indices. Use this when your calculations require only defined data points and cannot handle missing values, such as when calculating averages on sparse data.
Modifying Series Data
While the question focuses on reading data, the Append(obj interface{}) method in core.go allows you to add new values to the series. This accepts either a single float64 or a slice of values, enabling dynamic updates to the underlying array when processing live market feeds.
Practical Code Examples
The following examples demonstrate how to access the underlying data array in real trading scenarios using the banta package API.
Accessing the Last 10 Bars
// Assume env is a *banta.BarEnv that has been populated with market data.
last10 := env.Close.Range(0, 10) // Returns newest → oldest
fmt.Println("Close prices of the last 10 bars:", last10)
Retrieving the Latest Value
// Get the most recent close price using index 0.
latestClose := env.Close.Get(0)
fmt.Printf("Latest close: %.2f\n", latestClose)
Handling Missing Data
// Get valid volume data for the last 20 bars, skipping NaN entries.
vals, idxs := env.Volume.RangeValid(0, 20)
for i, v := range vals {
fmt.Printf("Bar %d (original index %d) volume: %.2f\n",
i, idxs[i], v)
}
Package-Internal Access
If you are contributing to the banta repository or writing code inside the package directory, Go permits direct access to the unexported Data field. The internal indicators in sta_inds.go demonstrate this pattern, accessing s.Data directly for performance-critical calculations that require tight loops over the raw array. However, external code must always use the public API methods described above to maintain proper encapsulation.
Summary
- The underlying data array in a BanTA Series is stored in the unexported
Data []float64field defined intypes.go. - External packages must use
Get(),Range(), orRangeValid()fromcore.goto access values safely. RangeValid()automatically filters outNaNvalues and returns the corresponding original indices for reference.- Package-internal code can access
Datadirectly when necessary, as demonstrated insta_inds.go.
Frequently Asked Questions
Can I access the Data field directly from my application?
No. The Data field is unexported (lowercase), meaning only code within the banta package can reference it. Your application must use the exported accessor methods like Get() and Range() to read values safely from outside the package.
What is the difference between Range() and RangeValid()?
Range() returns all values in the specified window including any NaN entries, preserving the exact index positions. RangeValid() filters out NaN values and returns a second slice containing the original indices, which is useful when you need to know where valid data exists within the full series timeline.
How do I get the most recent value in a Series?
Call Get(0) on your Series object. Index 0 always represents the latest (most recent) bar in the series, with higher indices representing progressively older data points ordered from newest to oldest.
Is there a performance difference between these methods?
Get() provides the fastest access for single-value lookups as it performs a direct index calculation on the underlying slice. Range() involves creating a new slice copy, while RangeValid() incurs additional overhead due to the logic required to filter NaN values and construct the index mapping array.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →