### Python State-Caching Mode Example Source: https://github.com/banbox/banta/blob/main/readme.md Shows how to use BanTA's state-caching mode in Python. It initializes a BarEnv, simulates pushing candle data, and calculates indicators like SMA, retrieving their latest values. ```python from bbta import ta # 1. Create an environment # BarEnv manages state; create one for each time frame/trading pair. env = ta.BarEnv(TimeFrame="1m") # 2. Prepare candle data # (timestamp ms, open, high, low, close, volume) klines = [ (1672531200000, 100, 102, 99, 101, 1000), (1672531260000, 101, 103, 100, 102, 1200), (1672531320000, 102, 105, 101, 104, 1500), (1672531380000, 104, 105, 103, 103, 1300), (1672531440000, 103, 104, 102, 103, 1100), (1672531500000, 103, 106, 103, 105, 1600), (1672531560000, 105, 107, 104, 106, 1800), (1672531620000, 106, 106, 102, 103, 2000), (1672531680000, 103, 104, 101, 102, 1700), (1672531740000, 102, 103, 100, 101, 1400), ] # 3. Simulate candle pushes # In live trading, call OnBar for each new candle. for kline in klines: ts, o, h, l, c, v = kline env.OnBar(ts, o, h, l, c, v, 0, 0, 0) # 4. Calculate indicators ma5 = ta.Series(ta.SMA(env.Close, 5)) ma30 = ta.Series(ta.SMA(env.Close, 30)) # Get the latest value ma5_val = ma5.Get(0) ma30_val = ma30.Get(0) print(f"Close={c:.2f}, MA5={ma5_val:.2f}, MA30={ma30_val:.2f}") ``` -------------------------------- ### Go Parallel Computation Mode Example Source: https://github.com/banbox/banta/blob/main/readme.md Illustrates using BanTA's parallel computation mode in Go for bulk indicator calculations, suitable for research purposes. It takes slices of price data and computes indicators like SMA, ATR, and Cross. ```go import ( "github.com/banbox/banta/tav" ) func main(){ highArr := []float64{1.01, 1.01, 1.02, 0.996, 0.98, 0.993, 0.99, 1.0, 1.02} lowArr := []float64{0.99, 1.0, 1.0, 0.98, 0.965, 0.98, 0.98, 0.984, 1.0} closeArr := []float64{1.0, 1.01, 1.0, 0.99, 0.97, 0.981, 0.988, 0.992, 1.002} sma := tav.SMA(closeArr, 5) ma30 := tav.SMA(closeArr, 30) atr := tav.ATR(highArr, lowArr, closeArr, 14) xArr := tav.Cross(ma5, ma30) } ``` -------------------------------- ### View Indicator Results Source: https://github.com/banbox/banta/blob/main/readme.md Display the computed indicator values. Convert the `go.Slice` results back to Python lists for easy viewing and formatting. This example shows the last 5 values. ```go print(f"Close: {list(close)[-5:]}") print(f"MA5: {[f'{x:.2f}' for x in list(ma5)[-5:]]}") print(f"ATR: {[f'{x:.2f}' for x in list(atr)[-5:]]}") ``` -------------------------------- ### Series.Range Source: https://context7.com/banbox/banta/llms.txt Returns a `[]float64` of length `stop - start` in **newest-first** order, covering offsets `[start, stop)`. ```APIDOC ## Series.Range — Read a slice of recent values ### Description Returns a `[]float64` of length `stop - start` in **newest-first** order, covering offsets `[start, stop)`. ### Usage ```go // Get the last 5 closing prices, newest first recent5 := e.Close.Range(0, 5) // e.g. [104.5, 103.2, 105.0, 102.8, 101.0] ``` ``` -------------------------------- ### Calculate Average True Range (ATR) and Stop Loss Source: https://context7.com/banbox/banta/llms.txt Computes the Average True Range over a specified period. An example is provided to calculate a stop-loss level by subtracting 1.5 times the ATR from the current closing price. ```go atr14 := ta.ATR(e.High, e.Low, e.Close, 14) stopLoss := e.Close.Get(0) - atr14.Get(0)*1.5 fmt.Printf("ATR=%.4f StopLoss=%.4f\n", atr14.Get(0), stopLoss) ``` -------------------------------- ### Read slice of recent values with Series.Range in Go Source: https://context7.com/banbox/banta/llms.txt Returns a `[]float64` of length `stop - start` in **newest-first** order, covering offsets `[start, stop)`. Useful for accessing multiple recent data points efficiently. ```go // Get the last 5 closing prices, newest first recent5 := e.Close.Range(0, 5) // e.g. [104.5, 103.2, 105.0, 102.8, 101.0] ``` -------------------------------- ### Calculate Arnaud Legoux Moving Average (ALMA) Source: https://context7.com/banbox/banta/llms.txt Computes the Arnaud Legoux Moving Average, a Gaussian-weighted MA with offset and sigma parameters. Example parameters: period=10, sigma=6, distOffset=0.85. ```go // period=10, sigma=6, distOffset=0.85 alma := ta.ALMA(e.Close, 10, 6.0, 0.85) fmt.Printf("ALMA(10,6,0.85) = %.4f\n", alma.Get(0)) ``` -------------------------------- ### Python: 使用带状态缓存的事件驱动 K 线处理 Source: https://github.com/banbox/banta/blob/main/readme.cn.md 在 Python 中使用 `bbta.ta.BarEnv` 来管理状态并处理 K 线数据。每次收到新 K 线时调用 `OnBar` 方法,然后计算指标。适用于实时交易和事件驱动回测。 ```python from bbta import ta # 1. 创建环境 # BarEnv 用于管理状态,在每个时间周期/交易对上创建一个即可 env = ta.BarEnv(TimeFrame="1m") # 2. 准备K线数据 # (时间戳ms, 开, 高, 低, 收, 交易量) klines = [ (1672531200000, 100, 102, 99, 101, 1000), (1672531260000, 101, 103, 100, 102, 1200), (1672531320000, 102, 105, 101, 104, 1500), (1672531380000, 104, 105, 103, 1300), (1672531440000, 103, 104, 102, 103, 1100), (1672531500000, 103, 106, 103, 105, 1600), (1672531560000, 105, 107, 104, 106, 1800), (1672531620000, 106, 106, 102, 103, 2000), (1672531680000, 103, 104, 101, 102, 1700), (1672531740000, 102, 103, 100, 101, 1400), ] # 3. 模拟K线推送 # 在实盘中,每收到一根新K线就调用一次 OnBar for kline in klines: ts, o, h, l, c, v = kline env.OnBar(ts, o, h, l, c, v, 0, 0, 0) # 4. 计算指标 ma5 = ta.Series(ta.SMA(env.Close, 5)) ma30 = ta.Series(ta.SMA(env.Close, 30)) # 获取最新值 ma5_val = ma5.Get(0) ma30_val = ma30.Get(0) print(f"Close={c:.2f}, MA5={ma5_val:.2f}, MA30={ma30_val:.2f}") ``` -------------------------------- ### Python: 使用并行计算一次性计算多个指标 Source: https://github.com/banbox/banta/blob/main/readme.cn.md 在 Python 中使用 `bbta.tav` 和 `bbta.go` 模块进行并行计算。适用于一次性计算大量历史 K 线数据的研究场景,将 Python list 转换为 `go.Slice_float64` 类型进行计算。 ```python from bbta import tav, go # 1. 准备数据 # 并行计算模式的函数接收 go.Slice_float64 类型 # 我们可以从python list创建 high_py = [102.0, 103.0, 105.0, 105.0, 104.0, 106.0, 107.0, 106.0, 104.0, 103.0] low_py = [99.0, 100.0, 101.0, 103.0, 102.0, 103.0, 104.0, 102.0, 101.0, 100.0] close_py = [101.0, 102.0, 104.0, 103.0, 103.0, 105.0, 106.0, 103.0, 102.0, 101.0] high = go.Slice_float64(high_py) low = go.Slice_float64(low_py) close = go.Slice_float64(close_py) # 2. 一次性计算所有指标 # 返回结果也是 go.Slice 类型 ma5 = tav.SMA(close, 5) atr = tav.ATR(high, low, close, 14) # 3. 查看结果 # 可以转为python list查看 print(f"Close: {list(close)[-5:]}") print(f"MA5: {[f'{x:.2f}' for x in list(ma5)[-5:]]}") print(f"ATR: {[f'{x:.2f}' for x in list(atr)[-5:]]}") # 对于多返回值指标,比如KDJ kdj_result = tav.KDJ(high, low, close, 9, 3, 3) k_line = kdj_result[0] d_line = kdj_result[1] j_line = kdj_result[2] print(f"K-line: {[f'{x:.2f}' for x in list(k_line)[-5:]]}") ``` -------------------------------- ### Snapshot and Restore Environment State using BarEnv.Clone and BarEnv.ResetTo Source: https://context7.com/banbox/banta/llms.txt Saves the current state of the trading environment, including derived series, using `Clone`. `ResetTo` restores the environment to a previously saved snapshot, useful for replaying scenarios. ```go snapshot := env.Clone() // save state at candle N // ... simulate forward env.ResetTo(snapshot) // roll back all cached indicators ``` -------------------------------- ### Create a named BarEnv in Go Source: https://context7.com/banbox/banta/llms.txt Constructs a `*BarEnv` with exchange, market, symbol, and timeframe metadata. Parses the timeframe string into millisecond intervals and pre-allocates internal state. Ensure the import path is correct. ```go import ta "github.com/banbox/banta" env, err := ta.NewBarEnv("binance", "spot", "BTC/USDT", "1h") if err != nil { panic(err) } // env.TFMSecs == 3600000 (1 hour in ms) // env.MaxCache == 1500 (default) ``` -------------------------------- ### Go: 使用并行计算一次性计算多个指标 Source: https://github.com/banbox/banta/blob/main/readme.cn.md 在 Go 中使用 BanTA 的 tav 包进行并行计算。适用于一次性计算大量历史 K 线数据的研究场景,可以快速获取多个指标的计算结果。 ```go import ( "github.com/banbox/banta/tav" ) func main(){ highArr := []float64{1.01, 1.01, 1.02, 0.996, 0.98, 0.993, 0.99, 1.0, 1.02} lowArr := []float64{0.99, 1.0, 1.0, 0.98, 0.965, 0.98, 0.98, 0.984, 1.0} closeArr := []float64{1.0, 1.01, 1.0, 0.99, 0.97, 0.981, 0.988, 0.992, 1.002} sma := tav.SMA(closeArr, 5) ma30 := tav.SMA(closeArr, 30) atr := tav.ATR(highArr, lowArr, closeArr, 14) xArr := tav.Cross(ma5, ma30) } ``` -------------------------------- ### Go: 使用带状态缓存的事件驱动 K 线处理 Source: https://github.com/banbox/banta/blob/main/readme.cn.md 在 Go 中使用 BanTA 的 BarEnv 来处理实时 K 线数据。每次收到新 K 线时,BarEnv 会更新其内部状态并重新计算指标,避免了重复计算历史数据,适用于实盘交易和事件驱动回测。 ```go import ( "fmt" ta "github.com/banbox/banta" ) var envMap = make(map[string]*ta.BarEnv) func OnBar(symbol string, timeframe string, bar *ta.Kline) { envKey := fmt.Sprintf("%s_%s", symbol, timeframe) e, ok := envMap[envKey] if !ok { e = &ta.BarEnv{ TimeFrame: timeframe, BarNum: 1, } envMap[envKey] = e } e.OnBar(bar.Time, bar.Open, bar.High, bar.Low, bar.Close, bar.Volume, bar.Quote, bar.BuyVolume, bar.TradeNum) ma5 := ta.SMA(e.Close, 5) ma30 := ta.SMA(e.Close, 30) atr := ta.ATR(e.High, e.Low, e.Close, 14).Get(0) xnum := ta.Cross(ma5, ma30) if xnum == 1 { // ma5 cross up ma30 curPrice := e.Close.Get(0) // or bar.Close stopLoss := curPrice - atr fmt.Printf("open long at %f, stoploss: %f", curPrice, stopLoss) } else if xnum == -1 { // ma5 cross down ma30 curPrice := e.Close.Get(0) fmt.Printf("close long at %f", curPrice) } kdjRes := ta.KDJ(e.High, e.Low, e.Close, 9, 3, 3).Cols k, d := kdjRes[0], kdjRes[1] } ``` -------------------------------- ### Python: 安装 BanTA 库 Source: https://github.com/banbox/banta/blob/main/readme.cn.md 使用 pip 安装 BanTA Python 包。请注意版本和操作系统的兼容性要求。 ```shell pip install bbta ``` -------------------------------- ### NewBarEnv Source: https://context7.com/banbox/banta/llms.txt Constructs a *BarEnv with exchange, market, symbol, and timeframe metadata. Parses the timeframe string (e.g. "1m", "4h", "1d") into millisecond intervals and pre-allocates internal state. ```APIDOC ## NewBarEnv — Create a named BarEnv ### Description Constructs a `*BarEnv` with exchange, market, symbol, and timeframe metadata. Parses the timeframe string (e.g. `"1m"`, `"4h"`, `"1d"`) into millisecond intervals and pre-allocates internal state. ### Usage ```go import ta "github.com/banbox/banta" env, err := ta.NewBarEnv("binance", "spot", "BTC/USDT", "1h") if err != nil { panic(err) } // env.TFMSecs == 3600000 (1 hour in ms) // env.MaxCache == 1500 (default) ``` ``` -------------------------------- ### Price Transforms (AvgPrice, HL2, HLC3) Source: https://context7.com/banbox/banta/llms.txt Provides common price transformations: Average Price ((H+L+C)/3), HL2 ((H+L)/2), and HLC3 ((H+L+C)/3). ```go tp := ta.AvgPrice(e) // (H+L+C)/3 hl2 := ta.HL2(e.High, e.Low) // (H+L)/2 hlc3 := ta.HLC3(e.High, e.Low, e.Close) // (H+L+C)/3 ``` -------------------------------- ### BarEnv.Clone / BarEnv.ResetTo Source: https://context7.com/banbox/banta/llms.txt Allows for snapshotting and restoring the state of a BarEnv, including all derived Series. Useful for backtesting alternate scenarios. ```APIDOC ## BarEnv.Clone / BarEnv.ResetTo ### Description `Clone` produces a deep copy of the environment, including all derived Series. `ResetTo` resets the current environment's derived Series to mirror a previously cloned snapshot, preserving OHLCV data. Used in backtesting to replay alternate scenarios from a checkpoint. ### Usage `env.Clone()` `env.ResetTo(snapshot)` ### Example ```go snapshot := env.Clone() // save state at candle N // ... simulate forward env.ResetTo(snapshot) // roll back all cached indicators ``` ``` -------------------------------- ### Compute Core Parallel Indicators with tav package Source: https://context7.com/banbox/banta/llms.txt Calculates various technical indicators in parallel using the tav package, which operates on []float64 slices. Ideal for batch processing and research. Ensure the tav package is imported. ```go import "github.com/banbox/banta/tav" high := []float64{101, 103, 105, 104, 106, 107, 106, 104, 103} low := []float64{ 99, 100, 101, 102, 103, 104, 102, 101, 100} close := []float64{100, 102, 104, 103, 105, 106, 103, 102, 101} vol := []float64{1000, 1200, 1500, 1300, 1600, 1800, 2000, 1700, 1400} sma5 := tav.SMA(close, 5) ema12 := tav.EMA(close, 12) rma14 := tav.RMA(close, 14) wma9 := tav.WMA(close, 9) hma9 := tav.HMA(close, 9) kama10 := tav.KAMA(close, 10) alma := tav.ALMA(close, 10, 6.0, 0.85) atr14 := tav.ATR(high, low, close, 14) rsi14 := tav.RSI(close, 14) macd, sig := tav.MACD(close, 12, 26, 9) cci20 := tav.CCI(close, 20) willr := tav.WillR(high, low, close, 14) cmf20 := tav.CMF(high, low, close, vol, 20) mfi14 := tav.MFI(high, low, close, vol, 14) adx14 := tav.ADX(high, low, close, 14) chop14 := tav.CHOP(high, low, close, 14) crsi := tav.CRSI(close, 3, 2, 100) stc := tav.STC(close, 12, 26, 50, 0.5) // Multi-output indicators k, d, rsv := tav.KDJ(high, low, close, 9, 3, 3) up, osc, dn := tav.Aroon(high, low, 25) bbUp, bbMid, bbLow := tav.BBANDS(close, 20, 2.0, 2.0) fastK, fastD := tav.StochRSI(close, 14, 14, 3, 3) plusDI, minusDI := tav.PluMinDI(high, low, close, 14) haO, haH, haL, haC := tav.HeikinAshi( []float64{99,101,103,102}, []float64{102,104,106,105}, []float64{98,100,101,100}, []float64{101,103,104,103}) // Cross signals (returns []int) crossArr := tav.Cross(sma5, ema12) // crossArr[i] > 0 means sma5 crossed above ema12 at or before bar i fmt.Printf("Last SMA5=%.4f RSI=%.2f ADX=%.2f BB(upper)=%.4f\n", sma5[len(sma5)-1], rsi14[len(rsi14)-1], adx14[len(adx14)-1], bbUp[len(bbUp)-1]) fmt.Printf("KDJ K=%.2f D=%.2f Aroon up=%.1f osc=%.1f dn=%.1f\n", k[len(k)-1], d[len(d)-1], up[len(up)-1], osc[len(osc)-1], dn[len(dn)-1]) ``` -------------------------------- ### Incremental Chanlun Analysis with CGraph in Go Source: https://context7.com/banbox/banta/llms.txt Feed candles one by one and call `Parse()` to detect Chanlun structures like pens, segments, and pivots in real time. Register callbacks to react to new or updated structures. ```go import ta "github.com/banbox/banta" graph := &ta.CGraph{ ParseLevel: ta.ParseLevelCentre, // parse up to pivot/centre level MaxPen: 1000, OnPen: func(p *ta.CPen, evt int) { switch evt { case ta.EvtNew: fmt.Printf("New pen: dir=%.0f %s\n", p.Dirt, p.String()) case ta.EvtChange: fmt.Printf("Pen updated: %s\n", p.String()) case ta.EvtRemove: fmt.Printf("Pen removed\n") } }, OnSeg: func(s *ta.CSeg, evt int) { if evt == ta.EvtNew { fmt.Printf("New segment: dir=%.0f %s\n", s.Dirt, s.String()) } }, } // Simulate candle feed env := &ta.BarEnv{TimeFrame: "1d", BarNum: 1} // Query detected structures fmt.Printf("Pens: %d Segments: %d Pivots: %d\n", len(graph.Pens), len(graph.Segs), len(graph.Centres)) // Export draw lines (segments + pivot overlap lines) for _, dl := range graph.Dump() { fmt.Printf("Line: pos %d→%d price %.4f→%.4f\n", dl.StartPos, dl.StopPos, dl.StartPrice, dl.StopPrice) } ``` ```go bars := []ta.Kline{ {Time: 1672531200000, Open: 100, High: 105, Low: 98, Close: 103, Volume: 1000}, {Time: 1672617600000, Open: 103, High: 108, Low: 101, Close: 107, Volume: 1200}, {Time: 1672704000000, Open: 107, High: 109, Low: 104, Close: 105, Volume: 900}, // ... more bars } for _, bar := range bars { env.OnBar(bar.Time, bar.Open, bar.High, bar.Low, bar.Close, bar.Volume, 0, 0, 0) graph.AddBar(env) graph.Parse() } ``` -------------------------------- ### Feed a single candle into state with BarEnv.OnBar in Go Source: https://context7.com/banbox/banta/llms.txt Appends one OHLCV bar to internal Series and advances the candle counter. Must be called chronologically; returns an error for out-of-order bars. This is the primary entry point for live/event-driven use. Indicators become available after calling `OnBar`. ```go import ( "fmt" ta "github.com/banbox/banta" ) var envMap = make(map[string]*ta.BarEnv) func OnBar(symbol, timeframe string, bar *ta.Kline) { key := symbol + "_" + timeframe e, ok := envMap[key] if !ok { e = &ta.BarEnv{TimeFrame: timeframe, BarNum: 1} envMap[key] = e } err := e.OnBar(bar.Time, bar.Open, bar.High, bar.Low, bar.Close, bar.Volume, bar.Quote, bar.BuyVolume, bar.TradeNum) if err != nil { fmt.Println("stale bar:", err) return } // All indicators are now available for this candle ma5 := ta.SMA(e.Close, 5) ma20 := ta.SMA(e.Close, 20) fmt.Printf("Close=%.4f MA5=%.4f MA20=%.4f\n", e.Close.Get(0), ma5.Get(0), ma20.Get(0)) } ``` -------------------------------- ### Calculate Statistical Helpers with Sum/StdDev/AvgDev/PercentRank Source: https://context7.com/banbox/banta/llms.txt Computes statistical measures like sum, standard deviation, average deviation, and percentile rank for a given data series over a specified period. Useful for understanding data distribution and volatility. ```go sum20 := ta.Sum(e.Close, 20) std20 := ta.StdDev(e.Close, 20) avgDev := ta.AvgDev(e.Close, 20) pctRank := ta.PercentRank(e.Close, 100) fmt.Printf("Sum=%.2f Std=%.4f AvgDev=%.4f PctRank=%.1f ", sum20.Get(0), std20.Get(0), avgDev.Get(0), pctRank.Get(0)) ``` -------------------------------- ### Calculate Stiffness Indicator Source: https://context7.com/banbox/banta/llms.txt Calculates the Stiffness indicator, which measures the percentage of closes above a smoothed band. Requires close prices, stiffness length, band percentage, and smoothing period. ```go stiff := ta.Stiffness(e.Close, 100, 60, 3) fmt.Printf("Stiffness = %.2f\n", stiff.Get(0)) ``` -------------------------------- ### Calculate UT Bot Alerts (UTBot) Source: https://context7.com/banbox/banta/llms.txt Calculates UT Bot signals, an ATR-based trailing stop. It emits +1 for buy signals, -1 for sell signals, and 0 for no signal. ```go atr := ta.ATR(e.High, e.Low, e.Close, 14) signal := ta.UTBot(e.Close, atr, 1.0) // rate=1.0 v := signal.Get(0) if v == 1 { fmt.Println("UTBot BUY signal") } else if v == -1 { fmt.Println("UTBot SELL signal") } ``` -------------------------------- ### Calculate Momentum using Series.Back Source: https://context7.com/banbox/banta/llms.txt Computes the one-bar momentum of a series by subtracting the previous bar's value from the current bar's value. Requires the `Back` method to access past values. ```go prev := e.Close.Back(1) momentum := e.Close.Sub(prev) fmt.Printf("1-bar momentum: %.4f\n", momentum.Get(0)) ``` -------------------------------- ### Stoch Source: https://context7.com/banbox/banta/llms.txt Calculates the raw Stochastic %K oscillator. ```APIDOC ## Stoch — Stochastic %K (raw RSV) ### Description Calculates the raw stochastic oscillator using the formula: `100 × (close − lowest) / (highest − lowest)`. ### Usage `ta.Stoch(highSeries Series, lowSeries Series, closeSeries Series, period int) *Series` ### Example ```go stoch14 := ta.Stoch(e.High, e.Low, e.Close, 14) fmt.Printf("Stoch(14) = %.2f\n", stoch14.Get(0)) ``` ``` -------------------------------- ### State-caching Mode in Python with bbta Source: https://context7.com/banbox/banta/llms.txt Utilize the `bbta` Python package for technical analysis. This mode processes bars sequentially and computes indicators in a state-caching manner. Ensure Python version is 3.8 or higher. ```python from bbta import ta env = ta.BarEnv(TimeFrame="1h") klines = [ (1672531200000, 100, 105, 98, 103, 1000), (1672534800000, 103, 108, 101, 107, 1200), (1672538400000, 107, 110, 104, 106, 1500), (1672542000000, 106, 107, 102, 104, 900), (1672545600000, 104, 109, 103, 108, 1100), (1672549200000, 108, 112, 106, 111, 1800), (1672552800000, 111, 113, 108, 109, 1600), (1672556400000, 109, 110, 105, 106, 2000), (1672560000000, 106, 108, 103, 107, 1400), (1672563600000, 107, 111, 105, 110, 1700), ] for ts, o, h, l, c, vol in klines: env.OnBar(ts, o, h, l, c, vol, 0, 0, 0) ma5 = ta.Series(ta.SMA(env.Close, 5)) ma10 = ta.Series(ta.SMA(env.Close, 10)) rsi = ta.Series(ta.RSI(env.Close, 14)) atr = ta.Series(ta.ATR(env.High, env.Low, env.Close, 14)) print(f"Close={c} MA5={ma5.Get(0):.4f} " f"MA10={ma10.Get(0):.4f} RSI={rsi.Get(0):.2f} ATR={atr.Get(0):.4f}") ``` -------------------------------- ### Series arithmetic helpers in Go Source: https://context7.com/banbox/banta/llms.txt Each method (`Add`, `Sub`, `Mul`, `Div`, `Min`, `Max`, `Abs`) returns a new cached `*Series` that applies the operation element-wise against a constant or another `*Series`. Results are cached per candle; subsequent calls in the same bar return the cached value instantly. ```go // Compute mid-band manually and derive ±2 stddev channels atr := ta.ATR(e.High, e.Low, e.Close, 14) atr2 := atr.Mul(2.0) // *Series ATR × 2 upper := e.Close.Add(atr2) // *Series close + 2×ATR lower := e.Close.Sub(atr2) // *Series close − 2×ATR fmt.Printf("Keltner: upper=%.4f lower=%.4f\n", upper.Get(0), lower.Get(0)) ``` -------------------------------- ### Calculate Linear Regression (LinReg) and Advanced (LinRegAdv) Source: https://context7.com/banbox/banta/llms.txt Calculates the linear regression value at the current bar (LinReg) or exposes advanced metrics like slope, intercept, angle, and correlation coefficient (LinRegAdv). ```go linreg := ta.LinReg(e.Close, 14) // regression line value slope := ta.LinRegAdv(e.Close, 14, false, false, false, false, true, false) fmt.Printf("LinReg=%.4f Slope=%.6f\n", linreg.Get(0), slope.Get(0)) ``` -------------------------------- ### Core Parallel Indicators (tav package) Source: https://context7.com/banbox/banta/llms.txt Computes various technical indicators in parallel, returning slices of float64 for each bar. ```APIDOC ## Core Parallel Indicators ### Description Computes various technical indicators in parallel, returning slices of float64 for each bar. These are ideal for research, backtesting data preparation, and one-shot batch analysis. ### Functions - `SMA(source []float64, period int) []float64`: Simple Moving Average. - `EMA(source []float64, period int) []float64`: Exponential Moving Average. - `RMA(source []float64, period int) []float64`: Running Moving Average. - `WMA(source []float64, period int) []float64`: Weighted Moving Average. - `HMA(source []float64, period int) []float64`: Hull Moving Average. - `KAMA(source []float64, period int) []float64`: Kaufman's Adaptive Moving Average. - `ALMA(source []float64, period int, offset float64, sigma float64) []float64`: Arnaud Legoux Moving Average. - `ATR(high, low, close []float64, period int) []float64`: Average True Range. - `RSI(source []float64, period int) []float64`: Relative Strength Index. - `MACD(source []float64, fastPeriod, slowPeriod, signalPeriod int) ([]float64, []float64)`: Moving Average Convergence Divergence. - `CCI(source []float64, period int) []float64`: Commodity Channel Index. - `WillR(high, low, close []float64, period int) []float64`: Williams' %R. - `CMF(high, low, close, volume []float64, period int) []float64`: Chande Momentum Oscillator. - `MFI(high, low, close, volume []float64, period int) []float64`: Money Flow Index. - `ADX(high, low, close []float64, period int) []float64`: Average Directional Movement Index. - `CHOP(high, low, close []float64, period int) []float64`: Choppiness Index. - `CRSI(source []float64, shortPeriod, longPeriod, n int) []float64`: Commodity Relative Strength Index. - `STC(source []float64, fastPeriod, slowPeriod, n float64, factor float64) []float64`: Stochastic Cycle Oscillator. - `KDJ(high, low, close []float64, kPeriod, dPeriod, n int) ([]float64, []float64, []float64)`: KDJ Oscillator. - `Aroon(high, low []float64, period int) ([]float64, []float64, []float64)`: Aroon Indicator. - `BBANDS(source []float64, period int, stdDev1, stdDev2 float64) ([]float64, []float64, []float64)`: Bollinger Bands. - `StochRSI(source []float64, rsiPeriod, kPeriod, dPeriod, n int) ([]float64, []float64)`: Stochastic RSI. - `PluMinDI(high, low, close []float64, period int) ([]float64, []float64)`: Plus Directional Indicator and Minus Directional Indicator. - `HeikinAshi(open, high, low, close []float64) ([]float64, []float64, []float64, []float64)`: Heikin Ashi candles. - `Cross(source1, source2 []float64) []int`: Detects crossovers between two series. ### Example ```go import "github.com/banbox/banta/tav" high := []float64{101, 103, 105, 104, 106, 107, 106, 104, 103} low := []float64{ 99, 100, 101, 102, 103, 104, 102, 101, 100} close := []float64{100, 102, 104, 103, 105, 106, 103, 102, 101} vol := []float64{1000, 1200, 1500, 1300, 1600, 1800, 2000, 1700, 1400} sma5 := tav.SMA(close, 5) ... fmt.Printf("Last SMA5=%.4f RSI=%.2f ADX=%.2f BB(upper)=%.4f\n", sma5[len(sma5)-1], rsi14[len(rsi14)-1], adx14[len(adx14)-1], bbUp[len(bbUp)-1]) ``` ``` -------------------------------- ### BarEnv.OnBar Source: https://context7.com/banbox/banta/llms.txt Appends one OHLCV bar to all internal Series and advances the candle counter. Must be called in chronological order; returns an error for out-of-order bars. This is the primary entry point for live/event-driven use. ```APIDOC ## BarEnv.OnBar — Feed a single candle into state ### Description Appends one OHLCV bar to all internal Series and advances the candle counter. Must be called in chronological order; returns an error for out-of-order bars. This is the primary entry point for live/event-driven use. ### Usage ```go import ( "fmt" ta "github.com/banbox/banta" ) var envMap = make(map[string]*ta.BarEnv) func OnBar(symbol, timeframe string, bar *ta.Kline) { key := symbol + "_" + timeframe e, ok := envMap[key] if !ok { e = &ta.BarEnv{TimeFrame: timeframe, BarNum: 1} envMap[key] = e } err := e.OnBar(bar.Time, bar.Open, bar.High, bar.Low, bar.Close, bar.Volume, bar.Quote, bar.BuyVolume, bar.TradeNum) if err != nil { fmt.Println("stale bar:", err) return } // All indicators are now available for this candle ma5 := ta.SMA(e.Close, 5) ma20 := ta.SMA(e.Close, 20) fmt.Printf("Close=%.4f MA5=%.4f MA20=%.4f\n", e.Close.Get(0), ma5.Get(0), ma20.Get(0)) } ``` ``` -------------------------------- ### Statistical Helpers Source: https://context7.com/banbox/banta/llms.txt Provides functions for calculating sum, standard deviation, average deviation, and percentile rank. ```APIDOC ## Statistical Helpers ### Description Provides functions for calculating sum, standard deviation, average deviation, and percentile rank. ### Functions - `Sum(source []float64, period int) []float64`: Calculates the sum of values over a specified period. - `StdDev(source []float64, period int) []float64`: Calculates the standard deviation of values over a specified period. - `AvgDev(source []float64, period int) []float64`: Calculates the average deviation of values over a specified period. - `PercentRank(source []float64, period int) []float64`: Calculates the percentile rank of values over a specified period. ### Example ```go sum20 := ta.Sum(e.Close, 20) std20 := ta.StdDev(e.Close, 20) avgDev := ta.AvgDev(e.Close, 20) pctRank := ta.PercentRank(e.Close, 100) fmt.Printf("Sum=%.2f Std=%.4f AvgDev=%.4f PctRank=%.1f", sum20.Get(0), std20.Get(0), avgDev.Get(0), pctRank.Get(0)) ``` ``` -------------------------------- ### Calculate Choppiness Index (CHOP) Source: https://context7.com/banbox/banta/llms.txt Calculates the CHOP, which identifies market conditions. Values above 61.8 suggest choppy markets, while values below 38.2 suggest strong trends. ```go chop14 := ta.CHOP(e, 14) fmt.Printf("CHOP(14) = %.2f\n", chop14.Get(0)) ``` -------------------------------- ### Calculate Relative Momentum Index (RMI) Source: https://context7.com/banbox/banta/llms.txt Calculates the RMI, a variant of RSI that compares current price to the price 'montLen' bars ago. Requires period and momentum length. ```go rmi := ta.RMI(e.Close, 14, 3) fmt.Printf("RMI(14,3) = %.2f\n", rmi.Get(0)) ``` -------------------------------- ### Calculate Simple Moving Average (SMA) Source: https://context7.com/banbox/banta/llms.txt Computes the Simple Moving Average of a given series over a specified period. The `OnBar` method must be called to update the environment before calculating. ```go e.OnBar(ts, o, h, l, c, vol, 0, 0, 0) ma20 := ta.SMA(e.Close, 20) fmt.Printf("SMA(20) = %.4f\n", ma20.Get(0)) ``` -------------------------------- ### Calculate Kaufman Adaptive Moving Average (KAMA) Source: https://context7.com/banbox/banta/llms.txt Computes the Kaufman Adaptive Moving Average, which adapts its smoothing constant based on the Efficiency Ratio. It is faster in trending markets and slower in ranging markets. The default parameters are period=10, fast=2, slow=30. ```go kama10 := ta.KAMA(e.Close, 10) // period=10, fast=2, slow=30 fmt.Printf("KAMA(10) = %.4f\n", kama10.Get(0)) ``` -------------------------------- ### BBANDS Source: https://context7.com/banbox/banta/llms.txt Calculates Bollinger Bands, returning the upper, middle, and lower bands. ```APIDOC ## BBANDS — Bollinger Bands ### Description Calculates Bollinger Bands, returning the upper, middle, and lower bands. It also allows for calculation of the bandwidth. ### Usage `ta.BBANDS(series Series, period int, stdDev1 float64, stdDev2 float64) (*Series, *Series, *Series)` ### Example ```go upper, mid, lower := ta.BBANDS(e.Close, 20, 2.0, 2.0) bw := upper.Sub(lower) // bandwidth fmt.Printf("BB upper=%.4f mid=%.4f lower=%.4f bw=%.4f\n", upper.Get(0), mid.Get(0), lower.Get(0), bw.Get(0)) ``` ``` -------------------------------- ### Compute KDJ Indicator and Extract Lines Source: https://github.com/banbox/banta/blob/main/readme.md Calculate the KDJ indicator, which returns three lines: K, D, and J. Access each line from the returned slice and format for display. ```go kdj_result = tav.KDJ(high, low, close, 9, 3, 3) k_line = kdj_result[0] d_line = kdj_result[1] j_line = kdj_result[2] print(f"K-line: {[f'{x:.2f}' for x in list(k_line)[-5:]]}") ``` -------------------------------- ### Calculate Commodity Channel Index (CCI) Source: https://context7.com/banbox/banta/llms.txt Computes the Commodity Channel Index using the typical price and average deviation over a specified period. A suggested period is 20. ```go typicalPrice := ta.AvgPrice(e) // (H+L+C)/3 cci20 := ta.CCI(typicalPrice, 20) fmt.Printf("CCI(20) = %.2f\n", cci20.Get(0)) ``` -------------------------------- ### Calculate Rate of Change (ROC) Source: https://context7.com/banbox/banta/llms.txt Calculates the percentage change in price over a specified number of bars. Useful for identifying momentum. ```go roc9 := ta.ROC(e.Close, 9) fmt.Printf("ROC(9) = %.2f%%\n", roc9.Get(0)) ``` -------------------------------- ### Parse Time Frame String to Seconds Source: https://context7.com/banbox/banta/llms.txt Converts human-readable timeframe strings (e.g., "1m", "4h", "1d") into their equivalent total seconds. Handles various units like minutes, hours, days, weeks, months, and years. Returns an error for invalid formats. ```go import ta "github.com/banbox/banta" secs, err := ta.ParseTimeFrame("4h") // secs == 14400, err == nil secs, err = ta.ParseTimeFrame("1d") // secs == 86400 _, err = ta.ParseTimeFrame("5x") // err != nil (unknown unit) ```