Download Latest Version ta4j-core-0.22.3-javadoc.jar (4.0 MB)
Email in envelope

Get an email when there's a new version of ta4j

Home / 0.22.0
Name Modified Size InfoDownloads / Week
Parent folder
ta4j-core-0.22.0-javadoc.jar 2026-01-06 2.8 MB
ta4j-core-0.22.0-sources.jar 2026-01-06 804.0 kB
ta4j-core-0.22.0-tests.jar 2026-01-06 1.6 MB
ta4j-core-0.22.0.jar 2026-01-06 767.2 kB
ta4j-examples-0.22.0-javadoc.jar 2026-01-06 762.9 kB
ta4j-examples-0.22.0-sources.jar 2026-01-06 1.2 MB
ta4j-examples-0.22.0.jar 2026-01-06 1.3 MB
0.22.0 source code.tar.gz 2025-12-29 3.3 MB
0.22.0 source code.zip 2025-12-29 4.5 MB
README.md 2025-12-29 18.8 kB
Totals: 10 Items   17.1 MB 0

0.22.0 (2025-12-29)

Breaking Changes

  • CachedIndicator and RecursiveCachedIndicator synchronization changes: CachedIndicator and RecursiveCachedIndicator no longer use synchronized methods. Thread safety is now achieved through internal locking using ReentrantReadWriteLock. Action required: Code that relied on external synchronization using indicator instances (e.g., synchronized(indicator) { ... }) must be updated to use explicit external locks.
  • SqueezeProIndicator return type change: SqueezeProIndicator return type changed from Boolean to Num. Use getSqueezeLevel(int) or isInSqueeze(int) for compression state instead of direct boolean checks.

Added

  • Added GitHub Actions workflow linting (actionlint) to catch workflow expression and shell syntax errors early.
  • Num.isValid() utility method: Added static Num.isValid(Num) method as the logical complement of Num.isNaNOrNull(), providing a convenient way to check if a value is non-null and represents a real number. Used extensively throughout the Elliott Wave indicators package for robust NaN handling.
  • SqueezeProIndicator correction: Corrected SqueezeProIndicator to mirror TradingView/LazyBear squeeze momentum output: SMA-based Bollinger vs. Keltner compression tiers (high/mid/low), SMA true range width (not Wilder ATR), and the LazyBear detrended-price momentum baseline used by linreg (with regression tests on AAPL/NEE 2025-12-05).
  • SuperTrend indicator usability improvements: Enhanced the SuperTrend indicator suite with intuitive helper methods and comprehensive documentation for traders:

    • Added isUpTrend(int), isDownTrend(int), and trendChanged(int) methods to SuperTrendIndicator for easy trend detection and signal generation without manual band comparisons
    • Comprehensive Javadoc with formulas, trading signals, usage examples, and references to authoritative sources (Investopedia, TradingView)
    • Added package-info.java documentation for the supertrend package
    • Expanded unit test coverage with trend reversal scenarios, serialization roundtrip tests, and ratcheting behavior verification
  • Trendline and swing point analysis suite: Added a comprehensive set of indicators for automated trendline drawing and swing point detection. These indicators solve the common problem of manually identifying support/resistance levels and drawing trendlines by automating the process while maintaining the same logic traders use when drawing lines manually. Useful for breakout strategies, trend-following systems, and Elliott Wave analysis.

    • Automated trendline indicators: TrendLineSupportIndicator and TrendLineResistanceIndicator project support and resistance lines by connecting confirmed swing points. The indicators select the best trendline from a configurable lookback window using a scoring system based on swing point touches, proximity to current price, and recency. Historical values are automatically backfilled so trendlines stay straight and anchored on actual pivot points (not confirmation bars), avoiding the visual artifacts common in other implementations. Works with any price indicator (high/low/open/close/VWAP) and handles plateau detection, NaN values, and irregular time gaps—trendlines remain straight even across weekends and holidays. Supports both dynamic recalculation (updates on each bar) and static mode (freeze the first established line and project forward).
    • ZigZag pattern detection: Added ZigZag indicator suite (ZigZagStateIndicator, ZigZagPivotHighIndicator, ZigZagPivotLowIndicator, RecentZigZagSwingHighIndicator, RecentZigZagSwingLowIndicator) that filters out insignificant price movements to reveal underlying trend structure. Unlike window-based swing indicators that require fixed lookback periods, ZigZag adapts dynamically using percentage or absolute price thresholds, making it particularly useful in volatile markets where fixed windows can miss significant moves. Pivot signals fire immediately when reversals are confirmed (no confirmation bar delay), and you can track support/resistance levels dynamically for mean-reversion strategies. Supports both fixed thresholds (e.g., 2% price movement) and dynamic thresholds based on indicators like ATR for volatility-adaptive detection.
    • Fractal-based swing detection: RecentFractalSwingHighIndicator and RecentFractalSwingLowIndicator implement Bill Williams' fractal approach, identifying swing points by requiring a specified number of surrounding bars to be strictly higher or lower. Includes plateau-aware logic to handle flat tops and bottoms, making it robust for real-world market data. Good choice if you prefer the classic fractal methodology or need consistent swing detection across different market conditions.
    • Unified swing infrastructure: All swing indicators share a common foundation (AbstractRecentSwingIndicator base class and RecentSwingIndicator interface) that provides consistent caching, automatic purging of stale swing points, and a unified API for accessing swing point indexes and values. Makes it straightforward to build custom swing detection algorithms or integrate with trendline tools—implement the interface and you get caching and lifecycle management automatically.
    • Swing point visualization: SwingPointMarkerIndicator highlights confirmed swing points on charts without drawing connecting lines, useful for visualizing where pivots occur. Works with any swing detection algorithm (fractal-based, ZigZag, or custom implementations).
  • Unified data source interface for seamless market data loading: Finally, a consistent way to load market data regardless of where it comes from! The new BarSeriesDataSource interface lets you work with trading domain concepts (ticker, interval, date range) instead of wrestling with file paths, API endpoints, or parsing logic. Want to switch from CSV files to Yahoo Finance API? Just swap the data source implementation—your strategy code stays exactly the same. Implementations include:

  • YahooFinanceBarSeriesDataSource: Fetch live data from Yahoo Finance (stocks, ETFs, crypto) with optional response caching to speed up development and avoid API rate limits
  • CoinbaseBarSeriesDataSource: Load historical crypto data from Coinbase's public API with automatic caching
  • CsvFileBarSeriesDataSource: Load OHLCV data from CSV files with intelligent filename pattern matching (e.g., AAPL-PT1D-20230102_20231231.csv)
  • JsonFileBarSeriesDataSource: Load Coinbase/Binance-style JSON bar data with flexible date filtering
  • BitStampCsvTradesFileBarSeriesDataSource: Aggregate Bitstamp trade-level CSV data into bars on-the-fly

All data sources support the same domain-driven API: loadSeries(ticker, interval, start, end). No more remembering whether your CSV uses _bars_from_ or -PT1D- in the filename, or which API endpoint returns what format. The interface handles the implementation details so you can focus on building strategies. File-based sources automatically search for matching files, while API-based sources fetch and cache data transparently. See the new CoinbaseBacktest and YahooFinanceBacktest examples for complete workflows.

  • Elliott Wave analysis package: Added a comprehensive suite of indicators for Elliott Wave analysis, enabling automated wave counting, pattern recognition, and confidence scoring. The package handles the inherent ambiguity in Elliott Wave analysis by generating multiple plausible wave interpretations with confidence percentages, making it practical for algorithmic trading strategies. All indicators work with swing point data from RecentSwingIndicator implementations (fractal or ZigZag), automatically filtering and compressing swings to identify Elliott wave structures. The system treats DoubleNum NaN values as invalid using Num.isNaNOrNull() and Num.isValid(), preventing NaN pivots, ratios, and targets from leaking into analysis.
  • Core swing processing: ElliottSwingIndicator generates Elliott swings from RecentSwingIndicator swing points, ElliottSwingCompressor filters and compresses swings to identify wave structures, and ElliottWaveCountIndicator counts waves in the current pattern. ElliottSwingMetadata tracks swing relationships and wave structure.
  • Fibonacci analysis: ElliottRatioIndicator calculates Fibonacci retracement/extension ratios between waves, ElliottChannelIndicator projects parallel trend channels for wave validation, and ElliottConfluenceIndicator identifies price levels where multiple Fibonacci ratios converge. ElliottFibonacciValidator provides continuous proximity scoring methods (waveTwoProximityScore(), waveThreeProximityScore(), etc.) returning 0.0-1.0 instead of boolean pass/fail.
  • Wave state tracking: ElliottPhaseIndicator tracks the current wave phase (impulse waves 1-5, corrective waves A-B-C), and ElliottInvalidationIndicator surfaces invalidations when wave counts break down. ElliottPhase enum represents wave phases with degree information.
  • Confidence scoring and scenario generation: ElliottConfidence record captures confidence metrics with weighted factor scores (Fibonacci proximity 35%, time proportions 20%, alternation quality 15%, channel adherence 15%, structure completeness 15%). ElliottConfidenceScorer is a stateless utility that calculates confidence from swing data with configurable weights. ElliottScenario represents a single wave interpretation with confidence, invalidation level, and Fibonacci-based price targets. ElliottScenarioSet is an immutable container holding ranked alternative scenarios with convenience methods (base(), alternatives(), consensus(), hasStrongConsensus(), confidenceSpread()). ScenarioType enum classifies pattern types (IMPULSE, CORRECTIVE_ZIGZAG, CORRECTIVE_FLAT, CORRECTIVE_TRIANGLE, CORRECTIVE_COMPLEX, UNKNOWN). ElliottScenarioGenerator generates alternative interpretations by exploring different starting points, pattern types, and degree variations, with automatic pruning of low-confidence scenarios. ElliottScenarioIndicator is a CachedIndicator returning ElliottScenarioSet for each bar, integrating scenario generation with the indicator framework. ElliottScenarioComparator provides utilities for comparing scenarios with methods like divergenceScore(), sharedInvalidation(), consensusPhase(), and commonTargetRange().
  • Price projections and invalidation levels: ElliottProjectionIndicator returns Fibonacci-based price targets from the base case scenario. ElliottInvalidationLevelIndicator returns the specific price level that would invalidate the current count, with PRIMARY/CONSERVATIVE/AGGRESSIVE modes.
  • Facade and utilities: ElliottWaveFacade provides a high-level API with scenario-based methods: scenarios(), primaryScenario(int), alternativeScenarios(int), confidenceForPhase(int, ElliottPhase), hasScenarioConsensus(int), scenarioConsensus(int), scenarioSummary(int). ElliottDegree enum represents wave degrees (SUBMINUETTE through GRAND_SUPERCYCLE) with methods for higher/lower degree navigation. ElliottChannel represents parallel trend channels for wave validation.
  • Example and integration: ElliottWaveAnalysis example demonstrates confidence percentages, scenario probability distributions, and alternative scenario display, showing how to integrate Elliott Wave analysis into trading strategies.

  • Chart annotation support: Added BarSeriesLabelIndicator to the ta4j-examples charting package, enabling sparse bar-index labels for chart annotations. The indicator returns label Y-values (typically prices) at labeled indices and NaN elsewhere, with integrated support in TradingChartFactory for rendering text annotations on charts. Useful for marking significant events, wave labels, or custom annotations on trading charts.

  • Channel overlay helpers: Added a PriceChannel interface (upper/lower/median, shared validity/width/contains helpers, and a boundary enum), a ChannelBoundaryIndicator charting helper, and ChartBuilder.withChannelOverlay(...) convenience methods (including a channel-indicator overload) for plotting channel boundaries like Elliott channels, Bollinger bands, and Keltner channels. Charting now validates that channel overlays include both upper and lower boundaries, provides TradingView-inspired muted defaults with channel fill shading and a dashed, lower-opacity median line, and exposes a fluent channel styling stage including interior fill controls.

Changed

  • Elliott Wave scenario probability JSON output: Scenario probability values are now serialized as decimal ratios (0.0-1.0) rounded to two decimals instead of percentages, while log output remains in percent.
  • CachedIndicator and RecursiveCachedIndicator performance improvements: Major refactoring to improve indicator caching performance:
    • O(1) eviction: Replaced ArrayList-based storage with a fixed-size ring buffer (CachedBuffer). When maximumBarCount is set, evicting old values now takes constant time instead of O(n) per-bar copies.
    • Read-optimized locking: Migrated from synchronized blocks to a non-fair ReentrantReadWriteLock with an optimistic (lock-free) fast path for cache hits. Cache misses and invalidation remain write-locked, while read-heavy workloads scale without serializing threads.
    • Reduced allocation churn: Eliminated Collections.nCopies() allocations in the common "advance by 1 bar" case. The ring buffer writes directly to slots without creating intermediate lists.
    • Last-bar mutation caching: Repeated calls to getValue(endIndex) on an unchanged in-progress bar now reuse the cached result. The cache automatically invalidates when the bar is mutated (via addTrade() or addPrice()) or replaced (via addBar(..., true)).
    • Deadlock avoidance: Fixed lock-order deadlock risk between last-bar caching and the main cache by ensuring last-bar computations and invalidation never run while holding locks needed by cache writes.
    • Iterative prefill under single lock: RecursiveCachedIndicator now uses CachedBuffer.prefillUntil() to compute gap values iteratively under one write lock, avoiding repeated lock re-entry and series lookups.
    • Last-bar computation timeout: Added 5-second timeout for waiting threads to prevent indefinite hangs if the thread owning a last-bar computation dies unexpectedly.
  • ta4j-examples runners and regression coverage: Added main-source runners (CachedIndicatorBenchmark, RuleNameBenchmark, TrendLineAndSwingPointAnalysis) and a robust regression test (TrendLineAndSwingPointAnalysisTest) so full builds stay quiet while still validating trendlines/swing points and enabling chart generation via main.
  • BacktestPerformanceTuningHarness: Expanded the example into a configurable tuning harness that sweeps strategy counts, bar counts, and maximumBarCount hints, capturing runtime + GC overhead and identifying the last linear ("sweet spot") configuration. Includes an optional heap sweep that forks a child JVM per -Xmx value.
  • Comprehensive README overhaul: Completely rewrote the README to make Ta4j more approachable for new users while keeping it useful for experienced developers. Added a dedicated "Sourcing market data" section that walks through getting started with Yahoo Finance (no API key required!), explains all available data source implementations, and shows how to create custom data sources. Reorganized content with clearer navigation, better code examples, and practical tips throughout. The Quickstart example now includes proper error handling and demonstrates real-world data loading patterns. New users can go from zero to running their first backtest in minutes, while experienced quants can quickly find the advanced features they need.

