Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
4 changes: 2 additions & 2 deletions .github/workflows/ci-cd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: CI/CD

on:
push:
branches: [ main, develop ]
branches: [ main, dev ]
pull_request:
workflow_dispatch:

Expand Down Expand Up @@ -76,7 +76,7 @@ jobs:
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
release_branches: main
pre_release_branches: develop
pre_release_branches: dev
dry_run: true
default_bump: ${{ steps.check_tags.outputs.has_tags == 'false' && 'major' || 'false' }}
custom_release_rules: |
Expand Down
9 changes: 9 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -287,3 +287,12 @@ __pycache__/
*.odx.cs
*.xsd.cs
.DS_Store

# Agent tooling scratch directories and generated state
.auto-claude/
.auto-claude-security.json
.auto-claude-status
.claude_settings.json
.worktrees/
.security-key
logs/security/
4 changes: 4 additions & 0 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -29,5 +29,9 @@
<PackageVersion Include="MudBlazor" Version="9.7.0" />
<PackageVersion Include="System.Text.Json" Version="10.0.5" />
<PackageVersion Include="PublishSPAforGitHubPages.Build" Version="3.0.3" />
<!-- Benchmarks -->
<PackageVersion Include="BenchmarkDotNet" Version="0.15.8" />
<!-- Samples -->
<PackageVersion Include="Microsoft.AspNetCore.SignalR.Client" Version="10.0.5" />
</ItemGroup>
</Project>
114 changes: 104 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,16 @@ A modern and robust C# Technical Analysis library based on the original open-sou
* [📌 Features](#-features)
* [Roadmap (next features)](#roadmap-next-features)
* [📄 Documentation](#-documentation)
* [📖 Guides](#-guides)
* [📥 Installation](#-installation)
* [📋 Prerequisites](#-prerequisites)
* [🚀 We use the latest C# features](#-we-use-the-latest-c-features)
* [📦 NuGet Packages](#-nuget-packages)
* [🧪 Tests Specifications](#-tests-specifications)
* [💾 Installation](#-installation-1)
* [🧑‍💻 Usage](#-usage)
* [🧩 Samples](#-samples)
* [⚡ Benchmarks](#-benchmarks)
* [📊 Code Quality](#-code-quality)
* [❓ Issues and Feature Requests](#-issues-and-feature-requests)
* [🤝 Contributing](#-contributing)
Expand All @@ -59,7 +63,12 @@ The primary objective of TaLibStandard is to provide a comprehensive, feature-ri

## 🏁 Getting started

To get started with TaLibStandard, you can clone the repository and explore the examples provided in the `examples` directory. You can also refer to the list of [available functions](./docs/functions.md) in the documentation for a comprehensive overview of the library's capabilities.
To get started with TaLibStandard, read the [getting started guide](./docs/guides/getting-started.md) —
it covers installation, your first indicator, and the output-alignment rule that everything else depends
on. Then clone the repository and explore the runnable projects in the [`samples`](./samples) directory
(see [Samples](#-samples)). For a comprehensive overview of the library's capabilities, refer to the
[indicator catalog](./docs/indicators/README.md) or the flat list of
[available functions](./docs/functions.md).

## 📌 Features

Expand All @@ -70,12 +79,12 @@ To get started with TaLibStandard, you can clone the repository and explore the
### Roadmap (next features)

* [ ] Comprehensive API documentation that is easy to understand
* [ ] High-Level API for common use cases
* [x] High-Level API for common use cases — see the [fluent API guide](./docs/guides/fluent-api.md)
* [ ] Support for more data types
* [ ] Support for more functions
* [ ] More tests
* [ ] More examples
* [ ] Add a Benchmark project
* [x] More examples — see [Samples](#-samples)
* [x] Add a Benchmark project — see [Benchmarks](#-benchmarks)
* [ ] Create a gRPC server to expose the library as a service

## 📄 Documentation
Expand All @@ -87,6 +96,21 @@ discuss it.

> **Note:** The documentation is generated using [Doraku/DefaultDocumentation]() tool. It is generated automatically when the project is built.

## 📖 Guides

Hand-written guides live in [`docs/guides`](./docs/guides), and every public entry point is catalogued in
[`docs/indicators`](./docs/indicators/README.md).

| Guide | What it covers |
|-------|----------------|
| [🏁 Getting started](./docs/guides/getting-started.md) | Installation, your first indicator, and the three things that trip everyone up: `RetCode`, `BegIdx`/`NBElement` output alignment, and the `double` / `float` / `decimal` story. **Start here.** |
| [✨ Fluent API](./docs/guides/fluent-api.md) | `PriceSeries` in, bar-indexed `IndicatorSeries` out — the layer that does the `BegIdx`/`NBElement` arithmetic for you, with `null` for a bar that has not warmed up. Warm-up semantics, crossings, `AsOf`, the nine shipped indicators and the `Align` escape hatch to the rest. |
| [📋 Indicator catalog](./docs/indicators/README.md) | Every `TAMath` and `TACandle` entry point, grouped by category, with signatures, defaults, outputs and links to the generated API pages. |
| [📡 Real-time streaming](./docs/guides/real-time-streaming.md) | Ticks → bars → indicators over SignalR and raw WebSocket: architecture, message contracts, warm-up semantics and production notes. |
| [📉 Backtesting](./docs/guides/backtesting.md) | The engine model, the structurally enforced no-look-ahead guarantee, the cost model, every metric with its formula, and how to write your own strategy. |
| [📈 TradingView integration](./docs/guides/tradingview-integration.md) | Pine Script `ta.*` → `TAMath` mapping, parity caveats, UDF datafeed and Lightweight Charts wiring, alert-webhook security. |
| [⚡ Benchmarks](./docs/guides/benchmarks.md) | What the benchmark suite measures, how to run it, how to read BenchmarkDotNet output, and the measured results. |

## 📥 Installation

### 📋 Prerequisites
Expand Down Expand Up @@ -130,11 +154,31 @@ dotnet add package Atypical.TechnicalAnalysis.Functions

## 🧑‍💻 Usage

TaLibStandard exposes two APIs on the same indicator: a low-level `TAFunc` API that mirrors the
original TA-Lib C signature (`ref`/`in` parameters, pre-allocated output arrays), and a higher-level
`TAMath` API that wraps it and returns a strongly-typed result record.
TaLibStandard exposes three APIs over the same indicators: a **fluent** API (`PriceSeries` /
`IndicatorSeries`) that hands you values addressed by bar index, a **`TAMath`** API that returns a
strongly-typed result record carrying TA-Lib's raw output array and its alignment metadata, and a
low-level **`TAFunc`** API that mirrors the original TA-Lib C signature (`ref`/`in` parameters,
pre-allocated output arrays).

### High-level API (`TAMath`)
### Fluent API (`PriceSeries` → `IndicatorSeries`)

```csharp
using TechnicalAnalysis.Functions;

PriceSeries prices = PriceSeries.FromHlc(highs, lows, closes);

double? rsi = prices.Rsi(14).Latest; // null until the indicator has warmed up
double? atr = prices.Atr(14).Latest;

IndicatorSeries fast = prices.Sma(5);
IndicatorSeries slow = prices.Sma(20);
bool goldenCross = fast.CrossedAbove(slow, bar: prices.BarCount - 1);
```

Every index is a **bar** index, and a bar the indicator has not reached yet is `null` — never `0.0`.
See the [fluent API guide](./docs/guides/fluent-api.md).

### `TAMath` — the raw result record

```csharp
using TechnicalAnalysis.Functions;
Expand All @@ -144,9 +188,11 @@ double[] closingPrices = [.. /* your OHLCV data */];
// RsiResult exposes RetCode, BegIdx, NBElement and the Real[] output array
RsiResult rsi = TAMath.Rsi(0, closingPrices.Length - 1, closingPrices, timePeriod: 14);

if (rsi.RetCode == RetCode.Success)
if (rsi.RetCode == RetCode.Success && rsi.NBElement > 0)
{
double latestRsi = rsi.Real[^1]; // most recent RSI value
// The newest value is at array index NBElement - 1, and it describes
// bar BegIdx + NBElement - 1. Those are two different numbers.
double latestRsi = rsi.Real[rsi.NBElement - 1];
}
```

Expand Down Expand Up @@ -187,6 +233,54 @@ inputs. See the [full function list](./docs/functions.md) for every available in
candlestick pattern, and the [Demo.BlazorWasm](./Demo.BlazorWasm) project for a working end-to-end
example that charts these indicators.

> **One rule to internalise before anything else.** `TAMath` fills its output array from index `0`, not
> from the input index it corresponds to. Output element `k` describes **input index `BegIdx + k`**, for
> `k` in `[0, NBElement)`; everything from `NBElement` onwards is a meaningless zero. Getting this wrong
> shifts every signal in time, silently. The [getting started guide](./docs/guides/getting-started.md)
> works through it with a hand-checkable example, and the
> [fluent API](./docs/guides/fluent-api.md) does the arithmetic for you in one tested place.

## 🧩 Samples

Runnable projects, all completely offline — no market data provider, no API key, no network calls.

| Sample | Run it | Guide |
|--------|--------|-------|
| [**Real-time streaming**](./samples/TechnicalAnalysis.Samples.RealTime)<br/>ASP.NET Core server: synthetic tick feed → OHLCV bars → seven indicators (eleven series) per closed bar, published over a SignalR hub *and* a raw WebSocket, plus a zero-dependency browser dashboard. | `dotnet run --project samples/TechnicalAnalysis.Samples.RealTime -c Release`<br/>then open <http://localhost:5199> | [📡 Real-time streaming](./docs/guides/real-time-streaming.md) |
| [**Real-time console client**](./samples/TechnicalAnalysis.Samples.RealTime.Client)<br/>SignalR client for the server above; exercises both the group-push and the server-streaming paths. | `dotnet run --project samples/TechnicalAnalysis.Samples.RealTime.Client -c Release -- --symbol GLOBEX` | [📡 Real-time streaming](./docs/guides/real-time-streaming.md) |
| [**Backtesting**](./samples/TechnicalAnalysis.Samples.Backtesting)<br/>Bar-by-bar engine with a structurally enforced no-look-ahead guarantee, a commission/slippage cost model, a full metrics suite and five strategies compared side by side. | `dotnet run --project samples/TechnicalAnalysis.Samples.Backtesting -c Release` | [📉 Backtesting](./docs/guides/backtesting.md) |
| [**Blazor WebAssembly demo**](./Demo.BlazorWasm)<br/>Interactive browser demo charting the indicators. | `dotnet run --project Demo.BlazorWasm` | — |

## ⚡ Benchmarks

[`benchmarks/TechnicalAnalysis.Benchmarks`](./benchmarks/TechnicalAnalysis.Benchmarks) is a
BenchmarkDotNet suite of **119 benchmarks** over deterministic synthetic market data at three series
lengths (1 000 / 10 000 / 100 000), all with `[MemoryDiagnoser]`. Every indicator in the overlap,
momentum and volatility/volume suites is measured **twice** — once through the allocation-free `TAFunc`
API and once through the ergonomic `TAMath` API — so the cost of convenience is a number rather than a
guess. Candlestick patterns are measured on `double`, `float` **and** `decimal` to price the
generic-math design.

```shell
# see what is there, without running anything
dotnet run --project benchmarks/TechnicalAnalysis.Benchmarks -c Release -- --list flat

# prove every benchmark computes something valid (fast; not a measurement)
dotnet run --project benchmarks/TechnicalAnalysis.Benchmarks -c Release -- --selfcheck

# one suite
dotnet run --project benchmarks/TechnicalAnalysis.Benchmarks -c Release -- --anyCategories Momentum
```

An optional sixth suite compares the managed port head to head against the original TA-Lib C library
through P/Invoke, with an equivalence assertion that runs *before* anything is timed. It is enabled
automatically when the native library is found and silently skipped when it is not, so the suite has no
native dependency.

See the [benchmarks guide](./docs/guides/benchmarks.md) for the full switch reference, the native
install instructions per platform, how to read every output column, the measured results and the
methodology caveats.

## 📊 Code Quality

We strive for the highest code quality in TaLibStandard, leveraging Codacy—an automated code analysis/quality tool. Codacy provides static analysis, cyclomatic complexity measures, duplication identification, and code unit test coverage changes for every commit and pull request.
Expand Down
Loading
Loading