Skip to content
laclancePublic

About

Deterministic, no-lookahead support/resistance detection for Go trading systems, backtests and live strategies.

Topics

Resources

Contributing

Security policy

Stars

3 stars

Watchers

0 watching

Forks

Latest commit

 

History

111 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

go-sr

CI Go Reference License: Apache-2.0

Deterministic, no-lookahead support/resistance detection for Go trading systems.

go-sr is a focused Go module for support/resistance detection that is designed for backtests and live systems where reproducibility and no-lookahead behavior matter.

  • Deterministic results for the same candle prefix and options
  • Closed-candle inputs and confirmation-based zone pivots
  • Legacy line-based and ATR-aware zone modes
  • Nearest support/resistance metadata for strategy logic
  • Multi-timeframe candle aggregation and sizing helpers
  • No third-party runtime dependencies
  • CI with race detection, static analysis, a high statement-coverage floor, and fuzz smoke tests

Example

BTC 5m support/resistance zones detected by go-sr

Zone-mode output generated from the repository's BTC 5m fixture. The preview shows detected support/resistance structure, qualified zones, and nearest levels.

Install

go get github.com/laclance/go-sr@latest
import sr "github.com/laclance/go-sr"

Quick Start

levels, err := sr.Compute(candles, sr.Options{
    Timeframe:   "5m",
    Lookback:    120,
    Mode:        sr.ModeZones,
    MinStrength: 2,
})
if err != nil {
    return err
}

fmt.Printf("support=%.2f resistance=%.2f\n",
    levels.NearestSupport,
    levels.NearestResistance,
)

candles is a slice of closed OHLCV candles:

[]sr.Candle{
    {
        OpenTime:  openTime,
        CloseTime: closeTime,
        Open:      100.0,
        High:      103.0,
        Low:       99.0,
        Close:     102.0,
        Volume:    1250,
    },
}

The result includes the detected levels plus strategy-friendly nearest-level metadata:

levels.Levels
levels.NearestSupport
levels.NearestResistance
levels.NearestSupportDistance
levels.NearestResistanceDistance
levels.NearestSupportStrength
levels.NearestResistanceStrength
levels.NearestSupportScore
levels.NearestResistanceScore
levels.NearSupport
levels.NearResistance

Standalone Example

examples/basic is a self-contained runnable program. It generates deterministic closed 5m candles, runs zone mode, and prints the detected level count plus nearest support and resistance.

From a clean directory, copy and run:

git clone --depth=1 https://github.com/laclance/go-sr.git
cd go-sr
go run ./examples/basic

The example imports only the Go standard library plus github.com/laclance/go-sr; it does not depend on repository test helpers. You can also copy examples/basic/main.go into another Go module unchanged, then replace demoCandles with candles from your exchange, broker, backtest fixture, or market-data pipeline.

Integrations

  • BBGO closed-kline adapter shows how to map BBGO types.KLine events into a bounded slice of closed sr.Candle values without adding BBGO to this module.

Why go-sr?

Many trading implementations accidentally make support/resistance look better in backtests by allowing future candles to influence historical pivots. go-sr is built around prefix-stable, confirmation-based behavior so the same candle history produces the same result whether it is processed in a backtest or a live strategy.

That makes it a good fit when you need S/R as a dependable input rather than a chart-only visual indicator.

Modes

Zone mode

levels, err := sr.Compute(candles, sr.Options{
    Timeframe:   "5m",
    Lookback:    120,
    Mode:        sr.ModeZones,
    MinStrength: 2,
})

Zone mode clusters confirmed swing pivots into support/resistance zones. MinStrength filters qualified zones; values <= 0 use the default of 2.

Legacy mode

levels, err := sr.Compute(candles, sr.Options{
    Timeframe: "5m",
    Lookback:  120,
    Mode:      sr.ModeLegacy,
    Tolerance: 0.002,
})

Legacy mode provides line-based S/R behavior. Tolerance applies only to legacy mode; values <= 0 use the default 0.002.

Multi-Timeframe Support

Aggregate lower-timeframe candles before computing higher-timeframe S/R:

candles15m := sr.AggregateCandlesToTimeframe(candles5m, "5m", "15m")

levels15m, err := sr.Compute(candles15m, sr.Options{
    Timeframe: "15m",
    Lookback:  50,
    Mode:      sr.ModeZones,
})

Helpers are also available for calculating warmup and exchange-fetch requirements for a finite lookback:

warmup := sr.WarmupCandles(50, sr.ModeZones)
limit := sr.RequiredKlineLimit("5m", "1h", 50, sr.ModeZones)