Removed

  • Deleted BuyAndSellSignalsToChartTest.java, CashFlowToChartTest.java, StrategyAnalysisTest.java, TradeCostTest.java, IndicatorsToChartTest.java, IndicatorsToCsvTest.java from the ta4j-examples project. Despite designated as "tests", they simply launched the main of the associated class.
  • Consolidated SwingPointAnalysis.java and TrendLineAnalysis.java into TrendLineAndSwingPointAnalysis.java to provide a unified analysis example combining both features.
  • Removed TopStrategiesExampleBacktest.java and TrendLineDefaultCapsTest.java as part of example consolidation and test cleanup.

Fixed

  • Rule naming now lightweight: Rule#getName() is now a simple label (defaults to the class name) and no longer triggers JSON serialization. Composite rules build readable names from child labels without serialization side effects.
  • Explicit rule serialization APIs: Added Rule#toJson(BarSeries)/Rule#fromJson(BarSeries, String) so serialization happens only when explicitly requested. Custom names are preserved via __customName metadata, independent of getName().
  • Rule name visibility: Made rule names volatile and added regression coverage so custom names set on one thread are always visible on others, preventing fallback to expensive default-name serialization under concurrency.
  • Fixed GitHub Actions release-scheduler.yml failure in the Compute new version step (bash syntax) and hardened job if: conditions.
  • Fixed SuperTrendUpperBandIndicator NaN contamination by recovering once ATR leaves its unstable window and aligning unstable-bar counts across SuperTrend components so values stabilize after ATR warms up.
  • Consistent NaN handling across all SuperTrend indicators: SuperTrendLowerBandIndicator and SuperTrendIndicator now return NaN during the unstable period (when ATR values are not yet reliable), consistent with SuperTrendUpperBandIndicator and the project convention that indicators should return NaN during their unstable period. Previously, these indicators returned zero during the unstable period, which was inconsistent with other indicators and could lead to misleading calculations.
  • Test improvements for headless environment compatibility: Updated strategy and charting tests (RSI2StrategyTest, CCICorrectionStrategyTest, GlobalExtremaStrategyTest, MovingMomentumStrategyTest, ChartWorkflowTest) to use SwingChartDisplayer.DISABLE_DISPLAY_PROPERTY instead of Assume.assumeFalse() for headless environment checks. This allows tests to run reliably in both headless and non-headless environments without skipping, improving CI/CD compatibility and test coverage.
Source: README.md, updated 2025-12-29