{"id":13591152,"url":"https://github.com/ta4j/ta4j","last_synced_at":"2026-10-19T08:04:35.533Z","repository":{"id":37270519,"uuid":"103560333","full_name":"ta4j/ta4j","owner":"ta4j","description":"A Java library for technical analysis.","archived":false,"fork":false,"pushed_at":"2026-10-17T21:34:27.000Z","size":32529,"stargazers_count":2516,"open_issues_count":28,"forks_count":800,"subscribers_count":100,"default_branch":"master","last_synced_at":"2026-10-17T23:22:22.659Z","etag":null,"topics":["bitcoin","ethereum","forex","java","java-library","stocks","ta4j","technical-analysis","trading","trading-algorithms","trading-strategies"],"latest_commit_sha":null,"homepage":"http://www.ta4j.com","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ta4j.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":".github/CONTRIBUTING.md","funding":null,"license":"license-header.txt","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":"AUTHORS","dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","claude":null,"gemini":null,"cursor":null,"copilot":null,"dco":null,"cla":null,"disclosure":null}},"created_at":"2017-09-14T17:14:32.000Z","updated_at":"2026-10-17T18:23:55.000Z","dependencies_parsed_at":"2026-10-05T18:37:22.316Z","dependency_job_id":null,"html_url":"https://github.com/ta4j/ta4j","commit_stats":{"total_commits":1229,"total_committers":90,"mean_commits":"13.655555555555555","dds":0.7119609438567942,"last_synced_commit":"4755270e61e2478a66a65c1c9606e50be6c02204"},"previous_names":[],"tags_count":33,"template":false,"template_full_name":null,"purl":"pkg:github/ta4j/ta4j","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ta4j%2Fta4j","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ta4j%2Fta4j/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ta4j%2Fta4j/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ta4j%2Fta4j/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ta4j","download_url":"https://codeload.github.com/ta4j/ta4j/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ta4j%2Fta4j/sbom","scorecard":{"id":499347,"data":{"date":"2025-08-11","repo":{"name":"github.com/ta4j/ta4j","commit":"5ecafb411feb595fe9cd59b788d42779f90e12f6"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":5.4,"checks":[{"name":"Code-Review","score":8,"reason":"Found 6/7 approved changesets -- score normalized to 8","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/check.yml:1","Warn: no topLevel permission defined: .github/workflows/deploy_snapshot.yml:1","Warn: no topLevel permission defined: .github/workflows/test.yml:1","Warn: no topLevel permission defined: .github/workflows/validate.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Maintained","score":10,"reason":"30 commit(s) and 11 issue activity found in the last 90 days -- score normalized to 10","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"License","score":9,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Warn: project license file does not contain an FSF or OSI license."],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/check.yml:16: update your workflow using https://app.stepsecurity.io/secureworkflow/ta4j/ta4j/check.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/check.yml:18: update your workflow using https://app.stepsecurity.io/secureworkflow/ta4j/ta4j/check.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/deploy_snapshot.yml:15: update your workflow using https://app.stepsecurity.io/secureworkflow/ta4j/ta4j/deploy_snapshot.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/deploy_snapshot.yml:20: update your workflow using https://app.stepsecurity.io/secureworkflow/ta4j/ta4j/deploy_snapshot.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/test.yml:21: update your workflow using https://app.stepsecurity.io/secureworkflow/ta4j/ta4j/test.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/test.yml:24: update your workflow using https://app.stepsecurity.io/secureworkflow/ta4j/ta4j/test.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/test.yml:32: update your workflow using https://app.stepsecurity.io/secureworkflow/ta4j/ta4j/test.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/validate.yml:16: update your workflow using https://app.stepsecurity.io/secureworkflow/ta4j/ta4j/validate.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/validate.yml:18: update your workflow using https://app.stepsecurity.io/secureworkflow/ta4j/ta4j/validate.yml/master?enable=pin","Info:   0 out of   9 GitHub-owned GitHubAction dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Signed-Releases","score":0,"reason":"Project has not signed or included provenance with any releases.","details":["Warn: release artifact 0.18 not signed: https://api.github.com/repos/ta4j/ta4j/releases/218915638","Warn: release artifact 0.17 not signed: https://api.github.com/repos/ta4j/ta4j/releases/175745263","Warn: release artifact 0.16 not signed: https://api.github.com/repos/ta4j/ta4j/releases/156282072","Warn: release artifact 0.15 not signed: https://api.github.com/repos/ta4j/ta4j/releases/76832625","Warn: release artifact 0.14 not signed: https://api.github.com/repos/ta4j/ta4j/releases/41967382","Warn: release artifact 0.18 does not have provenance: https://api.github.com/repos/ta4j/ta4j/releases/218915638","Warn: release artifact 0.17 does not have provenance: https://api.github.com/repos/ta4j/ta4j/releases/175745263","Warn: release artifact 0.16 does not have provenance: https://api.github.com/repos/ta4j/ta4j/releases/156282072","Warn: release artifact 0.15 does not have provenance: https://api.github.com/repos/ta4j/ta4j/releases/76832625","Warn: release artifact 0.14 does not have provenance: https://api.github.com/repos/ta4j/ta4j/releases/41967382"],"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"Branch-Protection","score":-1,"reason":"internal error: error during branchesHandler.setup: internal error: githubv4.Query: Resource not accessible by integration","details":null,"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Packaging","score":10,"reason":"packaging workflow detected","details":["Info: Project packages its releases by way of GitHub Actions.: .github/workflows/deploy_snapshot.yml:9"],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 30 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-19T21:23:50.531Z","repository_id":37270519,"created_at":"2025-08-19T21:23:50.534Z","updated_at":"2025-08-19T21:23:50.534Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":344872684,"owners_count":38336094,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-10-03T21:59:58.778Z","status":"online","status_checked_at":"2026-10-17T02:00:06.547Z","response_time":57,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bitcoin","ethereum","forex","java","java-library","stocks","ta4j","technical-analysis","trading","trading-algorithms","trading-strategies"],"created_at":"2024-08-01T16:00:54.177Z","updated_at":"2026-10-19T08:04:35.522Z","avatar_url":"https://github.com/ta4j.png","language":"Java","funding_links":[],"categories":["Technical analysis libraries","Java","项目","Projects","Utilities","金融"],"sub_categories":["财务","FrameWorks","文件同步"],"readme":"# ta4j  [![Run Verify](https://github.com/ta4j/ta4j/actions/workflows/test.yml/badge.svg)](https://github.com/ta4j/ta4j/actions/workflows/test.yml) [![Discord](https://img.shields.io/discord/745552125769023488.svg?label=\u0026logo=discord\u0026logoColor=ffffff\u0026color=7389D8\u0026labelColor=6A7EC2)](https://discord.gg/HX9MbWZ) [![License: MIT](https://img.shields.io/badge/License-MIT-brightgreen.svg)](https://opensource.org/licenses/MIT) ![Maven Central](https://img.shields.io/maven-central/v/org.ta4j/ta4j-parent?color=blue\u0026label=Version) ![JDK](https://img.shields.io/badge/JDK-25%2B-orange)\n\n**Technical Analysis for Java**\n\n[Documentation](https://ta4j.github.io/ta4j-wiki/) · [Javadoc](https://ta4j.github.io/ta4j/) · [Examples](ta4j-examples/README.md) · [Discord](https://discord.gg/HX9MbWZ)\n\nta4j is an open-source Java library for technical analysis and trading-system research. Build indicators and rules, backtest strategies with realistic costs and execution assumptions, inspect the results, and reuse the same strategy logic in live applications.\n\n[Why ta4j?](#why-ta4j) · [Install](#install-in-seconds) · [Quick start](#quick-start-your-first-strategy) · [Workflow](#the-core-workflow) · [Examples](#real-world-examples) · [Contributing](#contributing)\n\n---\n\n## Why ta4j?\n\nta4j gives Java developers a typed, composable model for market data, indicators, rules, strategies, backtests, analysis, and live-style execution records. It fits naturally into JVM applications and tooling without requiring a Python bridge, a separate service, or a proprietary strategy DSL.\n\nThe goal is **reproducible research**, not guaranteed returns. ta4j helps you state a trading idea precisely, test it under explicit assumptions, and understand where the result came from. Market data and broker connectivity remain under your control.\n\n### Features at a glance\n\n| Capability | What it gives you |\n| --- | --- |\n| **Market-series model** | OHLCV `BarSeries` implementations for ordinary, moving-window, and concurrent workflows |\n| **Broad indicator and pattern catalog** | Moving averages, momentum, volatility, volume, candlestick patterns, market structure, and more |\n| **Composable strategies** | Fluent `Indicator`, `Rule`, and `Strategy` APIs with no required DSL |\n| **Backtesting and research** | Single-strategy runs, large candidate sets, ranking, parameter research, and walk-forward workflows |\n| **Execution realism** | Transaction and borrowing costs, slippage, stop-limit fills, position sizing, partial fills, and lot matching |\n| **Analysis and presentation** | Risk/return criteria, charting workflows, and JSON serialization support |\n| **Forecasting** | Causal forecast-state and projection APIs for Monte Carlo, analog, Kalman, and conformal workflows |\n| **Live integration** | Reuse strategy logic while your application owns data ingestion, order routing, reconciliation, and recovery |\n\n## Install in seconds\n\nta4j requires **Java 25+**. Most applications need only `ta4j-core`:\n\n\u003c!-- TA4J_VERSION_BLOCK:core:stable:begin --\u003e\n\n```xml\n\u003cdependency\u003e\n  \u003cgroupId\u003eorg.ta4j\u003c/groupId\u003e\n  \u003cartifactId\u003eta4j-core\u003c/artifactId\u003e\n  \u003cversion\u003e0.26.0\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\n\u003c!-- TA4J_VERSION_BLOCK:core:stable:end --\u003e\n\nUse `ta4j-examples` for runnable demos, sample data sources, and charting workflows to learn from or copy into your own project. It is not required by `ta4j-core`.\n\n\u003cdetails\u003e\n\u003csummary\u003eSnapshots and the ta4j-examples dependency\u003c/summary\u003e\n\nSnapshot builds are published through the Sonatype Central snapshot repository:\n\n\u003c!-- TA4J_VERSION_BLOCK:core:snapshot:begin --\u003e\n\n```xml\n\u003crepository\u003e\n  \u003cid\u003ecentral-portal-snapshots\u003c/id\u003e\n  \u003curl\u003ehttps://central.sonatype.com/repository/maven-snapshots/\u003c/url\u003e\n  \u003creleases\u003e\u003cenabled\u003efalse\u003c/enabled\u003e\u003c/releases\u003e\n  \u003csnapshots\u003e\u003cenabled\u003etrue\u003c/enabled\u003e\u003c/snapshots\u003e\n\u003c/repository\u003e\n\n\u003cdependency\u003e\n  \u003cgroupId\u003eorg.ta4j\u003c/groupId\u003e\n  \u003cartifactId\u003eta4j-core\u003c/artifactId\u003e\n  \u003cversion\u003e0.26.1-SNAPSHOT\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\n\u003c!-- TA4J_VERSION_BLOCK:core:snapshot:end --\u003e\n\nStable examples artifact:\n\n\u003c!-- TA4J_VERSION_BLOCK:examples:stable:begin --\u003e\n\n```xml\n\u003cdependency\u003e\n  \u003cgroupId\u003eorg.ta4j\u003c/groupId\u003e\n  \u003cartifactId\u003eta4j-examples\u003c/artifactId\u003e\n  \u003cversion\u003e0.26.0\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\n\u003c!-- TA4J_VERSION_BLOCK:examples:stable:end --\u003e\n\nSnapshot examples artifact:\n\n\u003c!-- TA4J_VERSION_BLOCK:examples:snapshot:begin --\u003e\n\n```xml\n\u003cdependency\u003e\n  \u003cgroupId\u003eorg.ta4j\u003c/groupId\u003e\n  \u003cartifactId\u003eta4j-examples\u003c/artifactId\u003e\n  \u003cversion\u003e0.26.1-SNAPSHOT\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\n\u003c!-- TA4J_VERSION_BLOCK:examples:snapshot:end --\u003e\n\n\u003c/details\u003e\n\n## Quick start: Your first strategy\n\n### Run the included example\n\n```bash\ngit clone https://github.com/ta4j/ta4j.git\ncd ta4j\n\n# Build the reactor once, then run the default Quickstart example.\n./mvnw -DskipTests install\n./mvnw -pl ta4j-examples exec:java\n```\n\nOn Windows, use `mvnw.cmd` instead of `./mvnw`. The example loads bundled Bitcoin data, evaluates a strategy, prints performance metrics, and displays a chart when a graphical environment is available.\n\nRun another example by overriding the configured main class:\n\n```bash\n./mvnw -pl ta4j-examples exec:java -Dexec.mainClass=ta4jexamples.backtesting.TradingRecordParityBacktest\n```\n\n### Use the core API\n\nThe essential model is:\n\n\u003e `BarSeries` → `Indicator` → `Rule` → `Strategy` → `TradingRecord`\n\n```java\nimport org.ta4j.core.BarSeries;\nimport org.ta4j.core.BaseStrategy;\nimport org.ta4j.core.Rule;\nimport org.ta4j.core.Strategy;\nimport org.ta4j.core.TradingRecord;\nimport org.ta4j.core.backtest.BarSeriesManager;\nimport org.ta4j.core.indicators.averages.EMAIndicator;\nimport org.ta4j.core.indicators.helpers.ClosePriceIndicator;\nimport org.ta4j.core.rules.CrossedDownIndicatorRule;\nimport org.ta4j.core.rules.CrossedUpIndicatorRule;\n\nBarSeries series = ...; // Load your OHLCV bars.\n\nClosePriceIndicator close = new ClosePriceIndicator(series);\nEMAIndicator fastEma = new EMAIndicator(close, 12);\nEMAIndicator slowEma = new EMAIndicator(close, 26);\n\nRule entry = new CrossedUpIndicatorRule(fastEma, slowEma);\nRule exit = new CrossedDownIndicatorRule(fastEma, slowEma);\nStrategy strategy = new BaseStrategy(\"EMA crossover\", entry, exit);\n\nTradingRecord record = new BarSeriesManager(series).run(strategy);\nSystem.out.printf(\"Positions: %d%n\", record.getPositionCount());\n```\n\nThe runnable [`Quickstart`](ta4j-examples/src/main/java/ta4jexamples/Quickstart.java) adds data loading, metrics, and charting around this same flow.\n\n## The core workflow\n\nA typical ta4j application follows one path:\n\n\u003e market data → `BarSeries` → indicators → rules → strategy → backtest or live evaluation → metrics and charts\n\n### Sourcing market data\n\n`ta4j-core` works with any OHLCV source. The `ta4j-examples` module includes a shared `BarSeriesDataSource` model and ready-to-run loaders for:\n\n- [Yahoo Finance](ta4j-examples/src/main/java/ta4jexamples/datasources/YahooFinanceHttpBarSeriesDataSource.java) for stocks, ETFs, and crypto\n- [Coinbase](ta4j-examples/src/main/java/ta4jexamples/datasources/CoinbaseHttpBarSeriesDataSource.java) for cryptocurrency pairs\n- [CSV](ta4j-examples/src/main/java/ta4jexamples/datasources/CsvFileBarSeriesDataSource.java), [JSON](ta4j-examples/src/main/java/ta4jexamples/datasources/JsonFileBarSeriesDataSource.java), and trade-level [Bitstamp CSV](ta4j-examples/src/main/java/ta4jexamples/datasources/BitStampCsvTradesFileBarSeriesDataSource.java)\n\nFor production systems, adapt your broker, exchange, database, REST API, or WebSocket feed into bars and keep normalization, gap handling, and corporate-action adjustments explicit.\n\n### Evaluate performance with metrics\n\nBacktests can model costs before you calculate returns and risk:\n\n```java\nTradingRecord record = new BarSeriesManager(\n        series,\n        new LinearTransactionCostModel(0.001),\n        new LinearBorrowingCostModel(0.0001))\n        .run(strategy);\n\nNum netReturn = new NetReturnCriterion().calculate(series, record);\nNum maximumDrawdown = new MaximumDrawdownCriterion().calculate(series, record);\n```\n\nUse `TradeExecutionModel` implementations when fill timing, slippage, stop-limit behavior, or partial execution matters. Use `BacktestExecutor` when you need to evaluate and rank many independent strategy candidates. The [backtesting guide](https://ta4j.github.io/ta4j-wiki/Backtesting.html) and [realism checklist](https://ta4j.github.io/ta4j-wiki/Backtesting-Realism-Checklist.html) explain the assumptions that most often invalidate attractive results.\n\n### Visualize and share strategies\n\nCharting helpers live in `ta4j-examples` and build on JFreeChart:\n\n\u003c!-- START_SNIPPET: ema-crossover --\u003e\n```java\n// Generate simplified chart - just price, indicators, and signals (no subchart)\nChartWorkflow chartWorkflow = new ChartWorkflow();\nJFreeChart chart = chartWorkflow.builder()\n        .withTitle(\"EMA Crossover Strategy\")\n        .withSeries(series) // Price bars (candlesticks)\n        .withIndicatorOverlay(fastEma) // Overlay indicators on price chart\n        .withIndicatorOverlay(slowEma)\n        .withTradingRecordOverlay(record) // Mark entry/exit points with arrows\n        .toChart();\nchartWorkflow.saveChartImage(chart, series, \"ema-crossover-strategy\", \"output/charts\"); // Save as image\n```\n\u003c!-- END_SNIPPET: ema-crossover --\u003e\n\n![EMA crossover strategy chart](ta4j-examples/docs/img/ema-crossover-readme.jpg)\n\n\u003cdetails\u003e\n\u003csummary\u003eMore charting examples\u003c/summary\u003e\n\nRSI in a separate subchart:\n\n\u003c!-- START_SNIPPET: rsi-strategy --\u003e\n```java\n// Create indicators\nClosePriceIndicator close = new ClosePriceIndicator(series);\nRSIIndicator rsi = new RSIIndicator(close, 14);\n\n// RSI strategy: buy when RSI crosses below 30 (oversold), sell when RSI crosses\n// above 70 (overbought)\nRule entry = new CrossedDownIndicatorRule(rsi, 30);\nRule exit = new CrossedUpIndicatorRule(rsi, 70);\nStrategy strategy = new BaseStrategy(\"RSI Strategy\", entry, exit);\nTradingRecord record = new BarSeriesManager(series).run(strategy);\n\nChartWorkflow chartWorkflow = new ChartWorkflow();\nJFreeChart chart = chartWorkflow.builder()\n        .withTitle(\"RSI Strategy with Subchart\")\n        .withSeries(series) // Price bars (candlesticks)\n        .withTradingRecordOverlay(record) // Mark entry/exit points\n        .withSubChart(rsi) // RSI indicator in separate subchart panel\n        .toChart();\n```\n\u003c!-- END_SNIPPET: rsi-strategy --\u003e\n\n![RSI strategy with subchart](ta4j-examples/docs/img/rsi-strategy-readme.jpg)\n\nA performance criterion beside the strategy:\n\n\u003c!-- START_SNIPPET: strategy-performance --\u003e\n```java\n// Create indicators: multiple moving averages\nClosePriceIndicator close = new ClosePriceIndicator(series);\nSMAIndicator sma20 = new SMAIndicator(close, 20);\nEMAIndicator ema12 = new EMAIndicator(close, 12);\n\n// Strategy: buy when EMA crosses above SMA, sell when EMA crosses below SMA\nRule entry = new CrossedUpIndicatorRule(ema12, sma20);\nRule exit = new CrossedDownIndicatorRule(ema12, sma20);\nStrategy strategy = new BaseStrategy(\"EMA/SMA Crossover\", entry, exit);\nTradingRecord record = new BarSeriesManager(series).run(strategy);\n\nChartWorkflow chartWorkflow = new ChartWorkflow();\nJFreeChart chart = chartWorkflow.builder()\n        .withTitle(\"Strategy Performance Analysis\")\n        .withSeries(series) // Price bars (candlesticks)\n        .withIndicatorOverlay(sma20) // Overlay SMA on price chart\n        .withIndicatorOverlay(ema12) // Overlay EMA on price chart\n        .withTradingRecordOverlay(record) // Mark entry/exit points\n        .withSubChart(new MaximumDrawdownCriterion(), record) // Performance metric in subchart\n        .toChart();\n```\n\u003c!-- END_SNIPPET: strategy-performance --\u003e\n\n![Strategy performance analysis](ta4j-examples/docs/img/strategy-performance-readme.jpg)\n\nMultiple indicators and performance layers:\n\n\u003c!-- START_SNIPPET: advanced-strategy --\u003e\n```java\n// Create indicators\nClosePriceIndicator close = new ClosePriceIndicator(series);\nSMAIndicator sma50 = new SMAIndicator(close, 50);\nEMAIndicator ema12 = new EMAIndicator(close, 12);\nMACDIndicator macd = new MACDIndicator(close, 12, 26);\nRSIIndicator rsi = new RSIIndicator(close, 14);\n\n// Strategy: buy when EMA crosses above SMA and RSI \u003e 50, sell when EMA crosses\n// below SMA\nRule entry = new CrossedUpIndicatorRule(ema12, sma50).and(new OverIndicatorRule(rsi, 50));\nRule exit = new CrossedDownIndicatorRule(ema12, sma50);\nStrategy strategy = new BaseStrategy(\"Advanced Multi-Indicator Strategy\", entry, exit);\nTradingRecord record = new BarSeriesManager(series).run(strategy);\n\nChartWorkflow chartWorkflow = new ChartWorkflow();\nJFreeChart chart = chartWorkflow.builder()\n        .withTitle(\"Advanced Multi-Indicator Strategy\")\n        .withSeries(series) // Price bars (candlesticks)\n        .withIndicatorOverlay(sma50) // Overlay SMA on price chart\n        .withIndicatorOverlay(ema12) // Overlay indicators on price chart\n        .withTradingRecordOverlay(record) // Mark entry/exit points\n        .withSubChart(macd) // MACD indicator in subchart\n        .withSubChart(rsi) // RSI indicator in subchart\n        .withSubChart(new NetProfitLossCriterion(), record) // Net profit/loss performance metric\n        .toChart();\n```\n\u003c!-- END_SNIPPET: advanced-strategy --\u003e\n\n![Advanced multi-indicator strategy](ta4j-examples/docs/img/advanced-strategy-readme.jpg)\n\nSee the [charting guide](https://ta4j.github.io/ta4j-wiki/Charting.html) for layout, export, and time-axis options.\n\n\u003c/details\u003e\n\n### From backtest to live trading\n\nThe same `Strategy` can evaluate historical or newly arriving bars, but ta4j is not an order-management system. A live integration must:\n\n- choose deliberately between forming-candle and closed-candle evaluation\n- call `shouldEnter(index, tradingRecord)` and `shouldExit(index, tradingRecord)`\n- record broker-confirmed fills and keep `TradingRecord` synchronized\n- deduplicate orders, reconcile state after restart, and handle rejected or partial fills\n\nStart with the [core API decision guide](ta4j-core/README.md), [live-candle semantics](https://ta4j.github.io/ta4j-wiki/Live-Candle-vs-Closed-Candle-Evaluation.html), and the [live trading runbook](https://ta4j.github.io/ta4j-wiki/Live-Trading-Runbook.html).\n\n## Advanced capabilities\n\n### Forecasting\n\nForecast indicators stay inside the normal `Indicator` model while producing a distribution at a fixed future horizon. A forecast evaluated at index `i` reads source values only through `i`, so it can later be compared with the realized value at `i + horizon` without look-ahead leakage.\n\n```java\nLogReturnIndicator returns = new LogReturnIndicator(series);\nReturnForecastStateIndicator\u003cReturnForecastState\u003e state =\n        new EwmaReturnForecastStateIndicator(returns);\n\nForecastProjectionIndicator fiveBarForecast =\n        new MonteCarloPriceForecastIndicator(state, 5);\n\nIndicator\u003cNum\u003e median = fiveBarForecast.median();\nIndicator\u003cNum\u003e downside = fiveBarForecast.quantile(0.05);\n```\n\nUse deterministic seeds and explicit projection indicators when results must be repeatable. The examples module includes complete [rolling conformal](ta4j-examples/src/main/java/ta4jexamples/analysis/forecast/RollingConformalForecastExample.java) and [kinematic Kalman](ta4j-examples/src/main/java/ta4jexamples/analysis/forecast/KinematicKalmanForecastExample.java) walkthroughs.\n\n### Strategy and component serialization\n\nSupported indicators, rules, and strategies can be serialized for persistence, sharing, and integration with other systems.\n\n\u003cdetails\u003e\n\u003csummary\u003eJSON serialization examples\u003c/summary\u003e\n\n\u003c!-- START_SNIPPET: serialize-indicator --\u003e\n```java\n// Serialize an indicator (RSI) to JSON\nClosePriceIndicator close = new ClosePriceIndicator(series);\nRSIIndicator rsi = new RSIIndicator(close, 14);\nString rsiJson = rsi.toJson();\nLOG.info(\"Output: {}\", rsiJson);\n// Output:\n// {\"type\":\"RSIIndicator\",\"parameters\":{\"barCount\":14},\"components\":[{\"type\":\"ClosePriceIndicator\"}]}\n```\n\u003c!-- END_SNIPPET: serialize-indicator --\u003e\n\n\u003c!-- START_SNIPPET: serialize-rule --\u003e\n```java\n// Serialize a rule (AndRule) to JSON\nRule rule1 = new OverIndicatorRule(rsi, 50);\nRule rule2 = new UnderIndicatorRule(rsi, 80);\nRule andRule = new AndRule(rule1, rule2);\nString ruleJson = ComponentSerialization.toJson(RuleSerialization.describe(andRule));\nLOG.info(\"Output: {}\", ruleJson);\n// Output:\n// {\"type\":\"AndRule\",\"label\":\"AndRule\",\"components\":[{\"type\":\"OverIndicatorRule\",\"label\":\"OverIndicatorRule\",\"components\":[{\"type\":\"RSIIndicator\",\"parameters\":{\"barCount\":14},\"components\":[{\"type\":\"ClosePriceIndicator\"}]}],\"parameters\":{\"threshold\":50.0}},{\"type\":\"UnderIndicatorRule\",\"label\":\"UnderIndicatorRule\",\"components\":[{\"type\":\"RSIIndicator\",\"parameters\":{\"barCount\":14},\"components\":[{\"type\":\"ClosePriceIndicator\"}]}],\"parameters\":{\"threshold\":80.0}}]}\n```\n\u003c!-- END_SNIPPET: serialize-rule --\u003e\n\n\u003c!-- START_SNIPPET: serialize-strategy --\u003e\n```java\n// Serialize a strategy (EMA Crossover) to JSON\nEMAIndicator fastEma = new EMAIndicator(close, 12);\nEMAIndicator slowEma = new EMAIndicator(close, 26);\nRule entry = new CrossedUpIndicatorRule(fastEma, slowEma);\nRule exit = new CrossedDownIndicatorRule(fastEma, slowEma);\nStrategy strategy = new BaseStrategy(\"EMA Crossover\", entry, exit);\nString strategyJson = strategy.toJson();\nLOG.info(\"Output: {}\", strategyJson);\n// Output: {\"type\":\"BaseStrategy\",\"label\":\"EMA\n// Crossover\",\"parameters\":{\"unstableBars\":0},\"rules\":[{\"type\":\"CrossedUpIndicatorRule\",\"label\":\"entry\",\"components\":[{\"type\":\"EMAIndicator\",\"parameters\":{\"barCount\":12},\"components\":[{\"type\":\"ClosePriceIndicator\"}]},{\"type\":\"EMAIndicator\",\"parameters\":{\"barCount\":26},\"components\":[{\"type\":\"ClosePriceIndicator\"}]}]},{\"type\":\"CrossedDownIndicatorRule\",\"label\":\"exit\",\"components\":[{\"type\":\"EMAIndicator\",\"parameters\":{\"barCount\":12},\"components\":[{\"type\":\"ClosePriceIndicator\"}]},{\"type\":\"EMAIndicator\",\"parameters\":{\"barCount\":26},\"components\":[{\"type\":\"ClosePriceIndicator\"}]}]}]}\n```\n\u003c!-- END_SNIPPET: serialize-strategy --\u003e\n\nRestore supported components with `Indicator.fromJson(series, json)` and `Strategy.fromJson(series, json)`. See [migration and version compatibility](https://ta4j.github.io/ta4j-wiki/Migration-and-Version-Compatibility.html) before persisting descriptors across releases.\n\n\u003c/details\u003e\n\n### Specialized research tools\n\nBeyond the basic strategy loop, ta4j includes building blocks for batch backtests, static target-weight multi-asset portfolio backtests, portfolio correlation clustering and minimum-variance allocation, parameter research, position sizing, causal swing detection, rolling correlations, regime-aware rules, candlestick patterns, Elliott Wave analysis, LPPL residuals, streaming trade ingestion, and fill-aware live records.\n\nThese capabilities are intentionally not expanded into mini-manuals here. Use the [examples index](ta4j-examples/README.md), [core API guide](ta4j-core/README.md), [Javadoc](https://ta4j.github.io/ta4j/), and [wiki](https://ta4j.github.io/ta4j-wiki/) to go deeper without losing the onboarding path.\n\n### Bounded trading records\n\nA `BaseTradingRecord` created with a start or end index scopes position-based criteria to that range: positions entered before the start are excluded, and positions exiting after the end count as still open at the end. Use `TradingRecord.getContainedPositions(series)` to inspect the closed positions a criterion will see, or `AnalysisWindow` with `AnalysisContext` to choose a different inclusion policy for an unbounded record.\n\n### Performance\n\nta4j lets you choose `DecimalNum` for precision-first workflows or `DoubleNum` for throughput-first workflows with accepted floating-point tradeoffs. Moving series can cap retained history, indicator values are cached, and independent strategy candidates can be evaluated in parallel.\n\nMeasure changes on your own workload rather than relying on generic claims. Use the [`BacktestPerformanceTuningHarness`](ta4j-examples/src/main/java/ta4jexamples/backtesting/BacktestPerformanceTuningHarness.java), the [Num guide](https://ta4j.github.io/ta4j-wiki/Num.html), and [Performance Characterization](https://ta4j.github.io/ta4j-wiki/Performance-Characterization.html) for repeatable comparisons.\n\n## Real-world examples\n\nThe `ta4j-examples` module is organized as progressive learning tracks:\n\n| Goal | Start here |\n| --- | --- |\n| First strategy and metrics | [`Quickstart`](ta4j-examples/src/main/java/ta4jexamples/Quickstart.java), [`StrategyAnalysis`](ta4j-examples/src/main/java/ta4jexamples/analysis/StrategyAnalysis.java) |\n| Data sourcing | [`YahooFinanceBacktest`](ta4j-examples/src/main/java/ta4jexamples/backtesting/YahooFinanceBacktest.java), [`CoinbaseBacktest`](ta4j-examples/src/main/java/ta4jexamples/backtesting/CoinbaseBacktest.java) |\n| Execution semantics | [`TradingRecordParityBacktest`](ta4j-examples/src/main/java/ta4jexamples/backtesting/TradingRecordParityBacktest.java), [`TradeFillRecordingExample`](ta4j-examples/src/main/java/ta4jexamples/backtesting/TradeFillRecordingExample.java) |\n| Multi-asset portfolios | [`StaticPortfolioBacktest`](ta4j-examples/src/main/java/ta4jexamples/portfolio/StaticPortfolioBacktest.java) compares buy-and-hold with monthly rebalancing of a target-weight portfolio with a cash sleeve and transaction costs |\n| Parameter research | [`SimpleMovingAverageRangeBacktest`](ta4j-examples/src/main/java/ta4jexamples/backtesting/SimpleMovingAverageRangeBacktest.java), [`RelationshipObjectiveSearchExample`](ta4j-examples/src/main/java/ta4jexamples/research/RelationshipObjectiveSearchExample.java) |\n| Forecasting and calibration | [`RollingConformalForecastExample`](ta4j-examples/src/main/java/ta4jexamples/analysis/forecast/RollingConformalForecastExample.java), [`KinematicKalmanForecastExample`](ta4j-examples/src/main/java/ta4jexamples/analysis/forecast/KinematicKalmanForecastExample.java) |\n| Forecasting and robustness | [`CorrentropyKalmanExample`](ta4j-examples/src/main/java/ta4jexamples/analysis/forecast/CorrentropyKalmanExample.java) demonstrates ATR-derived Q/R, the robust estimate, residual, and measurement weight on an ossified S\u0026P 500 weekly series |\n| Charting and diagnostics | [`IndicatorsToChart`](ta4j-examples/src/main/java/ta4jexamples/indicators/IndicatorsToChart.java), [`CashFlowToChart`](ta4j-examples/src/main/java/ta4jexamples/analysis/CashFlowToChart.java) |\n\nSee [`ta4j-examples/README.md`](ta4j-examples/README.md) for the complete learning sequence and runnable commands.\n\n## Documentation\n\nNew to ta4j? Follow the [Canonical User Journey](https://ta4j.github.io/ta4j-wiki/Canonical-User-Journey.html) and run the examples in order. Moving from exploration to serious research? Apply the [realism checklist](https://ta4j.github.io/ta4j-wiki/Backtesting-Realism-Checklist.html) before trusting a result. Moving toward live execution? Build around the [live trading runbook](https://ta4j.github.io/ta4j-wiki/Live-Trading-Runbook.html), especially its reconciliation and recovery guidance.\n\n| Need | Resource |\n| --- | --- |\n| A guided first hour | [Canonical User Journey](https://ta4j.github.io/ta4j-wiki/Canonical-User-Journey.html) |\n| Core API and execution choices | [`ta4j-core/README.md`](ta4j-core/README.md) |\n| Runnable examples | [`ta4j-examples/README.md`](ta4j-examples/README.md) |\n| Backtesting concepts | [Backtesting guide](https://ta4j.github.io/ta4j-wiki/Backtesting.html) |\n| Research quality gate | [Backtesting Realism Checklist](https://ta4j.github.io/ta4j-wiki/Backtesting-Realism-Checklist.html) |\n| Live operations | [Live Trading Runbook](https://ta4j.github.io/ta4j-wiki/Live-Trading-Runbook.html) |\n| API changes | [Migration and Version Compatibility](https://ta4j.github.io/ta4j-wiki/Migration-and-Version-Compatibility.html) |\n| Troubleshooting | [Troubleshooting Hub](https://ta4j.github.io/ta4j-wiki/Troubleshooting-Hub.html) |\n| Complete API reference | [Javadoc](https://ta4j.github.io/ta4j/) |\n\n## Community \u0026 support\n\n- [Discord](https://discord.gg/HX9MbWZ) for usage questions and design discussion\n- [GitHub Issues](https://github.com/ta4j/ta4j/issues) for reproducible bugs and feature requests\n- [Documentation wiki](https://ta4j.github.io/ta4j-wiki/) for guides and operational references\n- [Javadoc](https://ta4j.github.io/ta4j/) for API-level detail\n\n## Contributing\n\nRead the [contribution guide](.github/CONTRIBUTING.md), [Code of Conduct](CODE_OF_CONDUCT.md), and [roadmap](https://ta4j.github.io/ta4j-wiki/Roadmap-and-Tasks.html). Contributions should include focused tests and an appropriate `CHANGELOG.md` entry.\n\nContributor reference:\n\n- [Build commands: Maven](#build-commands-maven)\n\n### Build commands: Maven\n\n\u003cdetails\u003e\n\u003csummary\u003eContributor build and verification commands\u003c/summary\u003e\n\nThe repository requires Java 25+ and includes Maven Wrapper scripts pinned to Maven 3.9.16.\n\n- Standard wrapper: use `./mvnw ...` on macOS/Linux, `mvnw.cmd ...` on Windows, or system Maven 3.9+ intentionally.\n- Canonical quality gate: Use `scripts/run-full-build-quiet.sh` on macOS/Linux/Git Bash/WSL or `scripts/run-full-build-quiet.ps1` on Windows PowerShell; it uses native Maven and WSL preflight when available, with Git Bash as the fallback.\n- Maven-only repair and verification: `./mvnw -B clean license:format spotless:apply verify -Dta4j.excludedTestTags=analysis-demo,benchmark,requires-display,requires-headless`\n- Non-mutating Maven-only validation: `./mvnw -B clean license:check spotless:check verify -Dta4j.excludedTestTags=analysis-demo,benchmark,requires-display,requires-headless`\n- Focused formatting repair: `./mvnw -B license:format spotless:apply`\n- SpotBugs gate: `./mvnw -pl ta4j-core -am clean compile spotbugs:check`\n- JaCoCo gate: `./mvnw -pl ta4j-core -am test jacoco:report jacoco:check`\n- Focused coverage report: `./mvnw -pl ta4j-core -am -Dtest=BarSeriesManagerTest -Dsurefire.failIfNoSpecifiedTests=false test jacoco:report`\n\nRun the full quality path before opening or updating a pull request and review any license-header or formatting repairs before committing them. Eclipse users can import `code-formatter.xml`; IntelliJ users should use an Eclipse-format-profile integration. Maven remains the authoritative formatter entrypoint.\n\n\u003c/details\u003e\n\n### Release \u0026 snapshot publishing\n\nSnapshot and stable publishing are automated. Maintainers should use [`RELEASE_PROCESS.md`](RELEASE_PROCESS.md) for the supported release path, recovery procedures, required configuration, and audit artifacts.\n\n## License and risk\n\nta4j is released under the [MIT License](https://opensource.org/licenses/MIT). It is provided as-is, without a warranty or any promise of correctness, profitability, or fitness for a particular purpose. Backtests are models of the assumptions you encode; they are not evidence that future trading will be profitable.\n\n## Powered by\n\n[![JetBrains logo](https://resources.jetbrains.com/storage/products/company/brand/logos/jetbrains.svg)](https://jb.gg/OpenSource)\n\n\u003ca href=\"https://github.com/ta4j/ta4j/graphs/contributors\"\u003e\n  \u003cimg src=\"https://contrib.rocks/image?repo=ta4j/ta4j\" alt=\"ta4j contributors\"\u003e\n\u003c/a\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fta4j%2Fta4j","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fta4j%2Fta4j","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fta4j%2Fta4j/lists"}