WarmupCandles and RequiredKlineLimit return 0 when lookback <= 0 because an all-supplied-history calculation has no finite warmup/fetch size. For bounded lookbacks, RequiredKlineLimit includes enough slack for fixed-duration UTC target buckets anchored at 1970-01-01T00:00:00Z, plus one potentially live final candle. Exclude that still-open candle before calling AggregateCandlesToTimeframe or Compute; both APIs expect closed candles.

Core API

type Mode string

const (
    ModeLegacy Mode = "legacy"
    ModeZones  Mode = "zone"
)

type Options struct {
    Timeframe   string
    Lookback    int
    Mode        Mode
    Tolerance   float64
    MinStrength int
}

func Compute(candles []Candle, opts Options) (Levels, error)
func EmptyLevels(timeframe string) Levels
func AggregateCandlesToTimeframe(candles []Candle, fromInterval, toInterval string) []Candle
func WarmupCandles(lookback int, mode Mode) int
func RequiredKlineLimit(baseInterval, targetInterval string, lookback int, mode Mode) int

See the standalone program in examples/basic, runnable package examples in examples_test.go, and the generated API documentation on pkg.go.dev.

Behavioral Contract

  • Compute is deterministic for the same candle prefix and options.
  • The zero value of Options.Mode selects ModeLegacy.
  • Options.Lookback <= 0 uses all supplied candle history in both modes.
  • Unknown modes cause Compute to return EmptyLevels(opts.Timeframe) plus an error.
  • WarmupCandles and RequiredKlineLimit require a positive, bounded lookback and return 0 when a finite size cannot be provided, including for non-positive lookbacks and existing invalid-input cases.
  • Zone-mode pivots are confirmation-based; no future candles are read beyond the current prefix.
  • AggregateCandlesToTimeframe uses fixed-duration UTC buckets anchored at 1970-01-01T00:00:00Z. Only complete contiguous target buckets are emitted; partial or gapped buckets are dropped.
  • For positive lookbacks, RequiredKlineLimit includes enough raw candles to preserve the higher-timeframe warmup after alignment to that bucket grid, plus one potentially live candle for exchange REST responses.
  • Callers must exclude still-open candles before passing data to AggregateCandlesToTimeframe or Compute.
  • Supported interval strings use <n><unit> with m, h, or d; the target interval must be larger than and evenly divisible by the base interval.
  • NearSupport / NearResistance describe whether the nearest level on each side is within the mode-specific near threshold.
  • In zone mode, the near threshold is 2 × the zone half-width; zero-width zones fall back to 0.1% of the absolute current price.
  • In legacy mode, the near threshold is Tolerance × |close|.

Scope

This module owns:

  • Closed-candle S/R detection
  • Legacy line-based and zone-based S/R modes
  • Deterministic nearest support/resistance metadata
  • S/R-specific multi-timeframe aggregation, warmup sizing, and fetch sizing

This module intentionally does not own:

  • Exchange or Binance parsing
  • Strategy scoring or trade evaluation
  • App-specific timeframe policy
  • Order execution

Keeping exchange and strategy concerns outside the package makes go-sr usable across backtest engines, bots, and brokers.

Manual Chart Inspection

The repository includes a BTC fixture and an HTML chart generator for visually inspecting detected zones:

GO_SR_CHART=/tmp/go-sr-btc-5m.html \
  go test -run TestGenerateManualSRChart -count=1 -v

xdg-open /tmp/go-sr-btc-5m.html

Optional overrides:

GO_SR_CHART_TIMEFRAME=15m
GO_SR_CHART_MODE=legacy
GO_SR_CHART_LOOKBACK=80
GO_SR_CHART_WINDOW=300
GO_SR_CHART_MIN_STRENGTH=1

Quality Gate

CI runs on pull requests and pushes to main.

Required status checks on main are:

  • Minimum Go Compatibility — runs the test suite on the minimum Go version declared by go.mod
  • Current Go Quality Gate — runs gofmt, tests, race detection, go vet, Staticcheck, golangci-lint, the statement-coverage floor, and fuzz smoke tests
  • API Compatibility — rejects backward-incompatible exported Go API changes against the latest stable release

Additional non-required CI checks are:

  • Root Vulnerability Scan — runs govulncheck on the root module with current stable Go
  • BBGO Example Compatibility — verifies the root module remains BBGO-free and compiles the isolated BBGO adapter module

Contributing

Issues and pull requests are welcome. See CONTRIBUTING.md before making a change, and use SECURITY.md for security reports.

If you are using go-sr in a project, opening a discussion or issue with your use case is also useful feedback for the API.

License

Apache-2.0. See LICENSE.

About

Deterministic, no-lookahead support/resistance detection for Go trading systems, backtests and live strategies.

Topics

Resources

Contributing

Security policy

Stars

3 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages