mirror of
https://github.com/mihakralj/QuanTAlib.git
synced 2026-08-03 19:57:44 +00:00
fix(python): critical bug fixes across Python wrapper
This commit is contained in:
+69
-21
@@ -1,30 +1,78 @@
|
||||
# quantalib (Python NativeAOT wrapper)
|
||||
# quantalib — Python NativeAOT Wrapper
|
||||
|
||||
Skeleton package and NativeAOT project scaffolding for the `quantalib` Python wrapper over QuanTAlib.
|
||||
High-performance Python wrapper for [QuanTAlib](https://github.com/mihakralj/quantalib), a .NET NativeAOT technical analysis library.
|
||||
|
||||
## Current status
|
||||
## Features
|
||||
|
||||
This is a **skeleton-only** implementation containing:
|
||||
- **~391 indicators** across 15 categories: channels, core, cycles, dynamics, errors, filters, momentum, numerics, oscillators, reversals, statistics, trends (FIR & IIR), volatility, volume
|
||||
- **Zero-copy FFI** — ctypes bridge to pre-compiled NativeAOT shared library
|
||||
- **NumPy native** — all inputs/outputs are `float64` arrays
|
||||
- **Optional pandas support** — pass `pd.Series` in, get `pd.Series` out with preserved index
|
||||
- **pandas-ta compatible** — `quantalib._compat` provides alias mapping for drop-in migration
|
||||
|
||||
- NativeAOT project files (`python.csproj`, `Directory.Build.props`)
|
||||
- Python packaging metadata (`pyproject.toml`)
|
||||
- Python package layout (`quantalib/`)
|
||||
- Loader and bridge stubs (`_loader.py`, `_bridge.py`)
|
||||
- Native artifact placeholders (`quantalib/native/...`)
|
||||
- Minimal smoke test scaffold (`tests/test_smoke.py`)
|
||||
- Native export scaffolding (`src/StatusCodes.cs`, `src/ArrayBridge.cs`, `src/Exports.cs`)
|
||||
## Installation
|
||||
|
||||
## Not included yet
|
||||
```bash
|
||||
pip install quantalib
|
||||
```
|
||||
|
||||
- Full indicator export implementation
|
||||
- Full ctypes signatures for all exports
|
||||
- Indicator wrappers in `indicators.py`
|
||||
- Complete test matrix and compatibility suite
|
||||
> **Note:** The NativeAOT shared library (`quantalib_native.dll` / `.so` / `.dylib`) must be present in `quantalib/native/<platform>/`. Pre-built binaries are included in wheel distributions.
|
||||
|
||||
## Local dev
|
||||
## Quick Start
|
||||
|
||||
From `python/`:
|
||||
```python
|
||||
import numpy as np
|
||||
import quantalib as qtl
|
||||
|
||||
- Create venv and install deps
|
||||
- Run tests: `pytest`
|
||||
- Build wheel: `python -m build`
|
||||
close = np.random.randn(200).cumsum() + 100
|
||||
|
||||
# Simple Moving Average
|
||||
sma = qtl.sma(close, length=20)
|
||||
|
||||
# Bollinger Bands (multi-output → tuple or DataFrame)
|
||||
upper, mid, lower = qtl.bbands(close, length=20, std=2.0)
|
||||
|
||||
# With pandas
|
||||
import pandas as pd
|
||||
s = pd.Series(close, name="close")
|
||||
rsi = qtl.rsi(s, length=14) # returns pd.Series with preserved index
|
||||
```
|
||||
|
||||
## Categories
|
||||
|
||||
| Category | Module | Examples |
|
||||
|----------|--------|----------|
|
||||
| Channels | `channels` | bbands, kchannel, dchannel, aberr |
|
||||
| Core | `core` | ha, midpoint, avgprice, typprice |
|
||||
| Cycles | `cycles` | ht_dcperiod, ht_sine, cg, dsp |
|
||||
| Dynamics | `dynamics` | adx, aroon, ichimoku, supertrend |
|
||||
| Errors | `errors` | mse, rmse, mae, mape, huber |
|
||||
| Filters | `filters` | kalman, sgf, hp, butter2, wavelet |
|
||||
| Momentum | `momentum` | rsi, macd, roc, mom, tsi |
|
||||
| Numerics | `numerics` | fft, normalize, sigmoid, slope |
|
||||
| Oscillators | `oscillators` | stoch, cci, fisher, qqe, willr |
|
||||
| Reversals | `reversals` | psar, pivot, fractals, swings |
|
||||
| Statistics | `statistics` | zscore, correlation, entropy, linreg |
|
||||
| Trends FIR | `trends_fir` | sma, wma, hma, alma, trima |
|
||||
| Trends IIR | `trends_iir` | ema, dema, tema, kama, jma |
|
||||
| Volatility | `volatility` | atr, bbw, stddev, hv, tr |
|
||||
| Volume | `volume` | obv, vwma, mfi, cmf, adl |
|
||||
|
||||
## Local Development
|
||||
|
||||
```bash
|
||||
cd python/
|
||||
python -m venv .venv && .venv/Scripts/activate # or source .venv/bin/activate
|
||||
pip install -e ".[dev]"
|
||||
pytest
|
||||
```
|
||||
|
||||
### Building the native library
|
||||
|
||||
```bash
|
||||
dotnet publish python.csproj -c Release
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
[MIT](../LICENSE)
|
||||
|
||||
@@ -7,8 +7,34 @@ name = "quantalib"
|
||||
dynamic = ["version"]
|
||||
description = "High-performance technical analysis wrappers over QuanTAlib NativeAOT"
|
||||
readme = "README.md"
|
||||
license = "MIT"
|
||||
requires-python = ">=3.10"
|
||||
dependencies = ["numpy>=1.24"]
|
||||
authors = [
|
||||
{ name = "QuanTAlib Contributors" },
|
||||
]
|
||||
keywords = ["quantitative", "finance", "technical-analysis", "indicators", "nativeaot"]
|
||||
classifiers = [
|
||||
"Development Status :: 4 - Beta",
|
||||
"Intended Audience :: Financial and Insurance Industry",
|
||||
"Intended Audience :: Science/Research",
|
||||
"License :: OSI Approved :: MIT License",
|
||||
"Operating System :: OS Independent",
|
||||
"Programming Language :: Python :: 3",
|
||||
"Programming Language :: Python :: 3.10",
|
||||
"Programming Language :: Python :: 3.11",
|
||||
"Programming Language :: Python :: 3.12",
|
||||
"Programming Language :: Python :: 3.13",
|
||||
"Topic :: Office/Business :: Financial :: Investment",
|
||||
"Topic :: Scientific/Engineering :: Mathematics",
|
||||
"Typing :: Typed",
|
||||
]
|
||||
|
||||
[project.urls]
|
||||
Homepage = "https://github.com/mihakralj/quantalib"
|
||||
Repository = "https://github.com/mihakralj/quantalib"
|
||||
Documentation = "https://mihakralj.github.io/quantalib/"
|
||||
Issues = "https://github.com/mihakralj/quantalib/issues"
|
||||
|
||||
[project.optional-dependencies]
|
||||
pandas = ["pandas>=1.5"]
|
||||
|
||||
@@ -11,6 +11,11 @@
|
||||
<EnableDefaultCompileItems>false</EnableDefaultCompileItems>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)' == 'Release'">
|
||||
<DebugSymbols>false</DebugSymbols>
|
||||
<DebugType>none</DebugType>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Include="src\**\*.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
@@ -6,6 +6,9 @@ Usage::
|
||||
|
||||
result = qtl.sma(close_array, length=14)
|
||||
result = qtl.bbands(close_array, length=20, std=2.0)
|
||||
|
||||
print(qtl.version) # e.g. "0.8.0"
|
||||
print(qtl.__version__) # same
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
@@ -14,6 +17,26 @@ from pathlib import Path
|
||||
from ._loader import load_native_library
|
||||
from . import indicators
|
||||
from .indicators import * # noqa: F401, F403 — re-export all indicator functions
|
||||
|
||||
# Re-export per-category submodules for direct access
|
||||
from . import ( # noqa: F401
|
||||
channels,
|
||||
core,
|
||||
cycles,
|
||||
dynamics,
|
||||
errors,
|
||||
filters,
|
||||
momentum,
|
||||
numerics,
|
||||
oscillators,
|
||||
reversals,
|
||||
statistics,
|
||||
trends_fir,
|
||||
trends_iir,
|
||||
volatility,
|
||||
volume,
|
||||
)
|
||||
|
||||
from ._compat import ALIASES, get_compat
|
||||
from ._bridge import (
|
||||
QtlError,
|
||||
@@ -26,6 +49,21 @@ from ._bridge import (
|
||||
__all__ = [
|
||||
"load_native_library",
|
||||
"indicators",
|
||||
"channels",
|
||||
"core",
|
||||
"cycles",
|
||||
"dynamics",
|
||||
"errors",
|
||||
"filters",
|
||||
"momentum",
|
||||
"numerics",
|
||||
"oscillators",
|
||||
"reversals",
|
||||
"statistics",
|
||||
"trends_fir",
|
||||
"trends_iir",
|
||||
"volatility",
|
||||
"volume",
|
||||
"ALIASES",
|
||||
"get_compat",
|
||||
"QtlError",
|
||||
@@ -33,14 +71,35 @@ __all__ = [
|
||||
"QtlInvalidLengthError",
|
||||
"QtlInvalidParamError",
|
||||
"QtlInternalError",
|
||||
"version",
|
||||
"__version__",
|
||||
]
|
||||
|
||||
|
||||
def _resolve_version() -> str:
|
||||
version_file = Path(__file__).resolve().parents[2] / "lib" / "VERSION"
|
||||
if version_file.exists():
|
||||
version = version_file.read_text(encoding="utf-8").strip()
|
||||
if version:
|
||||
return version
|
||||
"""Resolve version from lib/VERSION (dev) or package metadata (installed)."""
|
||||
# 1. Try repo-local VERSION file (works in dev / editable install)
|
||||
pkg_dir = Path(__file__).resolve().parent # python/quantalib/
|
||||
candidates = [
|
||||
pkg_dir.parents[1] / "lib" / "VERSION", # repo root / lib / VERSION
|
||||
pkg_dir.parent / "lib" / "VERSION", # python / lib / VERSION (fallback)
|
||||
pkg_dir / "VERSION", # baked into wheel
|
||||
]
|
||||
for vf in candidates:
|
||||
if vf.is_file():
|
||||
ver = vf.read_text(encoding="utf-8").strip()
|
||||
if ver:
|
||||
return ver
|
||||
|
||||
# 2. Fall back to importlib.metadata (pip-installed wheel)
|
||||
try:
|
||||
from importlib.metadata import version as _pkg_version
|
||||
return _pkg_version("quantalib")
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
return "0.0.0"
|
||||
|
||||
|
||||
__version__ = _resolve_version()
|
||||
__version__: str = _resolve_version()
|
||||
version: str = __version__
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+441
-179
@@ -1,5 +1,7 @@
|
||||
"""Low-level ctypes bindings for every quantalib NativeAOT export.
|
||||
|
||||
Auto-generated by generate_category_modules.py — DO NOT EDIT.
|
||||
|
||||
Each native function is bound via ``_bind`` at module load. If the shared
|
||||
library was compiled without a particular export the binding is silently
|
||||
skipped (the corresponding ``HAS_*`` flag stays False).
|
||||
@@ -66,41 +68,10 @@ _lib = load_native_library()
|
||||
# Shorthand type aliases
|
||||
_dp = POINTER(c_double) # double*
|
||||
_ip = POINTER(c_int) # int*
|
||||
_lp = POINTER(ctypes.c_long) # long*
|
||||
_ci = c_int
|
||||
_cd = c_double
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# ABI signature pattern templates
|
||||
#
|
||||
# Pattern A : (src*, n, dst*, period) → single-input + int
|
||||
# Pattern A2: (src*, n, dst*, alpha) → single-input + double
|
||||
# Pattern A3: (src*, n, dst*) → single-input no params
|
||||
# Pattern B : (h*, l*, c*, v*, n, dst*, period) → HLCV + int
|
||||
# Pattern C : (o*, h*, l*, c*, n, dst*) → OHLC no extra
|
||||
# Pattern C2: (o*, h*, l*, c*, n, dst*, double) → OHLC + double
|
||||
# Pattern D : (h*, l*, n, dst*) → HL
|
||||
# Pattern E : (h*, l*, c*, n, dst*) → HLC
|
||||
# Pattern F : (actual*, predicted*, n, dst*, period) → dual-input + int
|
||||
# Pattern G : (src*, vol*, n, dst*) → source+volume
|
||||
# Pattern G2: (src*, vol*, n, dst*, period) → source+volume+int
|
||||
# Pattern H : (x*, y*, n, dst*, period) → X+Y + int
|
||||
# Pattern I : multi-output (various)
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
# Common argtypes per pattern
|
||||
_PA = [_dp, _ci, _dp, _ci] # Pattern A
|
||||
_PA2 = [_dp, _ci, _dp, _cd] # Pattern A (alpha)
|
||||
_PA3 = [_dp, _ci, _dp] # Pattern A (no param)
|
||||
_PB = [_dp, _dp, _dp, _dp, _ci, _dp, _ci] # Pattern B (HLCV)
|
||||
_PC = [_dp, _dp, _dp, _dp, _ci, _dp] # Pattern C (OHLC)
|
||||
_PC2 = [_dp, _dp, _dp, _dp, _ci, _dp, _cd] # Pattern C (OHLC+double)
|
||||
_PD = [_dp, _dp, _ci, _dp] # Pattern D (HL)
|
||||
_PE = [_dp, _dp, _dp, _ci, _dp] # Pattern E (HLC)
|
||||
_PF = [_dp, _dp, _ci, _dp, _ci] # Pattern F
|
||||
_PG = [_dp, _dp, _ci, _dp] # Pattern G
|
||||
_PG2 = [_dp, _dp, _ci, _dp, _ci] # Pattern G2
|
||||
_PH = [_dp, _dp, _ci, _dp, _ci] # Pattern H
|
||||
|
||||
|
||||
def _bind(name: str, argtypes: list[object]) -> bool:
|
||||
"""Bind a single native function. Returns True if found."""
|
||||
@@ -118,187 +89,478 @@ def _bind(name: str, argtypes: list[object]) -> bool:
|
||||
HAS_SKELETON = _bind("qtl_skeleton_noop", [_dp, _ci, _dp])
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════════════════
|
||||
# §8.1 Core
|
||||
# Core (Exports.Generated.cs)
|
||||
# ═══════════════════════════════════════════════════════════════════════════
|
||||
HAS_AVGPRICE = _bind("qtl_avgprice", _PC)
|
||||
HAS_MEDPRICE = _bind("qtl_medprice", _PD)
|
||||
HAS_TYPPRICE = _bind("qtl_typprice", [_dp, _dp, _dp, _ci, _dp]) # OHL (no close!)
|
||||
HAS_MIDBODY = _bind("qtl_midbody", [_dp, _dp, _ci, _dp]) # OC
|
||||
HAS_HA = _bind("qtl_ha", [_dp, _dp, _dp, _dp, _dp, _dp, _dp, _dp, _ci])
|
||||
HAS_MIDPOINT = _bind("qtl_midpoint", [_dp, _dp, _ci, _ci])
|
||||
HAS_MIDPRICE = _bind("qtl_midprice", [_dp, _dp, _dp, _ci, _ci])
|
||||
HAS_WCLPRICE = _bind("qtl_wclprice", [_dp, _dp, _dp, _dp, _ci])
|
||||
|
||||
# ── Core (Exports.cs — manual) ──
|
||||
HAS_AVGPRICE = _bind("qtl_avgprice", [_dp, _dp, _dp, _dp, _ci, _dp])
|
||||
HAS_MEDPRICE = _bind("qtl_medprice", [_dp, _dp, _ci, _dp])
|
||||
HAS_TYPPRICE = _bind("qtl_typprice", [_dp, _dp, _dp, _ci, _dp])
|
||||
HAS_MIDBODY = _bind("qtl_midbody", [_dp, _dp, _ci, _dp])
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════════════════
|
||||
# §8.2 Momentum
|
||||
# Momentum
|
||||
# ═══════════════════════════════════════════════════════════════════════════
|
||||
HAS_RSI = _bind("qtl_rsi", _PA)
|
||||
HAS_ROC = _bind("qtl_roc", _PA)
|
||||
HAS_MOM = _bind("qtl_mom", _PA)
|
||||
HAS_CMO = _bind("qtl_cmo", _PA)
|
||||
HAS_TSI = _bind("qtl_tsi", [_dp, _ci, _dp, _ci, _ci]) # longP, shortP
|
||||
HAS_APO = _bind("qtl_apo", [_dp, _ci, _dp, _ci, _ci]) # fast, slow
|
||||
HAS_BIAS = _bind("qtl_bias", _PA)
|
||||
HAS_CFO = _bind("qtl_cfo", _PA)
|
||||
HAS_CFB = _bind("qtl_cfb", [_dp, _ci, _dp, _ip, _ci]) # special
|
||||
HAS_ASI = _bind("qtl_asi", _PC2) # OHLC + double limit
|
||||
HAS_BOP = _bind("qtl_bop", [_dp, _dp, _dp, _dp, _dp, _ci])
|
||||
HAS_CCI = _bind("qtl_cci", [_dp, _dp, _dp, _dp, _dp, _ci, _ci, _dp])
|
||||
HAS_MACD = _bind("qtl_macd", [_dp, _dp, _ci, _ci, _ci])
|
||||
HAS_PMO = _bind("qtl_pmo", [_dp, _dp, _ci, _ci, _ci, _ci])
|
||||
HAS_PPO = _bind("qtl_ppo", [_dp, _dp, _ci, _ci, _ci])
|
||||
HAS_PRS = _bind("qtl_prs", [_dp, _dp, _dp, _ci, _ci])
|
||||
HAS_ROCP = _bind("qtl_rocp", [_dp, _dp, _ci, _ci])
|
||||
HAS_ROCR = _bind("qtl_rocr", [_dp, _dp, _ci, _ci])
|
||||
HAS_SAM = _bind("qtl_sam", [_dp, _dp, _ci, _cd, _ci])
|
||||
HAS_VEL = _bind("qtl_vel", [_dp, _dp, _ci, _ci])
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════════════════
|
||||
# §8.3 Oscillators
|
||||
# Oscillators
|
||||
# ═══════════════════════════════════════════════════════════════════════════
|
||||
HAS_FISHER = _bind("qtl_fisher", _PA)
|
||||
HAS_FISHER04 = _bind("qtl_fisher04", _PA)
|
||||
HAS_DPO = _bind("qtl_dpo", _PA)
|
||||
HAS_TRIX = _bind("qtl_trix", _PA)
|
||||
HAS_INERTIA = _bind("qtl_inertia", _PA)
|
||||
HAS_RSX = _bind("qtl_rsx", _PA)
|
||||
HAS_ER = _bind("qtl_er", _PA)
|
||||
HAS_CTI = _bind("qtl_cti", _PA)
|
||||
HAS_REFLEX = _bind("qtl_reflex", _PA)
|
||||
HAS_TRENDFLEX = _bind("qtl_trendflex", _PA)
|
||||
HAS_KRI = _bind("qtl_kri", _PA)
|
||||
HAS_PSL = _bind("qtl_psl", _PA)
|
||||
HAS_DECO = _bind("qtl_deco", [_dp, _ci, _dp, _ci, _ci]) # shortP, longP
|
||||
HAS_DOSC = _bind("qtl_dosc", [_dp, _ci, _dp, _ci, _ci, _ci, _ci]) # rsiP, ema1P, ema2P, sigP
|
||||
HAS_DYMOI = _bind("qtl_dymoi", [_dp, _ci, _dp, _ci, _ci, _ci, _ci, _ci]) # p1..p5
|
||||
HAS_CRSI = _bind("qtl_crsi", [_dp, _ci, _dp, _ci, _ci, _ci]) # rsiP, streakP, rankP
|
||||
HAS_BBB = _bind("qtl_bbb", [_dp, _ci, _dp, _ci, _cd]) # period, mult
|
||||
HAS_BBI = _bind("qtl_bbi", [_dp, _ci, _dp, _ci, _ci, _ci, _ci]) # p1..p4
|
||||
HAS_DEM = _bind("qtl_dem", [_dp, _dp, _ci, _dp, _ci]) # high,low,n,dst,period
|
||||
HAS_BRAR = _bind("qtl_brar", [_dp, _dp, _dp, _dp, _ci, _dp, _dp, _ci]) # OHLC + 2 outputs + period
|
||||
HAS_AC = _bind("qtl_ac", [_dp, _dp, _dp, _ci, _ci, _ci, _ci])
|
||||
HAS_AO = _bind("qtl_ao", [_dp, _dp, _dp, _ci, _ci, _ci])
|
||||
HAS_BBS = _bind("qtl_bbs", [_dp, _dp, _dp, _dp, _ci, _ci, _cd])
|
||||
HAS_COPPOCK = _bind("qtl_coppock", [_dp, _dp, _ci, _ci, _ci, _ci])
|
||||
HAS_ERI = _bind("qtl_eri", [_dp, _ci, _ci, _dp])
|
||||
HAS_FI = _bind("qtl_fi", [_dp, _ci, _ci, _dp])
|
||||
HAS_GATOR = _bind("qtl_gator", [_dp, _dp, _ci, _ci, _ci, _ci, _ci, _ci, _ci])
|
||||
HAS_IMI = _bind("qtl_imi", [_dp, _dp, _dp, _dp, _dp, _ci, _ci, _dp])
|
||||
HAS_KDJ = _bind("qtl_kdj", [_dp, _dp, _dp, _dp, _dp, _dp, _ci, _ci, _ci])
|
||||
HAS_KST = _bind("qtl_kst", [_dp, _dp, _dp, _ci, _ci, _ci, _ci, _ci, _ci, _ci, _ci, _ci, _ci])
|
||||
HAS_MARKETFI = _bind("qtl_marketfi", [_dp, _dp, _dp, _dp, _ci])
|
||||
HAS_MSTOCH = _bind("qtl_mstoch", [_dp, _dp, _ci, _ci, _ci, _ci])
|
||||
HAS_PGO = _bind("qtl_pgo", [_dp, _dp, _dp, _dp, _ci, _ci])
|
||||
HAS_QQE = _bind("qtl_qqe", [_dp, _dp, _ci, _ci, _ci, _cd])
|
||||
HAS_REVERSEEMA = _bind("qtl_reverseema", [_dp, _dp, _ci, _ci])
|
||||
HAS_RVGI = _bind("qtl_rvgi", [_dp, _dp, _dp, _dp, _dp, _dp, _ci, _ci])
|
||||
HAS_SMI = _bind("qtl_smi", [_dp, _dp, _dp, _dp, _dp, _ci, _ci, _ci, _ci, _ci])
|
||||
HAS_SQUEEZE = _bind("qtl_squeeze", [_dp, _dp, _dp, _dp, _dp, _ci, _ci, _cd, _cd])
|
||||
HAS_STC = _bind("qtl_stc", [_dp, _dp, _ci, _ci, _ci, _ci, _ci, _ci])
|
||||
HAS_STOCH = _bind("qtl_stoch", [_dp, _dp, _dp, _dp, _dp, _ci, _ci, _ci])
|
||||
HAS_STOCHF = _bind("qtl_stochf", [_dp, _dp, _dp, _dp, _dp, _ci, _ci, _ci])
|
||||
HAS_STOCHRSI = _bind("qtl_stochrsi", [_dp, _dp, _ci, _ci, _ci, _ci, _ci])
|
||||
HAS_TTMWAVE = _bind("qtl_ttmwave", [_dp, _ci, _dp])
|
||||
HAS_ULTOSC = _bind("qtl_ultosc", [_dp, _dp, _dp, _dp, _ci, _ci, _ci, _ci])
|
||||
HAS_WILLR = _bind("qtl_willr", [_dp, _dp, _dp, _dp, _ci, _ci])
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════════════════
|
||||
# §8.4 Trends — FIR
|
||||
# Trends — FIR
|
||||
# ═══════════════════════════════════════════════════════════════════════════
|
||||
HAS_SMA = _bind("qtl_sma", _PA)
|
||||
HAS_WMA = _bind("qtl_wma", _PA)
|
||||
HAS_HMA = _bind("qtl_hma", _PA)
|
||||
HAS_TRIMA = _bind("qtl_trima", _PA)
|
||||
HAS_SWMA = _bind("qtl_swma", _PA)
|
||||
HAS_DWMA = _bind("qtl_dwma", _PA)
|
||||
HAS_BLMA = _bind("qtl_blma", _PA)
|
||||
HAS_ALMA = _bind("qtl_alma", [_dp, _ci, _dp, _ci, _cd, _cd]) # period, offset, sigma
|
||||
HAS_LSMA = _bind("qtl_lsma", _PA)
|
||||
HAS_SGMA = _bind("qtl_sgma", _PA)
|
||||
HAS_SINEMA = _bind("qtl_sinema", _PA)
|
||||
HAS_HANMA = _bind("qtl_hanma", _PA)
|
||||
HAS_PARZEN = _bind("qtl_parzen", _PA)
|
||||
HAS_TSF = _bind("qtl_tsf", _PA)
|
||||
HAS_CONV = _bind("qtl_conv", [_dp, _ci, _dp, _dp, _ci]) # src,n,dst,kernel*,kernelLen
|
||||
HAS_BWMA = _bind("qtl_bwma", [_dp, _ci, _dp, _ci, _ci]) # period, polyOrder
|
||||
HAS_CRMA = _bind("qtl_crma", [_dp, _ci, _dp, _ci, _cd]) # period, volumeFactor
|
||||
HAS_SP15 = _bind("qtl_sp15", _PA)
|
||||
HAS_TUKEY_W = _bind("qtl_tukey_w", _PA)
|
||||
HAS_RAIN = _bind("qtl_rain", _PA)
|
||||
HAS_AFIRMA = _bind("qtl_afirma", [_dp, _ci, _dp, _ci, _ci, _ci]) # src,n,dst,period,windowType,useSimd
|
||||
HAS_FWMA = _bind("qtl_fwma", [_dp, _dp, _ci, _ci])
|
||||
HAS_GWMA = _bind("qtl_gwma", [_dp, _dp, _ci, _ci, _cd])
|
||||
HAS_HAMMA = _bind("qtl_hamma", [_dp, _dp, _ci, _ci])
|
||||
HAS_HEND = _bind("qtl_hend", [_dp, _dp, _ci, _ci, _cd])
|
||||
HAS_ILRS = _bind("qtl_ilrs", [_dp, _dp, _ci, _ci])
|
||||
HAS_KAISER = _bind("qtl_kaiser", [_dp, _dp, _ci, _ci, _cd, _cd])
|
||||
HAS_LANCZOS = _bind("qtl_lanczos", [_dp, _dp, _ci, _ci, _cd])
|
||||
HAS_NLMA = _bind("qtl_nlma", [_dp, _dp, _ci, _ci])
|
||||
HAS_NYQMA = _bind("qtl_nyqma", [_dp, _dp, _ci, _ci, _ci])
|
||||
HAS_PMA = _bind("qtl_pma", [_dp, _dp, _dp, _ci, _ci])
|
||||
HAS_PWMA = _bind("qtl_pwma", [_dp, _dp, _ci, _ci])
|
||||
HAS_QRMA = _bind("qtl_qrma", [_dp, _dp, _ci, _ci, _cd])
|
||||
HAS_RWMA = _bind("qtl_rwma", [_dp, _dp, _dp, _dp, _ci, _ci])
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════════════════
|
||||
# §8.5 Trends — IIR
|
||||
# Trends — IIR
|
||||
# ═══════════════════════════════════════════════════════════════════════════
|
||||
HAS_EMA = _bind("qtl_ema", _PA)
|
||||
HAS_EMA_ALPHA = _bind("qtl_ema_alpha", _PA2)
|
||||
HAS_DEMA = _bind("qtl_dema", _PA)
|
||||
HAS_DEMA_ALPHA = _bind("qtl_dema_alpha", _PA2)
|
||||
HAS_TEMA = _bind("qtl_tema", _PA)
|
||||
HAS_LEMA = _bind("qtl_lema", _PA)
|
||||
HAS_HEMA = _bind("qtl_hema", _PA)
|
||||
HAS_AHRENS = _bind("qtl_ahrens", _PA)
|
||||
HAS_DECYCLER = _bind("qtl_decycler", _PA)
|
||||
HAS_DSMA = _bind("qtl_dsma", [_dp, _ci, _dp, _ci, _cd]) # period, factor
|
||||
HAS_GDEMA = _bind("qtl_gdema", [_dp, _ci, _dp, _ci, _cd]) # period, factor
|
||||
HAS_CORAL = _bind("qtl_coral", [_dp, _ci, _dp, _ci, _cd]) # period, friction
|
||||
HAS_AGC = _bind("qtl_agc", _PA2) # alpha
|
||||
HAS_CCYC = _bind("qtl_ccyc", _PA2) # alpha
|
||||
HAS_ADXVMA = _bind("qtl_adxvma", [_dp, _dp, _dp, _dp, _dp, _ci, _ci, _dp])
|
||||
HAS_FRAMA = _bind("qtl_frama", [_dp, _dp, _ci, _ci])
|
||||
HAS_HOLT = _bind("qtl_holt", [_dp, _dp, _ci, _ci, _cd])
|
||||
HAS_HTIT = _bind("qtl_htit", [_dp, _dp, _ci])
|
||||
HAS_HWMA = _bind("qtl_hwma", [_dp, _dp, _ci, _ci])
|
||||
HAS_JMA = _bind("qtl_jma", [_dp, _dp, _ci, _ci, _ci, _cd])
|
||||
HAS_KAMA = _bind("qtl_kama", [_dp, _dp, _ci, _ci, _ci, _ci])
|
||||
HAS_LTMA = _bind("qtl_ltma", [_dp, _dp, _ci, _ci])
|
||||
HAS_MAMA = _bind("qtl_mama", [_dp, _dp, _cd, _ci, _cd, _dp])
|
||||
HAS_MAVP = _bind("qtl_mavp", [_dp, _dp, _dp, _ci, _ci, _ci])
|
||||
HAS_MCNMA = _bind("qtl_mcnma", [_dp, _dp, _ci, _ci])
|
||||
HAS_MGDI = _bind("qtl_mgdi", [_dp, _dp, _ci, _ci, _cd])
|
||||
HAS_MMA = _bind("qtl_mma", [_dp, _dp, _ci, _ci])
|
||||
HAS_NMA = _bind("qtl_nma", [_dp, _dp, _ci, _ci])
|
||||
HAS_QEMA = _bind("qtl_qema", [_dp, _dp, _ci, _ci])
|
||||
HAS_REMA = _bind("qtl_rema", [_dp, _dp, _ci, _ci, _cd])
|
||||
HAS_RGMA = _bind("qtl_rgma", [_dp, _dp, _ci, _ci, _ci])
|
||||
HAS_RMA = _bind("qtl_rma", [_dp, _dp, _ci, _ci])
|
||||
HAS_T3 = _bind("qtl_t3", [_dp, _dp, _ci, _ci, _cd])
|
||||
HAS_TRAMA = _bind("qtl_trama", [_dp, _dp, _ci, _ci])
|
||||
HAS_VAMA = _bind("qtl_vama", [_dp, _dp, _dp, _dp, _dp, _ci, _ci, _ci, _ci, _ci, _ci, _dp])
|
||||
HAS_VIDYA = _bind("qtl_vidya", [_dp, _dp, _ci, _ci])
|
||||
HAS_YZVAMA = _bind("qtl_yzvama", [_dp, _dp, _dp, _dp, _dp, _ci, _ci, _ci, _ci, _ci, _ci, _dp])
|
||||
HAS_ZLDEMA = _bind("qtl_zldema", [_dp, _dp, _ci, _ci])
|
||||
HAS_ZLEMA = _bind("qtl_zlema", [_dp, _dp, _ci, _ci])
|
||||
HAS_ZLTEMA = _bind("qtl_zltema", [_dp, _dp, _ci, _ci])
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════════════════
|
||||
# §8.6 Channels
|
||||
# Channels
|
||||
# ═══════════════════════════════════════════════════════════════════════════
|
||||
HAS_BBANDS = _bind("qtl_bbands", [_dp, _ci, _dp, _dp, _dp, _ci, _cd]) # src,n, upper,mid,lower, period,mult
|
||||
HAS_ABBER = _bind("qtl_abber", [_dp, _dp, _dp, _dp, _ci, _ci, _cd]) # src,mid,upper,lower,n,period,mult
|
||||
HAS_ATRBANDS = _bind("qtl_atrbands", [_dp, _dp, _dp, _ci, _dp, _dp, _dp, _ci, _cd]) # h,l,c,n, upper,mid,lower, period,mult
|
||||
HAS_APCHANNEL = _bind("qtl_apchannel", [_dp, _dp, _ci, _dp, _dp, _ci]) # h,l,n, upper,lower, period
|
||||
HAS_ACCBANDS = _bind("qtl_accbands", [_dp, _dp, _dp, _dp, _dp, _dp, _ci, _ci, _cd])
|
||||
HAS_APZ = _bind("qtl_apz", [_dp, _dp, _dp, _dp, _dp, _ci, _cd, _ci, _dp, _dp, _dp])
|
||||
HAS_DCHANNEL = _bind("qtl_dchannel", [_dp, _dp, _dp, _dp, _dp, _ci, _ci])
|
||||
HAS_DECAYCHANNEL = _bind("qtl_decaychannel", [_dp, _dp, _dp, _dp, _dp, _ci, _ci])
|
||||
HAS_FCB = _bind("qtl_fcb", [_dp, _dp, _dp, _dp, _dp, _ci, _ci])
|
||||
HAS_JBANDS = _bind("qtl_jbands", [_dp, _dp, _dp, _dp, _ci, _ci, _ci])
|
||||
HAS_KCHANNEL = _bind("qtl_kchannel", [_dp, _dp, _dp, _dp, _dp, _dp, _ci, _ci, _cd])
|
||||
HAS_MAENV = _bind("qtl_maenv", [_dp, _dp, _dp, _dp, _ci, _ci, _cd, _ci])
|
||||
HAS_MMCHANNEL = _bind("qtl_mmchannel", [_dp, _dp, _dp, _dp, _ci, _ci])
|
||||
HAS_PCHANNEL = _bind("qtl_pchannel", [_dp, _dp, _dp, _dp, _dp, _ci, _ci])
|
||||
HAS_REGCHANNEL = _bind("qtl_regchannel", [_dp, _dp, _dp, _dp, _ci, _ci, _cd])
|
||||
HAS_SDCHANNEL = _bind("qtl_sdchannel", [_dp, _dp, _dp, _dp, _ci, _ci, _cd])
|
||||
HAS_STARCHANNEL = _bind("qtl_starchannel", [_dp, _dp, _dp, _dp, _dp, _dp, _ci, _ci, _cd, _ci])
|
||||
HAS_STBANDS = _bind("qtl_stbands", [_dp, _dp, _dp, _dp, _dp, _dp, _ci, _ci, _cd])
|
||||
HAS_TTMLRC = _bind("qtl_ttmlrc", [_dp, _dp, _dp, _dp, _dp, _dp, _ci, _ci])
|
||||
HAS_UBANDS = _bind("qtl_ubands", [_dp, _dp, _dp, _dp, _ci, _ci, _cd])
|
||||
HAS_UCHANNEL = _bind("qtl_uchannel", [_dp, _dp, _dp, _dp, _dp, _dp, _ci, _ci, _ci, _cd])
|
||||
HAS_VWAPBANDS = _bind("qtl_vwapbands", [_dp, _dp, _dp, _dp, _dp, _dp, _dp, _dp, _ci, _cd])
|
||||
HAS_VWAPSD = _bind("qtl_vwapsd", [_dp, _dp, _dp, _dp, _dp, _dp, _ci, _cd])
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════════════════
|
||||
# §8.7 Volatility
|
||||
# Volatility
|
||||
# ═══════════════════════════════════════════════════════════════════════════
|
||||
HAS_TR = _bind("qtl_tr", _PE) # HLC
|
||||
HAS_BBW = _bind("qtl_bbw", _PA)
|
||||
HAS_BBWN = _bind("qtl_bbwn", [_dp, _ci, _dp, _ci, _cd, _ci]) # period, mult, lookback
|
||||
HAS_BBWP = _bind("qtl_bbwp", [_dp, _ci, _dp, _ci, _cd, _ci]) # period, mult, lookback
|
||||
HAS_STDDEV = _bind("qtl_stddev", _PA)
|
||||
HAS_VARIANCE = _bind("qtl_variance", _PA)
|
||||
HAS_ETHERM = _bind("qtl_etherm", [_dp, _dp, _ci, _dp, _ci]) # high,low,n,dst,period
|
||||
HAS_CCV = _bind("qtl_ccv", [_dp, _ci, _dp, _ci, _ci]) # shortP, longP
|
||||
HAS_CV = _bind("qtl_cv", [_dp, _ci, _dp, _ci, _cd, _cd]) # period, minVol, maxVol
|
||||
HAS_CVI = _bind("qtl_cvi", [_dp, _ci, _dp, _ci, _ci]) # emaPeriod, rocPeriod
|
||||
HAS_EWMA = _bind("qtl_ewma", [_dp, _ci, _dp, _ci, _ci, _ci]) # period, isPop, annFactor
|
||||
HAS_ADR = _bind("qtl_adr", [_dp, _dp, _dp, _dp, _dp, _ci, _ci, _ci, _dp])
|
||||
HAS_ATR = _bind("qtl_atr", [_dp, _dp, _dp, _dp, _dp, _ci, _ci, _dp])
|
||||
HAS_ATRN = _bind("qtl_atrn", [_dp, _dp, _dp, _dp, _dp, _ci, _ci, _dp])
|
||||
HAS_GKV = _bind("qtl_gkv", [_dp, _dp, _dp, _dp, _dp, _ci, _ci, _ci, _ci])
|
||||
HAS_HLV = _bind("qtl_hlv", [_dp, _dp, _dp, _ci, _ci, _ci, _ci])
|
||||
HAS_HV = _bind("qtl_hv", [_dp, _dp, _ci, _ci, _ci, _ci])
|
||||
HAS_JVOLTY = _bind("qtl_jvolty", [_dp, _dp, _ci, _ci])
|
||||
HAS_JVOLTYN = _bind("qtl_jvoltyn", [_dp, _dp, _ci, _ci])
|
||||
HAS_MASSI = _bind("qtl_massi", [_dp, _dp, _ci, _ci, _ci])
|
||||
HAS_NATR = _bind("qtl_natr", [_dp, _dp, _dp, _dp, _dp, _ci, _ci, _dp])
|
||||
HAS_RSV = _bind("qtl_rsv", [_dp, _dp, _dp, _dp, _dp, _ci, _ci, _ci, _ci])
|
||||
HAS_RV = _bind("qtl_rv", [_dp, _dp, _ci, _ci, _ci, _ci, _ci])
|
||||
HAS_RVI = _bind("qtl_rvi", [_dp, _dp, _ci, _ci, _ci])
|
||||
HAS_UI = _bind("qtl_ui", [_dp, _dp, _ci, _ci])
|
||||
HAS_VOV = _bind("qtl_vov", [_dp, _dp, _ci, _ci, _ci])
|
||||
HAS_VR = _bind("qtl_vr", [_dp, _dp, _dp, _dp, _ci, _ci])
|
||||
HAS_YZV = _bind("qtl_yzv", [_dp, _dp, _dp, _dp, _dp, _ci, _ci])
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════════════════
|
||||
# §8.8 Volume
|
||||
# Volume
|
||||
# ═══════════════════════════════════════════════════════════════════════════
|
||||
HAS_OBV = _bind("qtl_obv", _PG) # close,vol,n,dst
|
||||
HAS_PVT = _bind("qtl_pvt", _PG)
|
||||
HAS_PVR = _bind("qtl_pvr", _PG)
|
||||
HAS_VF = _bind("qtl_vf", _PG)
|
||||
HAS_NVI = _bind("qtl_nvi", _PG)
|
||||
HAS_PVI = _bind("qtl_pvi", _PG)
|
||||
HAS_TVI = _bind("qtl_tvi", _PG2) # close,vol,n,dst,period
|
||||
HAS_PVD = _bind("qtl_pvd", _PG2)
|
||||
HAS_VWMA = _bind("qtl_vwma", _PG2)
|
||||
HAS_EVWMA = _bind("qtl_evwma", _PG2)
|
||||
HAS_EFI = _bind("qtl_efi", _PG2)
|
||||
HAS_AOBV = _bind("qtl_aobv", [_dp, _dp, _ci, _dp, _dp]) # close,vol,n,obv,signal
|
||||
HAS_MFI = _bind("qtl_mfi", _PB) # HLCV + period
|
||||
HAS_CMF = _bind("qtl_cmf", _PB)
|
||||
HAS_EOM = _bind("qtl_eom", [_dp, _dp, _dp, _ci, _dp, _ci]) # h,l,v,n,dst,period
|
||||
HAS_PVO = _bind("qtl_pvo", [_dp, _ci, _dp, _dp, _dp, _ci, _ci, _ci]) # vol,n, pvo,signal,hist, fast,slow,signal_p
|
||||
HAS_ADL = _bind("qtl_adl", [_dp, _dp, _dp, _dp, _dp, _ci])
|
||||
HAS_ADOSC = _bind("qtl_adosc", [_dp, _dp, _dp, _dp, _dp, _ci, _ci, _ci])
|
||||
HAS_III = _bind("qtl_iii", [_dp, _dp, _dp, _dp, _dp, _ci, _ci, _ci])
|
||||
HAS_KVO = _bind("qtl_kvo", [_dp, _dp, _dp, _dp, _dp, _dp, _ci, _ci, _ci, _ci])
|
||||
HAS_TWAP = _bind("qtl_twap", [_dp, _dp, _ci, _ci])
|
||||
HAS_VA = _bind("qtl_va", [_dp, _dp, _dp, _dp, _dp, _ci])
|
||||
HAS_VO = _bind("qtl_vo", [_dp, _dp, _ci, _ci, _ci])
|
||||
HAS_VROC = _bind("qtl_vroc", [_dp, _dp, _ci, _ci, _ci])
|
||||
HAS_VWAD = _bind("qtl_vwad", [_dp, _dp, _dp, _dp, _dp, _ci, _ci])
|
||||
HAS_VWAP = _bind("qtl_vwap", [_dp, _dp, _dp, _dp, _dp, _ci, _ci])
|
||||
HAS_WAD = _bind("qtl_wad", [_dp, _dp, _dp, _dp, _dp, _ci])
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════════════════
|
||||
# §8.9 Statistics
|
||||
# Statistics
|
||||
# ═══════════════════════════════════════════════════════════════════════════
|
||||
HAS_ZSCORE = _bind("qtl_zscore", _PA)
|
||||
HAS_CMA = _bind("qtl_cma", _PA3) # no period
|
||||
HAS_ENTROPY = _bind("qtl_entropy", _PA)
|
||||
HAS_CORRELATION = _bind("qtl_correlation", _PH)
|
||||
HAS_COVARIANCE = _bind("qtl_covariance", [_dp, _dp, _ci, _dp, _ci, _ci]) # x,y,n,dst,period,isSample
|
||||
HAS_COINTEGRATION = _bind("qtl_cointegration", _PH)
|
||||
HAS_ACF = _bind("qtl_acf", [_dp, _dp, _ci, _ci, _ci])
|
||||
HAS_GEOMEAN = _bind("qtl_geomean", [_dp, _dp, _ci, _ci])
|
||||
HAS_GRANGER = _bind("qtl_granger", [_dp, _dp, _dp, _ci, _ci])
|
||||
HAS_HARMEAN = _bind("qtl_harmean", [_dp, _dp, _ci, _ci])
|
||||
HAS_HURST = _bind("qtl_hurst", [_dp, _dp, _ci, _ci])
|
||||
HAS_IQR = _bind("qtl_iqr", [_dp, _dp, _ci, _ci])
|
||||
HAS_JB = _bind("qtl_jb", [_dp, _dp, _ci, _ci])
|
||||
HAS_KENDALL = _bind("qtl_kendall", [_dp, _dp, _dp, _ci, _ci])
|
||||
HAS_KURTOSIS = _bind("qtl_kurtosis", [_dp, _dp, _ci, _ci, _ci])
|
||||
HAS_LINREG = _bind("qtl_linreg", [_dp, _dp, _ci, _ci, _ci, _cd])
|
||||
HAS_MEANDEV = _bind("qtl_meandev", [_dp, _dp, _ci, _ci])
|
||||
HAS_MEDIAN = _bind("qtl_median", [_dp, _dp, _ci, _ci])
|
||||
HAS_MODE = _bind("qtl_mode", [_dp, _dp, _ci, _ci])
|
||||
HAS_PACF = _bind("qtl_pacf", [_dp, _dp, _ci, _ci, _ci])
|
||||
HAS_PERCENTILE = _bind("qtl_percentile", [_dp, _dp, _ci, _ci, _cd])
|
||||
HAS_POLYFIT = _bind("qtl_polyfit", [_dp, _dp, _ci, _ci, _ci, _cd])
|
||||
HAS_QUANTILE = _bind("qtl_quantile", [_dp, _dp, _ci, _ci, _cd])
|
||||
HAS_SKEW = _bind("qtl_skew", [_dp, _dp, _ci, _ci, _ci])
|
||||
HAS_SPEARMAN = _bind("qtl_spearman", [_dp, _dp, _dp, _ci, _ci])
|
||||
HAS_STDERR = _bind("qtl_stderr", [_dp, _dp, _ci, _ci])
|
||||
HAS_SUM = _bind("qtl_sum", [_dp, _dp, _ci, _ci])
|
||||
HAS_THEIL = _bind("qtl_theil", [_dp, _dp, _ci, _ci])
|
||||
HAS_TRIM = _bind("qtl_trim", [_dp, _dp, _ci, _ci, _cd])
|
||||
HAS_WAVG = _bind("qtl_wavg", [_dp, _dp, _ci, _ci])
|
||||
HAS_WINS = _bind("qtl_wins", [_dp, _dp, _ci, _ci, _cd])
|
||||
HAS_ZTEST = _bind("qtl_ztest", [_dp, _dp, _ci, _ci, _cd])
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════════════════
|
||||
# §8.10 Errors
|
||||
# Errors
|
||||
# ═══════════════════════════════════════════════════════════════════════════
|
||||
HAS_MSE = _bind("qtl_mse", _PF)
|
||||
HAS_RMSE = _bind("qtl_rmse", _PF)
|
||||
HAS_MAE = _bind("qtl_mae", _PF)
|
||||
HAS_MAPE = _bind("qtl_mape", _PF)
|
||||
HAS_HUBER = _bind("qtl_huber", [_dp, _dp, _dp, _ci, _ci, _cd])
|
||||
HAS_LOGCOSH = _bind("qtl_logcosh", [_dp, _dp, _dp, _ci, _ci])
|
||||
HAS_MAAPE = _bind("qtl_maape", [_dp, _dp, _dp, _ci, _ci])
|
||||
HAS_MAPD = _bind("qtl_mapd", [_dp, _dp, _dp, _ci, _ci])
|
||||
HAS_MASE = _bind("qtl_mase", [_dp, _dp, _dp, _ci, _ci])
|
||||
HAS_MDAE = _bind("qtl_mdae", [_dp, _dp, _dp, _ci, _ci])
|
||||
HAS_MDAPE = _bind("qtl_mdape", [_dp, _dp, _dp, _ci, _ci])
|
||||
HAS_ME = _bind("qtl_me", [_dp, _dp, _dp, _ci, _ci])
|
||||
HAS_MPE = _bind("qtl_mpe", [_dp, _dp, _dp, _ci, _ci])
|
||||
HAS_MRAE = _bind("qtl_mrae", [_dp, _dp, _dp, _ci, _ci])
|
||||
HAS_MSLE = _bind("qtl_msle", [_dp, _dp, _dp, _ci, _ci])
|
||||
HAS_PSEUDOHUBER = _bind("qtl_pseudohuber", [_dp, _dp, _dp, _ci, _ci, _cd])
|
||||
HAS_QUANTILELOSS = _bind("qtl_quantileloss", [_dp, _dp, _dp, _ci, _ci, _cd])
|
||||
HAS_RAE = _bind("qtl_rae", [_dp, _dp, _dp, _ci, _ci])
|
||||
HAS_RMSLE = _bind("qtl_rmsle", [_dp, _dp, _dp, _ci, _ci])
|
||||
HAS_RSE = _bind("qtl_rse", [_dp, _dp, _dp, _ci, _ci])
|
||||
HAS_RSQUARED = _bind("qtl_rsquared", [_dp, _dp, _dp, _ci, _ci])
|
||||
HAS_SMAPE = _bind("qtl_smape", [_dp, _dp, _dp, _ci, _ci])
|
||||
HAS_THEILU = _bind("qtl_theilu", [_dp, _dp, _dp, _ci, _ci])
|
||||
HAS_TUKEYBIWEIGHT = _bind("qtl_tukeybiweight", [_dp, _dp, _dp, _ci, _ci, _cd])
|
||||
HAS_WMAPE = _bind("qtl_wmape", [_dp, _dp, _dp, _ci, _ci])
|
||||
HAS_WRMSE = _bind("qtl_wrmse", [_dp, _dp, _dp, _ci, _ci])
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════════════════
|
||||
# §8.11 Filters
|
||||
# Filters
|
||||
# ═══════════════════════════════════════════════════════════════════════════
|
||||
HAS_BESSEL = _bind("qtl_bessel", _PA)
|
||||
HAS_BUTTER2 = _bind("qtl_butter2", _PA)
|
||||
HAS_BUTTER3 = _bind("qtl_butter3", _PA)
|
||||
HAS_CHEBY1 = _bind("qtl_cheby1", _PA)
|
||||
HAS_CHEBY2 = _bind("qtl_cheby2", _PA)
|
||||
HAS_ELLIPTIC = _bind("qtl_elliptic", _PA)
|
||||
HAS_EDCF = _bind("qtl_edcf", _PA)
|
||||
HAS_BPF = _bind("qtl_bpf", _PA)
|
||||
HAS_ALAGUERRE = _bind("qtl_alaguerre", [_dp, _ci, _dp, _ci, _ci]) # period, order
|
||||
HAS_BILATERAL = _bind("qtl_bilateral", [_dp, _ci, _dp, _ci, _cd, _cd]) # period, sigmaS, sigmaR
|
||||
HAS_BAXTERKING = _bind("qtl_baxterking", [_dp, _ci, _dp, _ci, _ci, _ci]) # period, minP, maxP
|
||||
HAS_CFITZ = _bind("qtl_cfitz", [_dp, _ci, _dp, _ci, _ci]) # period, bandwidthP
|
||||
HAS_GAUSS = _bind("qtl_gauss", [_dp, _dp, _ci, _cd])
|
||||
HAS_HANN = _bind("qtl_hann", [_dp, _dp, _ci, _ci])
|
||||
HAS_HP = _bind("qtl_hp", [_dp, _dp, _ci, _cd])
|
||||
HAS_HPF = _bind("qtl_hpf", [_dp, _dp, _ci, _ci])
|
||||
HAS_KALMAN = _bind("qtl_kalman", [_dp, _dp, _ci, _cd, _cd])
|
||||
HAS_LAGUERRE = _bind("qtl_laguerre", [_dp, _dp, _ci, _cd])
|
||||
HAS_LMS = _bind("qtl_lms", [_dp, _dp, _ci, _ci, _cd])
|
||||
HAS_LOESS = _bind("qtl_loess", [_dp, _dp, _ci, _ci])
|
||||
HAS_MODF = _bind("qtl_modf", [_dp, _dp, _ci, _ci, _cd, _ci, _cd])
|
||||
HAS_NOTCH = _bind("qtl_notch", [_dp, _dp, _ci, _ci, _cd])
|
||||
HAS_NW = _bind("qtl_nw", [_dp, _dp, _ci, _ci, _cd])
|
||||
HAS_ONEEURO = _bind("qtl_oneeuro", [_dp, _dp, _ci, _cd, _cd, _cd])
|
||||
HAS_RLS = _bind("qtl_rls", [_dp, _dp, _ci, _ci, _cd])
|
||||
HAS_RMED = _bind("qtl_rmed", [_dp, _dp, _ci, _ci])
|
||||
HAS_ROOFING = _bind("qtl_roofing", [_dp, _dp, _ci, _ci, _ci])
|
||||
HAS_SGF = _bind("qtl_sgf", [_dp, _dp, _ci, _ci, _ci])
|
||||
HAS_SPBF = _bind("qtl_spbf", [_dp, _dp, _ci, _ci, _ci, _ci])
|
||||
HAS_SSF2 = _bind("qtl_ssf2", [_dp, _dp, _ci, _ci])
|
||||
HAS_SSF3 = _bind("qtl_ssf3", [_dp, _dp, _ci, _ci, _cd])
|
||||
HAS_USF = _bind("qtl_usf", [_dp, _dp, _ci, _ci])
|
||||
HAS_VOSS = _bind("qtl_voss", [_dp, _dp, _ci, _ci, _ci, _cd])
|
||||
HAS_WAVELET = _bind("qtl_wavelet", [_dp, _dp, _ci, _ci, _cd])
|
||||
HAS_WIENER = _bind("qtl_wiener", [_dp, _dp, _ci, _ci, _ci])
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════════════════
|
||||
# §8.12 Cycles
|
||||
# Cycles
|
||||
# ═══════════════════════════════════════════════════════════════════════════
|
||||
HAS_CG = _bind("qtl_cg", _PA)
|
||||
HAS_DSP = _bind("qtl_dsp", _PA)
|
||||
HAS_CCOR = _bind("qtl_ccor", _PA)
|
||||
HAS_EBSW = _bind("qtl_ebsw", [_dp, _ci, _dp, _ci, _ci]) # period, hpPeriod
|
||||
HAS_EACP = _bind("qtl_eacp", [_dp, _ci, _dp, _ci, _ci, _ci, _ci]) # period, minP, maxP, useMedian
|
||||
HAS_HOMOD = _bind("qtl_homod", [_dp, _dp, _ci, _cd, _cd])
|
||||
HAS_HTDCPERIOD = _bind("qtl_htdcperiod", [_dp, _dp, _ci])
|
||||
HAS_HTDCPHASE = _bind("qtl_htdcphase", [_dp, _dp, _ci])
|
||||
HAS_HTPHASOR = _bind("qtl_htphasor", [_dp, _dp, _dp, _ci])
|
||||
HAS_HTSINE = _bind("qtl_htsine", [_dp, _dp, _dp, _ci])
|
||||
HAS_LUNAR = _bind("qtl_lunar", [_dp, _ci, _dp])
|
||||
HAS_SOLAR = _bind("qtl_solar", [_dp, _ci, _dp])
|
||||
HAS_SSFDSP = _bind("qtl_ssfdsp", [_dp, _dp, _ci, _ci])
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════════════════
|
||||
# §8.14 Numerics
|
||||
# Dynamics
|
||||
# ═══════════════════════════════════════════════════════════════════════════
|
||||
HAS_CHANGE = _bind("qtl_change", _PA)
|
||||
HAS_EXPTRANS = _bind("qtl_exptrans", _PA3) # no period
|
||||
HAS_BETADIST = _bind("qtl_betadist", [_dp, _ci, _dp, _ci, _cd, _cd]) # period, alpha, beta
|
||||
HAS_EXPDIST = _bind("qtl_expdist", [_dp, _ci, _dp, _ci, _cd]) # period, lambda
|
||||
HAS_BINOMDIST = _bind("qtl_binomdist", [_dp, _ci, _dp, _ci, _ci, _ci]) # period, trials, successes
|
||||
HAS_CWT = _bind("qtl_cwt", [_dp, _ci, _dp, _cd, _cd]) # scale, omega
|
||||
HAS_DWT = _bind("qtl_dwt", [_dp, _ci, _dp, _ci, _ci]) # period, levels
|
||||
HAS_ADX = _bind("qtl_adx", [_dp, _dp, _dp, _ci, _ci, _dp])
|
||||
HAS_ADXR = _bind("qtl_adxr", [_dp, _dp, _dp, _ci, _ci, _dp])
|
||||
HAS_ALLIGATOR = _bind("qtl_alligator", [_dp, _dp, _dp, _dp, _dp, _ci, _ci, _ci, _ci, _ci, _ci, _ci, _dp])
|
||||
HAS_AMAT = _bind("qtl_amat", [_dp, _dp, _dp, _ci, _ci, _ci])
|
||||
HAS_AROON = _bind("qtl_aroon", [_dp, _dp, _ci, _ci, _dp])
|
||||
HAS_AROONOSC = _bind("qtl_aroonosc", [_dp, _dp, _ci, _ci, _dp])
|
||||
HAS_CHOP = _bind("qtl_chop", [_dp, _dp, _dp, _dp, _dp, _ci, _ci, _dp])
|
||||
HAS_DMX = _bind("qtl_dmx", [_dp, _dp, _dp, _ci, _ci, _dp])
|
||||
HAS_DX = _bind("qtl_dx", [_dp, _dp, _dp, _ci, _ci, _dp])
|
||||
HAS_GHLA = _bind("qtl_ghla", [_dp, _dp, _dp, _dp, _ci, _ci])
|
||||
HAS_HTTRENDMODE = _bind("qtl_httrendmode", [_dp, _dp, _ci])
|
||||
HAS_ICHIMOKU = _bind("qtl_ichimoku", [_dp, _dp, _dp, _dp, _dp, _ci, _ci, _ci, _ci, _ci, _dp, _dp, _dp, _dp, _dp])
|
||||
HAS_IMPULSE = _bind("qtl_impulse", [_dp, _ci, _ci, _ci, _ci, _ci, _dp])
|
||||
HAS_PFE = _bind("qtl_pfe", [_dp, _dp, _ci, _ci, _ci])
|
||||
HAS_QSTICK = _bind("qtl_qstick", [_dp, _dp, _dp, _dp, _dp, _ci, _ci, _ci, _dp])
|
||||
HAS_RAVI = _bind("qtl_ravi", [_dp, _dp, _ci, _ci, _ci])
|
||||
HAS_SUPER = _bind("qtl_super", [_dp, _dp, _dp, _dp, _dp, _ci, _cd, _ci, _dp])
|
||||
HAS_TTMSQUEEZE = _bind("qtl_ttmsqueeze", [_dp, _dp, _dp, _dp, _dp, _ci, _cd, _ci, _cd, _ci, _ci, _dp])
|
||||
HAS_TTMTREND = _bind("qtl_ttmtrend", [_dp, _dp, _dp, _dp, _dp, _ci, _ci, _dp])
|
||||
HAS_VHF = _bind("qtl_vhf", [_dp, _dp, _ci, _ci])
|
||||
HAS_VORTEX = _bind("qtl_vortex", [_dp, _dp, _dp, _ci, _dp, _ci, _dp])
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════════════════
|
||||
# Numerics
|
||||
# ═══════════════════════════════════════════════════════════════════════════
|
||||
HAS_ACCEL = _bind("qtl_accel", [_dp, _dp, _ci])
|
||||
HAS_FDIST = _bind("qtl_fdist", [_dp, _dp, _ci, _ci, _ci, _ci])
|
||||
HAS_FFT = _bind("qtl_fft", [_dp, _dp, _ci, _ci, _ci, _ci])
|
||||
HAS_GAMMADIST = _bind("qtl_gammadist", [_dp, _dp, _ci, _cd, _cd, _ci])
|
||||
HAS_HIGHEST = _bind("qtl_highest", [_dp, _dp, _ci, _ci])
|
||||
HAS_IFFT = _bind("qtl_ifft", [_dp, _dp, _ci, _ci, _ci])
|
||||
HAS_JERK = _bind("qtl_jerk", [_dp, _dp, _ci])
|
||||
HAS_LINEARTRANS = _bind("qtl_lineartrans", [_dp, _dp, _ci, _cd, _cd])
|
||||
HAS_LOGNORMDIST = _bind("qtl_lognormdist", [_dp, _dp, _ci, _cd, _cd, _ci])
|
||||
HAS_LOGTRANS = _bind("qtl_logtrans", [_dp, _dp, _ci])
|
||||
HAS_LOWEST = _bind("qtl_lowest", [_dp, _dp, _ci, _ci])
|
||||
HAS_NORMALIZE = _bind("qtl_normalize", [_dp, _dp, _ci, _ci])
|
||||
HAS_NORMDIST = _bind("qtl_normdist", [_dp, _dp, _ci, _cd, _cd, _ci])
|
||||
HAS_POISSONDIST = _bind("qtl_poissondist", [_dp, _dp, _ci, _cd, _ci, _ci])
|
||||
HAS_RELU = _bind("qtl_relu", [_dp, _dp, _ci])
|
||||
HAS_SIGMOID = _bind("qtl_sigmoid", [_dp, _dp, _ci, _cd, _cd])
|
||||
HAS_SLOPE = _bind("qtl_slope", [_dp, _dp, _ci])
|
||||
HAS_SQRTTRANS = _bind("qtl_sqrttrans", [_dp, _dp, _ci])
|
||||
HAS_TDIST = _bind("qtl_tdist", [_dp, _dp, _ci, _ci, _ci])
|
||||
HAS_WEIBULLDIST = _bind("qtl_weibulldist", [_dp, _dp, _ci, _cd, _cd, _ci])
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════════════════
|
||||
# Reversals
|
||||
# ═══════════════════════════════════════════════════════════════════════════
|
||||
HAS_CHANDELIER = _bind("qtl_chandelier", [_dp, _dp, _dp, _dp, _dp, _ci, _ci, _cd])
|
||||
HAS_CKSTOP = _bind("qtl_ckstop", [_dp, _dp, _dp, _dp, _dp, _ci, _ci, _cd, _ci])
|
||||
HAS_FRACTALS = _bind("qtl_fractals", [_dp, _dp, _dp, _dp, _ci])
|
||||
HAS_PIVOT = _bind("qtl_pivot", [_dp, _dp, _dp, _dp, _ci])
|
||||
HAS_PIVOTCAM = _bind("qtl_pivotcam", [_dp, _dp, _dp, _dp, _ci])
|
||||
HAS_PIVOTDEM = _bind("qtl_pivotdem", [_dp, _dp, _dp, _dp, _dp, _ci])
|
||||
HAS_PIVOTEXT = _bind("qtl_pivotext", [_dp, _dp, _dp, _dp, _ci])
|
||||
HAS_PIVOTFIB = _bind("qtl_pivotfib", [_dp, _dp, _dp, _dp, _ci])
|
||||
HAS_PIVOTWOOD = _bind("qtl_pivotwood", [_dp, _dp, _dp, _dp, _ci])
|
||||
HAS_PSAR = _bind("qtl_psar", [_dp, _dp, _dp, _dp, _dp, _ci, _cd, _cd, _cd])
|
||||
HAS_SWINGS = _bind("qtl_swings", [_dp, _dp, _dp, _dp, _ci, _ci])
|
||||
HAS_TTMSCALPER = _bind("qtl_ttmscalper", [_dp, _dp, _dp, _dp, _dp, _ci, _ci])
|
||||
|
||||
|
||||
# ── Momentum (Exports.cs — manual) ──
|
||||
HAS_RSI = _bind("qtl_rsi", [_dp, _ci, _dp, _ci])
|
||||
HAS_ROC = _bind("qtl_roc", [_dp, _ci, _dp, _ci])
|
||||
HAS_MOM = _bind("qtl_mom", [_dp, _ci, _dp, _ci])
|
||||
HAS_CMO = _bind("qtl_cmo", [_dp, _ci, _dp, _ci])
|
||||
HAS_TSI = _bind("qtl_tsi", [_dp, _ci, _dp, _ci, _ci])
|
||||
HAS_APO = _bind("qtl_apo", [_dp, _ci, _dp, _ci, _ci])
|
||||
HAS_BIAS = _bind("qtl_bias", [_dp, _ci, _dp, _ci])
|
||||
HAS_CFO = _bind("qtl_cfo", [_dp, _ci, _dp, _ci])
|
||||
HAS_CFB = _bind("qtl_cfb", [_dp, _ci, _dp, _ip, _ci])
|
||||
HAS_ASI = _bind("qtl_asi", [_dp, _dp, _dp, _dp, _ci, _dp, _cd])
|
||||
|
||||
# ── Oscillators (Exports.cs — manual) ──
|
||||
HAS_FISHER = _bind("qtl_fisher", [_dp, _ci, _dp, _ci])
|
||||
HAS_FISHER04 = _bind("qtl_fisher04", [_dp, _ci, _dp, _ci])
|
||||
HAS_DPO = _bind("qtl_dpo", [_dp, _ci, _dp, _ci])
|
||||
HAS_TRIX = _bind("qtl_trix", [_dp, _ci, _dp, _ci])
|
||||
HAS_INERTIA = _bind("qtl_inertia", [_dp, _ci, _dp, _ci])
|
||||
HAS_RSX = _bind("qtl_rsx", [_dp, _ci, _dp, _ci])
|
||||
HAS_ER = _bind("qtl_er", [_dp, _ci, _dp, _ci])
|
||||
HAS_CTI = _bind("qtl_cti", [_dp, _ci, _dp, _ci])
|
||||
HAS_REFLEX = _bind("qtl_reflex", [_dp, _ci, _dp, _ci])
|
||||
HAS_TRENDFLEX = _bind("qtl_trendflex", [_dp, _ci, _dp, _ci])
|
||||
HAS_KRI = _bind("qtl_kri", [_dp, _ci, _dp, _ci])
|
||||
HAS_PSL = _bind("qtl_psl", [_dp, _ci, _dp, _ci])
|
||||
HAS_DECO = _bind("qtl_deco", [_dp, _ci, _dp, _ci, _ci])
|
||||
HAS_DOSC = _bind("qtl_dosc", [_dp, _ci, _dp, _ci, _ci, _ci, _ci])
|
||||
HAS_DYMOI = _bind("qtl_dymoi", [_dp, _ci, _dp, _ci, _ci, _ci, _ci, _ci])
|
||||
HAS_CRSI = _bind("qtl_crsi", [_dp, _ci, _dp, _ci, _ci, _ci])
|
||||
HAS_BBB = _bind("qtl_bbb", [_dp, _ci, _dp, _ci, _cd])
|
||||
HAS_BBI = _bind("qtl_bbi", [_dp, _ci, _dp, _ci, _ci, _ci, _ci])
|
||||
HAS_DEM = _bind("qtl_dem", [_dp, _dp, _ci, _dp, _ci])
|
||||
HAS_BRAR = _bind("qtl_brar", [_dp, _dp, _dp, _dp, _ci, _dp, _dp, _ci])
|
||||
|
||||
# ── Trends — FIR (Exports.cs — manual) ──
|
||||
HAS_SMA = _bind("qtl_sma", [_dp, _ci, _dp, _ci])
|
||||
HAS_WMA = _bind("qtl_wma", [_dp, _ci, _dp, _ci])
|
||||
HAS_HMA = _bind("qtl_hma", [_dp, _ci, _dp, _ci])
|
||||
HAS_TRIMA = _bind("qtl_trima", [_dp, _ci, _dp, _ci])
|
||||
HAS_SWMA = _bind("qtl_swma", [_dp, _ci, _dp, _ci])
|
||||
HAS_DWMA = _bind("qtl_dwma", [_dp, _ci, _dp, _ci])
|
||||
HAS_BLMA = _bind("qtl_blma", [_dp, _ci, _dp, _ci])
|
||||
HAS_ALMA = _bind("qtl_alma", [_dp, _ci, _dp, _ci, _cd, _cd])
|
||||
HAS_LSMA = _bind("qtl_lsma", [_dp, _ci, _dp, _ci, _ci, _cd])
|
||||
HAS_SGMA = _bind("qtl_sgma", [_dp, _ci, _dp, _ci])
|
||||
HAS_SINEMA = _bind("qtl_sinema", [_dp, _ci, _dp, _ci])
|
||||
HAS_HANMA = _bind("qtl_hanma", [_dp, _ci, _dp, _ci])
|
||||
HAS_PARZEN = _bind("qtl_parzen", [_dp, _ci, _dp, _ci])
|
||||
HAS_TSF = _bind("qtl_tsf", [_dp, _ci, _dp, _ci])
|
||||
HAS_CONV = _bind("qtl_conv", [_dp, _ci, _dp, _dp, _ci])
|
||||
HAS_BWMA = _bind("qtl_bwma", [_dp, _ci, _dp, _ci, _ci])
|
||||
HAS_CRMA = _bind("qtl_crma", [_dp, _ci, _dp, _ci, _cd])
|
||||
HAS_SP15 = _bind("qtl_sp15", [_dp, _ci, _dp, _ci])
|
||||
HAS_TUKEY_W = _bind("qtl_tukey_w", [_dp, _ci, _dp, _ci])
|
||||
HAS_RAIN = _bind("qtl_rain", [_dp, _ci, _dp, _ci])
|
||||
HAS_AFIRMA = _bind("qtl_afirma", [_dp, _ci, _dp, _ci, _ci, _ci])
|
||||
|
||||
# ── Trends — IIR (Exports.cs — manual) ──
|
||||
HAS_EMA = _bind("qtl_ema", [_dp, _ci, _dp, _ci])
|
||||
HAS_EMA_ALPHA = _bind("qtl_ema_alpha", [_dp, _ci, _dp, _cd])
|
||||
HAS_DEMA = _bind("qtl_dema", [_dp, _ci, _dp, _ci])
|
||||
HAS_DEMA_ALPHA = _bind("qtl_dema_alpha", [_dp, _ci, _dp, _cd])
|
||||
HAS_TEMA = _bind("qtl_tema", [_dp, _ci, _dp, _ci])
|
||||
HAS_LEMA = _bind("qtl_lema", [_dp, _ci, _dp, _ci])
|
||||
HAS_HEMA = _bind("qtl_hema", [_dp, _ci, _dp, _ci])
|
||||
HAS_AHRENS = _bind("qtl_ahrens", [_dp, _ci, _dp, _ci])
|
||||
HAS_DECYCLER = _bind("qtl_decycler", [_dp, _ci, _dp, _ci])
|
||||
HAS_DSMA = _bind("qtl_dsma", [_dp, _ci, _dp, _ci, _cd])
|
||||
HAS_GDEMA = _bind("qtl_gdema", [_dp, _ci, _dp, _ci, _cd])
|
||||
HAS_CORAL = _bind("qtl_coral", [_dp, _ci, _dp, _ci, _cd])
|
||||
HAS_AGC = _bind("qtl_agc", [_dp, _ci, _dp, _cd])
|
||||
HAS_CCYC = _bind("qtl_ccyc", [_dp, _ci, _dp, _cd])
|
||||
|
||||
# ── Channels (Exports.cs — manual) ──
|
||||
HAS_BBANDS = _bind("qtl_bbands", [_dp, _ci, _dp, _dp, _dp, _ci, _cd])
|
||||
HAS_ATRBANDS = _bind("qtl_atrbands", [_dp, _dp, _dp, _ci, _dp, _dp, _dp, _ci, _cd])
|
||||
HAS_APCHANNEL = _bind("qtl_apchannel", [_dp, _dp, _ci, _dp, _dp, _cd])
|
||||
|
||||
# ── Volatility (Exports.cs — manual) ──
|
||||
HAS_TR = _bind("qtl_tr", [_dp, _dp, _dp, _ci, _dp])
|
||||
HAS_BBW = _bind("qtl_bbw", [_dp, _ci, _dp, _ci, _cd])
|
||||
HAS_BBWN = _bind("qtl_bbwn", [_dp, _ci, _dp, _ci, _cd, _ci])
|
||||
HAS_BBWP = _bind("qtl_bbwp", [_dp, _ci, _dp, _ci, _cd, _ci])
|
||||
HAS_STDDEV = _bind("qtl_stddev", [_dp, _ci, _dp, _ci])
|
||||
HAS_VARIANCE = _bind("qtl_variance", [_dp, _ci, _dp, _ci])
|
||||
HAS_ETHERM = _bind("qtl_etherm", [_dp, _dp, _ci, _dp, _ci])
|
||||
HAS_CCV = _bind("qtl_ccv", [_dp, _ci, _dp, _ci, _ci])
|
||||
HAS_CV = _bind("qtl_cv", [_dp, _ci, _dp, _ci, _cd, _cd])
|
||||
HAS_CVI = _bind("qtl_cvi", [_dp, _ci, _dp, _ci, _ci])
|
||||
HAS_EWMA = _bind("qtl_ewma", [_dp, _ci, _dp, _ci, _ci, _ci])
|
||||
|
||||
# ── Volume (Exports.cs — manual) ──
|
||||
HAS_OBV = _bind("qtl_obv", [_dp, _dp, _ci, _dp])
|
||||
HAS_PVT = _bind("qtl_pvt", [_dp, _dp, _ci, _dp])
|
||||
HAS_PVR = _bind("qtl_pvr", [_dp, _dp, _ci, _dp])
|
||||
HAS_VF = _bind("qtl_vf", [_dp, _dp, _ci, _dp])
|
||||
HAS_NVI = _bind("qtl_nvi", [_dp, _dp, _ci, _dp])
|
||||
HAS_PVI = _bind("qtl_pvi", [_dp, _dp, _ci, _dp])
|
||||
HAS_TVI = _bind("qtl_tvi", [_dp, _dp, _ci, _dp, _ci])
|
||||
HAS_PVD = _bind("qtl_pvd", [_dp, _dp, _ci, _dp, _ci])
|
||||
HAS_VWMA = _bind("qtl_vwma", [_dp, _dp, _ci, _dp, _ci])
|
||||
HAS_EVWMA = _bind("qtl_evwma", [_dp, _dp, _ci, _dp, _ci])
|
||||
HAS_EFI = _bind("qtl_efi", [_dp, _dp, _ci, _dp, _ci])
|
||||
HAS_AOBV = _bind("qtl_aobv", [_dp, _dp, _ci, _dp, _dp])
|
||||
HAS_MFI = _bind("qtl_mfi", [_dp, _dp, _dp, _dp, _ci, _dp, _ci])
|
||||
HAS_CMF = _bind("qtl_cmf", [_dp, _dp, _dp, _dp, _ci, _dp, _ci])
|
||||
HAS_EOM = _bind("qtl_eom", [_dp, _dp, _dp, _ci, _dp, _ci, _cd])
|
||||
HAS_PVO = _bind("qtl_pvo", [_dp, _ci, _dp, _dp, _dp, _ci, _ci, _ci])
|
||||
|
||||
# ── Statistics (Exports.cs — manual) ──
|
||||
HAS_ZSCORE = _bind("qtl_zscore", [_dp, _ci, _dp, _ci])
|
||||
HAS_CMA = _bind("qtl_cma", [_dp, _ci, _dp])
|
||||
HAS_ENTROPY = _bind("qtl_entropy", [_dp, _ci, _dp, _ci])
|
||||
HAS_CORRELATION = _bind("qtl_correlation", [_dp, _dp, _ci, _dp, _ci])
|
||||
HAS_COVARIANCE = _bind("qtl_covariance", [_dp, _dp, _ci, _dp, _ci, _ci])
|
||||
HAS_COINTEGRATION = _bind("qtl_cointegration", [_dp, _dp, _ci, _dp, _ci])
|
||||
|
||||
# ── Errors (Exports.cs — manual) ──
|
||||
HAS_MSE = _bind("qtl_mse", [_dp, _dp, _ci, _dp, _ci])
|
||||
HAS_RMSE = _bind("qtl_rmse", [_dp, _dp, _ci, _dp, _ci])
|
||||
HAS_MAE = _bind("qtl_mae", [_dp, _dp, _ci, _dp, _ci])
|
||||
HAS_MAPE = _bind("qtl_mape", [_dp, _dp, _ci, _dp, _ci])
|
||||
|
||||
# ── Filters (Exports.cs — manual) ──
|
||||
HAS_BESSEL = _bind("qtl_bessel", [_dp, _ci, _dp, _ci])
|
||||
HAS_BUTTER2 = _bind("qtl_butter2", [_dp, _ci, _dp, _ci, _cd])
|
||||
HAS_BUTTER3 = _bind("qtl_butter3", [_dp, _ci, _dp, _ci, _cd])
|
||||
HAS_CHEBY1 = _bind("qtl_cheby1", [_dp, _ci, _dp, _ci, _cd])
|
||||
HAS_CHEBY2 = _bind("qtl_cheby2", [_dp, _ci, _dp, _ci, _cd])
|
||||
HAS_ELLIPTIC = _bind("qtl_elliptic", [_dp, _ci, _dp, _ci])
|
||||
HAS_EDCF = _bind("qtl_edcf", [_dp, _ci, _dp, _ci])
|
||||
HAS_BPF = _bind("qtl_bpf", [_dp, _ci, _dp, _ci, _ci])
|
||||
HAS_ALAGUERRE = _bind("qtl_alaguerre", [_dp, _ci, _dp, _ci, _ci])
|
||||
HAS_BILATERAL = _bind("qtl_bilateral", [_dp, _ci, _dp, _ci, _cd, _cd])
|
||||
HAS_BAXTERKING = _bind("qtl_baxterking", [_dp, _ci, _dp, _ci, _ci, _ci])
|
||||
HAS_CFITZ = _bind("qtl_cfitz", [_dp, _ci, _dp, _ci, _ci])
|
||||
|
||||
# ── Cycles (Exports.cs — manual) ──
|
||||
HAS_CG = _bind("qtl_cg", [_dp, _ci, _dp, _ci])
|
||||
HAS_DSP = _bind("qtl_dsp", [_dp, _ci, _dp, _ci])
|
||||
HAS_CCOR = _bind("qtl_ccor", [_dp, _ci, _dp, _ci, _cd])
|
||||
HAS_EBSW = _bind("qtl_ebsw", [_dp, _ci, _dp, _ci, _ci])
|
||||
HAS_EACP = _bind("qtl_eacp", [_dp, _ci, _dp, _ci, _ci, _ci, _ci])
|
||||
|
||||
# ── Numerics (Exports.cs — manual) ──
|
||||
HAS_CHANGE = _bind("qtl_change", [_dp, _ci, _dp, _ci])
|
||||
HAS_EXPTRANS = _bind("qtl_exptrans", [_dp, _ci, _dp])
|
||||
HAS_BETADIST = _bind("qtl_betadist", [_dp, _ci, _dp, _ci, _cd, _cd])
|
||||
HAS_EXPDIST = _bind("qtl_expdist", [_dp, _ci, _dp, _ci, _cd])
|
||||
HAS_BINOMDIST = _bind("qtl_binomdist", [_dp, _ci, _dp, _ci, _ci, _ci])
|
||||
HAS_CWT = _bind("qtl_cwt", [_dp, _ci, _dp, _cd, _cd])
|
||||
HAS_DWT = _bind("qtl_dwt", [_dp, _ci, _dp, _ci, _ci])
|
||||
|
||||
@@ -0,0 +1,236 @@
|
||||
"""Shared wrapper helpers for quantalib indicator modules.
|
||||
|
||||
Auto-generated by generate_category_modules.py — DO NOT EDIT.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import numpy as np
|
||||
from numpy.typing import NDArray
|
||||
|
||||
from ._bridge import _lib, _check, _dp, _ci, _cd
|
||||
|
||||
# Optional pandas support
|
||||
try:
|
||||
import pandas as pd # type: ignore[import-untyped]
|
||||
except ImportError: # pragma: no cover
|
||||
pd = None # type: ignore[assignment]
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Internal helpers
|
||||
# ---------------------------------------------------------------------------
|
||||
_F64 = np.float64
|
||||
|
||||
|
||||
def _arr(x: object) -> tuple[NDArray[np.float64], object]:
|
||||
"""Return (contiguous float64 array, original_index_or_None)."""
|
||||
if x is None:
|
||||
raise ValueError("Input array must not be None")
|
||||
idx = None
|
||||
if pd is not None and isinstance(x, pd.Series):
|
||||
idx = x.index
|
||||
x = x.to_numpy(dtype=_F64, copy=False)
|
||||
elif pd is not None and isinstance(x, pd.DataFrame):
|
||||
idx = x.index
|
||||
x = x.iloc[:, 0].to_numpy(dtype=_F64, copy=False)
|
||||
arr = np.asarray(x, dtype=_F64)
|
||||
if not arr.flags["C_CONTIGUOUS"]:
|
||||
arr = np.ascontiguousarray(arr)
|
||||
if arr.ndim == 0 or len(arr) == 0:
|
||||
raise ValueError("Input array must not be empty")
|
||||
return arr, idx
|
||||
|
||||
|
||||
def _ptr(a: NDArray[np.float64]): # noqa: ANN202
|
||||
"""Get ctypes double* from array."""
|
||||
return a.ctypes.data_as(_dp)
|
||||
|
||||
|
||||
def _out(n: int) -> NDArray[np.float64]:
|
||||
"""Allocate output array."""
|
||||
return np.empty(n, dtype=_F64)
|
||||
|
||||
|
||||
def _offset(arr: NDArray[np.float64], off: int) -> NDArray[np.float64]:
|
||||
"""Apply offset (roll + NaN fill)."""
|
||||
if off != 0:
|
||||
arr = np.roll(arr, off)
|
||||
if off > 0:
|
||||
arr[:off] = np.nan
|
||||
else:
|
||||
arr[off:] = np.nan
|
||||
return arr
|
||||
|
||||
|
||||
def _wrap(
|
||||
arr: NDArray[np.float64],
|
||||
idx: object,
|
||||
name: str,
|
||||
category: str,
|
||||
offset: int = 0,
|
||||
):
|
||||
"""Wrap result: apply offset, optionally convert to pd.Series."""
|
||||
arr = _offset(arr, offset)
|
||||
if idx is not None and pd is not None:
|
||||
s = pd.Series(arr, index=idx, name=name)
|
||||
s.attrs["category"] = category
|
||||
return s
|
||||
return arr
|
||||
|
||||
|
||||
def _wrap_multi(
|
||||
arrays: dict[str, NDArray[np.float64]],
|
||||
idx: object,
|
||||
category: str,
|
||||
offset: int = 0,
|
||||
):
|
||||
"""Wrap multi-output result into tuple or DataFrame."""
|
||||
for k in arrays:
|
||||
arrays[k] = _offset(arrays[k], offset)
|
||||
if idx is not None and pd is not None:
|
||||
df = pd.DataFrame(arrays, index=idx)
|
||||
df.attrs["category"] = category
|
||||
return df
|
||||
return tuple(arrays.values())
|
||||
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════════════════
|
||||
# Generic pattern helpers
|
||||
# ═══════════════════════════════════════════════════════════════════════════
|
||||
|
||||
def _pa(
|
||||
fn_name: str, close: object, length: int, offset: int,
|
||||
default_length: int, label: str, category: str,
|
||||
) -> object:
|
||||
"""Generic Pattern A wrapper: single-input + period."""
|
||||
length = int(length) if length is not None else default_length
|
||||
offset = int(offset) if offset is not None else 0
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
dst = _out(n)
|
||||
_check(getattr(_lib, fn_name)(_ptr(src), n, _ptr(dst), length))
|
||||
return _wrap(dst, idx, f"{label}_{length}", category, offset)
|
||||
|
||||
|
||||
def _pa3(
|
||||
fn_name: str, close: object, offset: int,
|
||||
label: str, category: str,
|
||||
) -> object:
|
||||
"""Generic Pattern A3 wrapper: single-input, no params."""
|
||||
offset = int(offset) if offset is not None else 0
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
dst = _out(n)
|
||||
_check(getattr(_lib, fn_name)(_ptr(src), n, _ptr(dst)))
|
||||
return _wrap(dst, idx, label, category, offset)
|
||||
|
||||
|
||||
def _pf(
|
||||
fn_name: str, actual: object, predicted: object,
|
||||
length: int, offset: int, default_length: int,
|
||||
label: str, category: str,
|
||||
) -> object:
|
||||
"""Generic Pattern F wrapper: actual+predicted+period."""
|
||||
length = int(length) if length is not None else default_length
|
||||
offset = int(offset) if offset is not None else 0
|
||||
a, idx = _arr(actual)
|
||||
p, _ = _arr(predicted)
|
||||
n = len(a)
|
||||
dst = _out(n)
|
||||
_check(getattr(_lib, fn_name)(_ptr(a), _ptr(p), n, _ptr(dst), length))
|
||||
return _wrap(dst, idx, f"{label}_{length}", category, offset)
|
||||
|
||||
|
||||
def _pg(
|
||||
fn_name: str, close: object, volume: object,
|
||||
offset: int, label: str, category: str,
|
||||
) -> object:
|
||||
"""Pattern G: source+volume, no period."""
|
||||
offset = int(offset) if offset is not None else 0
|
||||
c, idx = _arr(close)
|
||||
v, _ = _arr(volume)
|
||||
n = len(c)
|
||||
dst = _out(n)
|
||||
_check(getattr(_lib, fn_name)(_ptr(c), _ptr(v), n, _ptr(dst)))
|
||||
return _wrap(dst, idx, label, category, offset)
|
||||
|
||||
|
||||
def _pg2(
|
||||
fn_name: str, close: object, volume: object, length: int,
|
||||
offset: int, default_length: int, label: str, category: str,
|
||||
) -> object:
|
||||
"""Pattern G2: source+volume+period."""
|
||||
length = int(length) if length is not None else default_length
|
||||
offset = int(offset) if offset is not None else 0
|
||||
c, idx = _arr(close)
|
||||
v, _ = _arr(volume)
|
||||
n = len(c)
|
||||
dst = _out(n)
|
||||
_check(getattr(_lib, fn_name)(_ptr(c), _ptr(v), n, _ptr(dst), length))
|
||||
return _wrap(dst, idx, f"{label}_{length}", category, offset)
|
||||
|
||||
|
||||
def _ph(
|
||||
fn_name: str, x: object, y: object, length: int,
|
||||
offset: int, default_length: int, label: str, category: str,
|
||||
) -> object:
|
||||
"""Pattern H: X+Y+period."""
|
||||
length = int(length) if length is not None else default_length
|
||||
offset = int(offset) if offset is not None else 0
|
||||
xarr, idx = _arr(x)
|
||||
yarr, _ = _arr(y)
|
||||
n = len(xarr)
|
||||
dst = _out(n)
|
||||
_check(getattr(_lib, fn_name)(_ptr(xarr), _ptr(yarr), n, _ptr(dst), length))
|
||||
return _wrap(dst, idx, f"{label}_{length}", category, offset)
|
||||
|
||||
|
||||
def _ohlcv_bars_period(
|
||||
fn_name: str, open: object, high: object, low: object,
|
||||
close: object, volume: object, period: int,
|
||||
offset: int, default_period: int, label: str, category: str,
|
||||
) -> object:
|
||||
"""OHLCV bars + period → single output (BuildBars pattern)."""
|
||||
period = int(period) if period is not None else default_period
|
||||
offset = int(offset) if offset is not None else 0
|
||||
o, idx = _arr(open)
|
||||
h, _ = _arr(high)
|
||||
l, _ = _arr(low)
|
||||
c, _ = _arr(close)
|
||||
v, _ = _arr(volume)
|
||||
n = len(o)
|
||||
dst = _out(n)
|
||||
_check(getattr(_lib, fn_name)(
|
||||
_ptr(o), _ptr(h), _ptr(l), _ptr(c), _ptr(v), period, n, _ptr(dst)))
|
||||
return _wrap(dst, idx, f"{label}_{period}", category, offset)
|
||||
|
||||
|
||||
def _hlc_period(
|
||||
fn_name: str, high: object, low: object, close: object,
|
||||
period: int, offset: int, default_period: int,
|
||||
label: str, category: str,
|
||||
) -> object:
|
||||
"""HLC + period → single output."""
|
||||
period = int(period) if period is not None else default_period
|
||||
offset = int(offset) if offset is not None else 0
|
||||
h, idx = _arr(high)
|
||||
l, _ = _arr(low)
|
||||
c, _ = _arr(close)
|
||||
n = len(h)
|
||||
dst = _out(n)
|
||||
_check(getattr(_lib, fn_name)(
|
||||
_ptr(h), _ptr(l), _ptr(c), period, n, _ptr(dst)))
|
||||
return _wrap(dst, idx, f"{label}_{period}", category, offset)
|
||||
|
||||
|
||||
def _src_period(
|
||||
fn_name: str, source: object, period: int,
|
||||
offset: int, default_period: int, label: str, category: str,
|
||||
) -> object:
|
||||
"""source + period → single output (BuildSeries pattern, src,period,n,dst)."""
|
||||
period = int(period) if period is not None else default_period
|
||||
offset = int(offset) if offset is not None else 0
|
||||
src, idx = _arr(source)
|
||||
n = len(src)
|
||||
dst = _out(n)
|
||||
_check(getattr(_lib, fn_name)(_ptr(src), period, n, _ptr(dst)))
|
||||
return _wrap(dst, idx, f"{label}_{period}", category, offset)
|
||||
@@ -0,0 +1,352 @@
|
||||
"""quantalib channels indicators.
|
||||
|
||||
Auto-generated — DO NOT EDIT.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
from ._helpers import _arr, _ptr, _out, _wrap, _wrap_multi, _check, _lib
|
||||
|
||||
|
||||
__all__ = [
|
||||
"aberr",
|
||||
"accbands",
|
||||
"apchannel",
|
||||
"apz",
|
||||
"atrbands",
|
||||
"bbands",
|
||||
"dchannel",
|
||||
"decaychannel",
|
||||
"fcb",
|
||||
"jbands",
|
||||
"kchannel",
|
||||
"maenv",
|
||||
"mmchannel",
|
||||
"pchannel",
|
||||
"regchannel",
|
||||
"sdchannel",
|
||||
"starchannel",
|
||||
"stbands",
|
||||
"ttm_lrc",
|
||||
"ubands",
|
||||
"uchannel",
|
||||
"vwapbands",
|
||||
"vwapsd",
|
||||
]
|
||||
|
||||
|
||||
def aberr(close: object, period: int = 14, multiplier: float = 2.0, offset: int = 0, **kwargs) -> object:
|
||||
"""Aberration Bands."""
|
||||
period = int(period)
|
||||
multiplier = float(multiplier)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
middle = _out(n)
|
||||
upper = _out(n)
|
||||
lower = _out(n)
|
||||
_check(_lib.qtl_abber(_ptr(src), _ptr(middle), _ptr(upper), _ptr(lower), n, period, multiplier))
|
||||
return _wrap_multi({"middle": middle, "upper": upper, "lower": lower}, idx, "channels", offset)
|
||||
|
||||
|
||||
def accbands(high: object, low: object, close: object, period: int = 14, factor: float = 2.0, offset: int = 0, **kwargs) -> object:
|
||||
"""Acceleration Bands."""
|
||||
period = int(period)
|
||||
factor = float(factor)
|
||||
offset = int(offset)
|
||||
h, idx = _arr(high); l, _ = _arr(low); c, _ = _arr(close)
|
||||
n = len(h)
|
||||
middle = _out(n)
|
||||
upper = _out(n)
|
||||
lower = _out(n)
|
||||
_check(_lib.qtl_accbands(_ptr(h), _ptr(l), _ptr(c), _ptr(middle), _ptr(upper), _ptr(lower), n, period, factor))
|
||||
return _wrap_multi({"middle": middle, "upper": upper, "lower": lower}, idx, "channels", offset)
|
||||
|
||||
|
||||
def apz(open: object, high: object, low: object, close: object, volume: object, period: int = 14, multiplier: float = 2.0, offset: int = 0, **kwargs) -> object:
|
||||
"""Adaptive Price Zone."""
|
||||
period = int(period)
|
||||
multiplier = float(multiplier)
|
||||
offset = int(offset)
|
||||
o, idx = _arr(open); h, _ = _arr(high); l, _ = _arr(low)
|
||||
c, _ = _arr(close); v, _ = _arr(volume)
|
||||
n = len(o)
|
||||
dstMiddle = _out(n)
|
||||
dstUpper = _out(n)
|
||||
dstLower = _out(n)
|
||||
_check(_lib.qtl_apz(_ptr(o), _ptr(h), _ptr(l), _ptr(c), _ptr(v), period, multiplier, n, _ptr(dstMiddle), _ptr(dstUpper), _ptr(dstLower)))
|
||||
return _wrap_multi({"dstMiddle": dstMiddle, "dstUpper": dstUpper, "dstLower": dstLower}, idx, "channels", offset)
|
||||
|
||||
|
||||
def dchannel(high: object, low: object, period: int = 14, offset: int = 0, **kwargs) -> object:
|
||||
"""Donchian Channel."""
|
||||
period = int(period)
|
||||
offset = int(offset)
|
||||
h, idx = _arr(high); l, _ = _arr(low)
|
||||
n = len(h)
|
||||
middle = _out(n)
|
||||
upper = _out(n)
|
||||
lower = _out(n)
|
||||
_check(_lib.qtl_dchannel(_ptr(h), _ptr(l), _ptr(middle), _ptr(upper), _ptr(lower), n, period))
|
||||
return _wrap_multi({"middle": middle, "upper": upper, "lower": lower}, idx, "channels", offset)
|
||||
|
||||
|
||||
def decaychannel(high: object, low: object, period: int = 14, offset: int = 0, **kwargs) -> object:
|
||||
"""Decay Channel."""
|
||||
period = int(period)
|
||||
offset = int(offset)
|
||||
h, idx = _arr(high); l, _ = _arr(low)
|
||||
n = len(h)
|
||||
middle = _out(n)
|
||||
upper = _out(n)
|
||||
lower = _out(n)
|
||||
_check(_lib.qtl_decaychannel(_ptr(h), _ptr(l), _ptr(middle), _ptr(upper), _ptr(lower), n, period))
|
||||
return _wrap_multi({"middle": middle, "upper": upper, "lower": lower}, idx, "channels", offset)
|
||||
|
||||
|
||||
def fcb(high: object, low: object, period: int = 14, offset: int = 0, **kwargs) -> object:
|
||||
"""Fractal Chaos Bands."""
|
||||
period = int(period)
|
||||
offset = int(offset)
|
||||
h, idx = _arr(high); l, _ = _arr(low)
|
||||
n = len(h)
|
||||
middle = _out(n)
|
||||
upper = _out(n)
|
||||
lower = _out(n)
|
||||
_check(_lib.qtl_fcb(_ptr(h), _ptr(l), _ptr(middle), _ptr(upper), _ptr(lower), n, period))
|
||||
return _wrap_multi({"middle": middle, "upper": upper, "lower": lower}, idx, "channels", offset)
|
||||
|
||||
|
||||
def jbands(close: object, period: int = 14, phase: int = 0, offset: int = 0, **kwargs) -> object:
|
||||
"""J-Line Bands."""
|
||||
period = int(period)
|
||||
phase = int(phase)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
middle = _out(n)
|
||||
upper = _out(n)
|
||||
lower = _out(n)
|
||||
_check(_lib.qtl_jbands(_ptr(src), _ptr(middle), _ptr(upper), _ptr(lower), n, period, phase))
|
||||
return _wrap_multi({"middle": middle, "upper": upper, "lower": lower}, idx, "channels", offset)
|
||||
|
||||
|
||||
def kchannel(high: object, low: object, close: object, period: int = 14, multiplier: float = 2.0, offset: int = 0, **kwargs) -> object:
|
||||
"""Keltner Channel."""
|
||||
period = int(period)
|
||||
multiplier = float(multiplier)
|
||||
offset = int(offset)
|
||||
h, idx = _arr(high); l, _ = _arr(low); c, _ = _arr(close)
|
||||
n = len(h)
|
||||
middle = _out(n)
|
||||
upper = _out(n)
|
||||
lower = _out(n)
|
||||
_check(_lib.qtl_kchannel(_ptr(h), _ptr(l), _ptr(c), _ptr(middle), _ptr(upper), _ptr(lower), n, period, multiplier))
|
||||
return _wrap_multi({"middle": middle, "upper": upper, "lower": lower}, idx, "channels", offset)
|
||||
|
||||
|
||||
def maenv(close: object, period: int = 14, percentage: float = 2.5, maType: int = 0, offset: int = 0, **kwargs) -> object:
|
||||
"""Moving Average Envelope."""
|
||||
period = int(period)
|
||||
percentage = float(percentage)
|
||||
maType = int(maType)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
middle = _out(n)
|
||||
upper = _out(n)
|
||||
lower = _out(n)
|
||||
_check(_lib.qtl_maenv(_ptr(src), _ptr(middle), _ptr(upper), _ptr(lower), n, period, percentage, maType))
|
||||
return _wrap_multi({"middle": middle, "upper": upper, "lower": lower}, idx, "channels", offset)
|
||||
|
||||
|
||||
def mmchannel(high: object, low: object, period: int = 14, offset: int = 0, **kwargs) -> object:
|
||||
"""Min-Max Channel."""
|
||||
period = int(period)
|
||||
offset = int(offset)
|
||||
h, idx = _arr(high); l, _ = _arr(low)
|
||||
n = len(h)
|
||||
upper = _out(n)
|
||||
lower = _out(n)
|
||||
_check(_lib.qtl_mmchannel(_ptr(h), _ptr(l), _ptr(upper), _ptr(lower), n, period))
|
||||
return _wrap_multi({"upper": upper, "lower": lower}, idx, "channels", offset)
|
||||
|
||||
|
||||
def pchannel(high: object, low: object, period: int = 14, offset: int = 0, **kwargs) -> object:
|
||||
"""Price Channel."""
|
||||
period = int(period)
|
||||
offset = int(offset)
|
||||
h, idx = _arr(high); l, _ = _arr(low)
|
||||
n = len(h)
|
||||
middle = _out(n)
|
||||
upper = _out(n)
|
||||
lower = _out(n)
|
||||
_check(_lib.qtl_pchannel(_ptr(h), _ptr(l), _ptr(middle), _ptr(upper), _ptr(lower), n, period))
|
||||
return _wrap_multi({"middle": middle, "upper": upper, "lower": lower}, idx, "channels", offset)
|
||||
|
||||
|
||||
def regchannel(close: object, period: int = 14, multiplier: float = 2.0, offset: int = 0, **kwargs) -> object:
|
||||
"""Regression Channel."""
|
||||
period = int(period)
|
||||
multiplier = float(multiplier)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
middle = _out(n)
|
||||
upper = _out(n)
|
||||
lower = _out(n)
|
||||
_check(_lib.qtl_regchannel(_ptr(src), _ptr(middle), _ptr(upper), _ptr(lower), n, period, multiplier))
|
||||
return _wrap_multi({"middle": middle, "upper": upper, "lower": lower}, idx, "channels", offset)
|
||||
|
||||
|
||||
def sdchannel(close: object, period: int = 14, multiplier: float = 2.0, offset: int = 0, **kwargs) -> object:
|
||||
"""Standard Deviation Channel."""
|
||||
period = int(period)
|
||||
multiplier = float(multiplier)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
middle = _out(n)
|
||||
upper = _out(n)
|
||||
lower = _out(n)
|
||||
_check(_lib.qtl_sdchannel(_ptr(src), _ptr(middle), _ptr(upper), _ptr(lower), n, period, multiplier))
|
||||
return _wrap_multi({"middle": middle, "upper": upper, "lower": lower}, idx, "channels", offset)
|
||||
|
||||
|
||||
def starchannel(high: object, low: object, close: object, period: int = 14, multiplier: float = 2.0, atrPeriod: int = 22, offset: int = 0, **kwargs) -> object:
|
||||
"""Stoller Average Range Channel (STARC)."""
|
||||
period = int(period)
|
||||
multiplier = float(multiplier)
|
||||
atrPeriod = int(atrPeriod)
|
||||
offset = int(offset)
|
||||
h, idx = _arr(high); l, _ = _arr(low); c, _ = _arr(close)
|
||||
n = len(h)
|
||||
middle = _out(n)
|
||||
upper = _out(n)
|
||||
lower = _out(n)
|
||||
_check(_lib.qtl_starchannel(_ptr(h), _ptr(l), _ptr(c), _ptr(middle), _ptr(upper), _ptr(lower), n, period, multiplier, atrPeriod))
|
||||
return _wrap_multi({"middle": middle, "upper": upper, "lower": lower}, idx, "channels", offset)
|
||||
|
||||
|
||||
def stbands(high: object, low: object, close: object, period: int = 14, multiplier: float = 2.0, offset: int = 0, **kwargs) -> object:
|
||||
"""SuperTrend Bands."""
|
||||
period = int(period)
|
||||
multiplier = float(multiplier)
|
||||
offset = int(offset)
|
||||
h, idx = _arr(high); l, _ = _arr(low); c, _ = _arr(close)
|
||||
n = len(h)
|
||||
upper = _out(n)
|
||||
lower = _out(n)
|
||||
trend = _out(n)
|
||||
_check(_lib.qtl_stbands(_ptr(h), _ptr(l), _ptr(c), _ptr(upper), _ptr(lower), _ptr(trend), n, period, multiplier))
|
||||
return _wrap_multi({"upper": upper, "lower": lower, "trend": trend}, idx, "channels", offset)
|
||||
|
||||
|
||||
def ttm_lrc(close: object, period: int = 14, offset: int = 0, **kwargs) -> object:
|
||||
"""TTM Linear Regression Channel."""
|
||||
period = int(period)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
midline = _out(n)
|
||||
upper1 = _out(n)
|
||||
lower1 = _out(n)
|
||||
upper2 = _out(n)
|
||||
lower2 = _out(n)
|
||||
_check(_lib.qtl_ttmlrc(_ptr(src), _ptr(midline), _ptr(upper1), _ptr(lower1), _ptr(upper2), _ptr(lower2), n, period))
|
||||
return _wrap_multi({"midline": midline, "upper1": upper1, "lower1": lower1, "upper2": upper2, "lower2": lower2}, idx, "channels", offset)
|
||||
|
||||
|
||||
def ubands(close: object, period: int = 14, multiplier: float = 2.0, offset: int = 0, **kwargs) -> object:
|
||||
"""Upper/Lower Bands."""
|
||||
period = int(period)
|
||||
multiplier = float(multiplier)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
upper = _out(n)
|
||||
middle = _out(n)
|
||||
lower = _out(n)
|
||||
_check(_lib.qtl_ubands(_ptr(src), _ptr(upper), _ptr(middle), _ptr(lower), n, period, multiplier))
|
||||
return _wrap_multi({"upper": upper, "middle": middle, "lower": lower}, idx, "channels", offset)
|
||||
|
||||
|
||||
def uchannel(high: object, low: object, close: object, strPeriod: int = 14, centerPeriod: int = 20, multiplier: float = 2.0, offset: int = 0, **kwargs) -> object:
|
||||
"""Ulcer Channel."""
|
||||
strPeriod = int(strPeriod)
|
||||
centerPeriod = int(centerPeriod)
|
||||
multiplier = float(multiplier)
|
||||
offset = int(offset)
|
||||
h, idx = _arr(high); l, _ = _arr(low); c, _ = _arr(close)
|
||||
n = len(h)
|
||||
upper = _out(n)
|
||||
middle = _out(n)
|
||||
lower = _out(n)
|
||||
_check(_lib.qtl_uchannel(_ptr(h), _ptr(l), _ptr(c), _ptr(upper), _ptr(middle), _ptr(lower), n, strPeriod, centerPeriod, multiplier))
|
||||
return _wrap_multi({"upper": upper, "middle": middle, "lower": lower}, idx, "channels", offset)
|
||||
|
||||
|
||||
def vwapbands(price: object, volume: object, multiplier: float = 2.0, offset: int = 0, **kwargs) -> object:
|
||||
"""VWAP Bands."""
|
||||
multiplier = float(multiplier)
|
||||
offset = int(offset)
|
||||
pr, idx = _arr(price); v, _ = _arr(volume)
|
||||
n = len(pr)
|
||||
upper1 = _out(n)
|
||||
lower1 = _out(n)
|
||||
upper2 = _out(n)
|
||||
lower2 = _out(n)
|
||||
vwap = _out(n)
|
||||
stdDev = _out(n)
|
||||
_check(_lib.qtl_vwapbands(_ptr(pr), _ptr(v), _ptr(upper1), _ptr(lower1), _ptr(upper2), _ptr(lower2), _ptr(vwap), _ptr(stdDev), n, multiplier))
|
||||
return _wrap_multi({"upper1": upper1, "lower1": lower1, "upper2": upper2, "lower2": lower2, "vwap": vwap, "stdDev": stdDev}, idx, "channels", offset)
|
||||
|
||||
|
||||
def vwapsd(price: object, volume: object, numDevs: float = 2.0, offset: int = 0, **kwargs) -> object:
|
||||
"""VWAP Standard Deviation."""
|
||||
numDevs = float(numDevs)
|
||||
offset = int(offset)
|
||||
pr, idx = _arr(price); v, _ = _arr(volume)
|
||||
n = len(pr)
|
||||
upper = _out(n)
|
||||
lower = _out(n)
|
||||
vwap = _out(n)
|
||||
stdDev = _out(n)
|
||||
_check(_lib.qtl_vwapsd(_ptr(pr), _ptr(v), _ptr(upper), _ptr(lower), _ptr(vwap), _ptr(stdDev), n, numDevs))
|
||||
return _wrap_multi({"upper": upper, "lower": lower, "vwap": vwap, "stdDev": stdDev}, idx, "channels", offset)
|
||||
|
||||
|
||||
def bbands(close: object, length: int = 20, std: float = 2.0,
|
||||
offset: int = 0, **kwargs) -> object:
|
||||
"""Bollinger Bands -> (upper, mid, lower) or DataFrame."""
|
||||
length = int(length); std = float(std); offset = int(offset)
|
||||
src, idx = _arr(close); n = len(src)
|
||||
upper = _out(n); mid = _out(n); lower = _out(n)
|
||||
_check(_lib.qtl_bbands(_ptr(src), n, _ptr(upper), _ptr(mid), _ptr(lower), length, std))
|
||||
return _wrap_multi(
|
||||
{f"BBU_{length}_{std}": upper, f"BBM_{length}_{std}": mid, f"BBL_{length}_{std}": lower},
|
||||
idx, "channels", offset)
|
||||
|
||||
|
||||
def atrbands(high: object, low: object, close: object,
|
||||
length: int = 14, mult: float = 2.0,
|
||||
offset: int = 0, **kwargs) -> object:
|
||||
"""ATR Bands -> (upper, mid, lower) or DataFrame."""
|
||||
length = int(length); mult = float(mult); offset = int(offset)
|
||||
h, idx = _arr(high); l, _ = _arr(low); c, _ = _arr(close)
|
||||
n = len(h)
|
||||
upper = _out(n); mid = _out(n); lower = _out(n)
|
||||
_check(_lib.qtl_atrbands(_ptr(h), _ptr(l), _ptr(c), n, _ptr(upper), _ptr(mid), _ptr(lower), length, mult))
|
||||
return _wrap_multi(
|
||||
{f"ATRBU_{length}_{mult}": upper, f"ATRBM_{length}_{mult}": mid, f"ATRBL_{length}_{mult}": lower},
|
||||
idx, "channels", offset)
|
||||
|
||||
|
||||
def apchannel(high: object, low: object, length: int = 20,
|
||||
offset: int = 0, **kwargs) -> object:
|
||||
"""Average Price Channel -> (upper, lower) or DataFrame."""
|
||||
length = int(length); offset = int(offset)
|
||||
h, idx = _arr(high); l, _ = _arr(low)
|
||||
n = len(h)
|
||||
upper = _out(n); lower = _out(n)
|
||||
_check(_lib.qtl_apchannel(_ptr(h), _ptr(l), n, _ptr(upper), _ptr(lower), float(length)))
|
||||
return _wrap_multi({f"APCU_{length}": upper, f"APCL_{length}": lower}, idx, "channels", offset)
|
||||
@@ -0,0 +1,98 @@
|
||||
"""quantalib core indicators.
|
||||
|
||||
Auto-generated — DO NOT EDIT.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
from ._helpers import _arr, _ptr, _out, _wrap, _wrap_multi, _check, _lib
|
||||
|
||||
|
||||
__all__ = [
|
||||
"ha",
|
||||
"midpoint",
|
||||
"midprice",
|
||||
"wclprice",
|
||||
"avgprice",
|
||||
"medprice",
|
||||
"typprice",
|
||||
"midbody",
|
||||
]
|
||||
|
||||
|
||||
def ha(open: object, high: object, low: object, close: object, offset: int = 0, **kwargs) -> object:
|
||||
"""Heikin-Ashi Candles."""
|
||||
offset = int(offset)
|
||||
o, idx = _arr(open); h, _ = _arr(high); l, _ = _arr(low); c, _ = _arr(close)
|
||||
n = len(o)
|
||||
haOpenOut = _out(n)
|
||||
haHighOut = _out(n)
|
||||
haLowOut = _out(n)
|
||||
haCloseOut = _out(n)
|
||||
_check(_lib.qtl_ha(_ptr(o), _ptr(h), _ptr(l), _ptr(c), _ptr(haOpenOut), _ptr(haHighOut), _ptr(haLowOut), _ptr(haCloseOut), n))
|
||||
return _wrap_multi({"haOpenOut": haOpenOut, "haHighOut": haHighOut, "haLowOut": haLowOut, "haCloseOut": haCloseOut}, idx, "core", offset)
|
||||
|
||||
|
||||
def midpoint(close: object, period: int = 14, offset: int = 0, **kwargs) -> object:
|
||||
"""Midpoint = src[i] over period."""
|
||||
period = int(period)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_midpoint(_ptr(src), _ptr(output), n, period))
|
||||
return _wrap(output, idx, f"MIDPOINT_{period}", "core", offset)
|
||||
|
||||
|
||||
def midprice(high: object, low: object, period: int = 14, offset: int = 0, **kwargs) -> object:
|
||||
"""Mid Price = (High+Low)/2 over period."""
|
||||
period = int(period)
|
||||
offset = int(offset)
|
||||
h, idx = _arr(high); l, _ = _arr(low)
|
||||
n = len(h)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_midprice(_ptr(h), _ptr(l), _ptr(output), n, period))
|
||||
return _wrap(output, idx, f"MIDPRICE_{period}", "core", offset)
|
||||
|
||||
|
||||
def wclprice(high: object, low: object, close: object, offset: int = 0, **kwargs) -> object:
|
||||
"""Weighted Close Price = (H+L+2*C)/4."""
|
||||
offset = int(offset)
|
||||
h, idx = _arr(high); l, _ = _arr(low); c, _ = _arr(close)
|
||||
n = len(h)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_wclprice(_ptr(h), _ptr(l), _ptr(c), _ptr(output), n))
|
||||
return _wrap(output, idx, "WCLPRICE", "core", offset)
|
||||
|
||||
def avgprice(open: object, high: object, low: object, close: object,
|
||||
offset: int = 0, **kwargs) -> object:
|
||||
"""Average Price = (O+H+L+C)/4."""
|
||||
offset = int(offset)
|
||||
o, idx = _arr(open); h, _ = _arr(high); l, _ = _arr(low); c, _ = _arr(close)
|
||||
n = len(o); dst = _out(n)
|
||||
_check(_lib.qtl_avgprice(_ptr(o), _ptr(h), _ptr(l), _ptr(c), n, _ptr(dst)))
|
||||
return _wrap(dst, idx, "AVGPRICE", "core", offset)
|
||||
|
||||
|
||||
def medprice(high: object, low: object, offset: int = 0, **kwargs) -> object:
|
||||
"""Median Price = (H+L)/2."""
|
||||
h, idx = _arr(high); l, _ = _arr(low)
|
||||
n = len(h); dst = _out(n)
|
||||
_check(_lib.qtl_medprice(_ptr(h), _ptr(l), n, _ptr(dst)))
|
||||
return _wrap(dst, idx, "MEDPRICE", "core", int(offset))
|
||||
|
||||
|
||||
def typprice(open: object, high: object, low: object,
|
||||
offset: int = 0, **kwargs) -> object:
|
||||
"""Typical Price = (O+H+L)/3 (QuanTAlib variant)."""
|
||||
o, idx = _arr(open); h, _ = _arr(high); l, _ = _arr(low)
|
||||
n = len(o); dst = _out(n)
|
||||
_check(_lib.qtl_typprice(_ptr(o), _ptr(h), _ptr(l), n, _ptr(dst)))
|
||||
return _wrap(dst, idx, "TYPPRICE", "core", int(offset))
|
||||
|
||||
|
||||
def midbody(open: object, close: object, offset: int = 0, **kwargs) -> object:
|
||||
"""Mid Body = (O+C)/2."""
|
||||
o, idx = _arr(open); c, _ = _arr(close)
|
||||
n = len(o); dst = _out(n)
|
||||
_check(_lib.qtl_midbody(_ptr(o), _ptr(c), n, _ptr(dst)))
|
||||
return _wrap(dst, idx, "MIDBODY", "core", int(offset))
|
||||
@@ -0,0 +1,152 @@
|
||||
"""quantalib cycles indicators.
|
||||
|
||||
Auto-generated — DO NOT EDIT.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
from ._helpers import _arr, _ptr, _out, _wrap, _wrap_multi, _check, _lib
|
||||
|
||||
|
||||
__all__ = [
|
||||
"homod",
|
||||
"ht_dcperiod",
|
||||
"ht_dcphase",
|
||||
"ht_phasor",
|
||||
"ht_sine",
|
||||
"lunar",
|
||||
"solar",
|
||||
"ssfdsp",
|
||||
"cg",
|
||||
"dsp",
|
||||
"ccor",
|
||||
"ebsw",
|
||||
"eacp",
|
||||
]
|
||||
|
||||
|
||||
def homod(close: object, minPeriod: float = 6, maxPeriod: float = 48, offset: int = 0, **kwargs) -> object:
|
||||
"""Homodyne Discriminator."""
|
||||
minPeriod = float(minPeriod)
|
||||
maxPeriod = float(maxPeriod)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_homod(_ptr(src), _ptr(output), n, minPeriod, maxPeriod))
|
||||
return _wrap(output, idx, f"HOMOD_{minPeriod}", "cycles", offset)
|
||||
|
||||
|
||||
def ht_dcperiod(close: object, offset: int = 0, **kwargs) -> object:
|
||||
"""Hilbert Transform Dominant Cycle Period."""
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_htdcperiod(_ptr(src), _ptr(output), n))
|
||||
return _wrap(output, idx, "HT_DCPERIOD", "cycles", offset)
|
||||
|
||||
|
||||
def ht_dcphase(close: object, offset: int = 0, **kwargs) -> object:
|
||||
"""Hilbert Transform Dominant Cycle Phase."""
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_htdcphase(_ptr(src), _ptr(output), n))
|
||||
return _wrap(output, idx, "HT_DCPHASE", "cycles", offset)
|
||||
|
||||
|
||||
def ht_phasor(close: object, offset: int = 0, **kwargs) -> object:
|
||||
"""Hilbert Transform Phasor."""
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
inPhase = _out(n)
|
||||
quadrature = _out(n)
|
||||
_check(_lib.qtl_htphasor(_ptr(src), _ptr(inPhase), _ptr(quadrature), n))
|
||||
return _wrap_multi({"inPhase": inPhase, "quadrature": quadrature}, idx, "cycles", offset)
|
||||
|
||||
|
||||
def ht_sine(close: object, offset: int = 0, **kwargs) -> object:
|
||||
"""Hilbert Transform Sine."""
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
sine = _out(n)
|
||||
leadSine = _out(n)
|
||||
_check(_lib.qtl_htsine(_ptr(src), _ptr(sine), _ptr(leadSine), n))
|
||||
return _wrap_multi({"sine": sine, "leadSine": leadSine}, idx, "cycles", offset)
|
||||
|
||||
|
||||
def lunar(close: object, offset: int = 0, **kwargs) -> object:
|
||||
"""Lunar Cycle."""
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
dst = _out(n)
|
||||
_check(_lib.qtl_lunar(_ptr(src), n, _ptr(dst)))
|
||||
return _wrap(dst, idx, "LUNAR", "cycles", offset)
|
||||
|
||||
|
||||
def solar(close: object, offset: int = 0, **kwargs) -> object:
|
||||
"""Solar Cycle."""
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
dst = _out(n)
|
||||
_check(_lib.qtl_solar(_ptr(src), n, _ptr(dst)))
|
||||
return _wrap(dst, idx, "SOLAR", "cycles", offset)
|
||||
|
||||
|
||||
def ssfdsp(close: object, period: int = 14, offset: int = 0, **kwargs) -> object:
|
||||
"""Supersmoother DSP."""
|
||||
period = int(period)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_ssfdsp(_ptr(src), _ptr(output), n, period))
|
||||
return _wrap(output, idx, f"SSFDSP_{period}", "cycles", offset)
|
||||
|
||||
def cg(close: object, length: int = 10, offset: int = 0, **kwargs) -> object:
|
||||
"""Center of Gravity."""
|
||||
length = int(length); offset = int(offset)
|
||||
src, idx = _arr(close); n = len(src); dst = _out(n)
|
||||
_check(_lib.qtl_cg(_ptr(src), n, _ptr(dst), length))
|
||||
return _wrap(dst, idx, f"CG_{length}", "cycles", offset)
|
||||
|
||||
|
||||
def dsp(close: object, length: int = 20, offset: int = 0, **kwargs) -> object:
|
||||
"""Dominant Cycle Period (DSP)."""
|
||||
length = int(length); offset = int(offset)
|
||||
src, idx = _arr(close); n = len(src); dst = _out(n)
|
||||
_check(_lib.qtl_dsp(_ptr(src), n, _ptr(dst), length))
|
||||
return _wrap(dst, idx, f"DSP_{length}", "cycles", offset)
|
||||
|
||||
|
||||
def ccor(close: object, length: int = 20, alpha: float = 0.07,
|
||||
offset: int = 0, **kwargs) -> object:
|
||||
"""Circular Correlation."""
|
||||
length = int(length); offset = int(offset)
|
||||
src, idx = _arr(close); n = len(src); dst = _out(n)
|
||||
_check(_lib.qtl_ccor(_ptr(src), n, _ptr(dst), length, float(alpha)))
|
||||
return _wrap(dst, idx, f"CCOR_{length}", "cycles", offset)
|
||||
|
||||
|
||||
def ebsw(close: object, hp_length: int = 40, ssf_length: int = 10,
|
||||
offset: int = 0, **kwargs) -> object:
|
||||
"""Even Better Sinewave."""
|
||||
hp_length = int(hp_length); ssf_length = int(ssf_length); offset = int(offset)
|
||||
src, idx = _arr(close); n = len(src); dst = _out(n)
|
||||
_check(_lib.qtl_ebsw(_ptr(src), n, _ptr(dst), hp_length, ssf_length))
|
||||
return _wrap(dst, idx, f"EBSW_{hp_length}", "cycles", offset)
|
||||
|
||||
|
||||
def eacp(close: object, min_period: int = 8, max_period: int = 48,
|
||||
avg_length: int = 3, enhance: int = 1,
|
||||
offset: int = 0, **kwargs) -> object:
|
||||
"""Ehlers Autocorrelation Periodogram."""
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close); n = len(src); dst = _out(n)
|
||||
_check(_lib.qtl_eacp(_ptr(src), n, _ptr(dst), int(min_period), int(max_period), int(avg_length), int(enhance)))
|
||||
return _wrap(dst, idx, f"EACP_{min_period}_{max_period}", "cycles", offset)
|
||||
@@ -0,0 +1,295 @@
|
||||
"""quantalib dynamics indicators.
|
||||
|
||||
Auto-generated — DO NOT EDIT.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
from ._helpers import _arr, _ptr, _out, _wrap, _wrap_multi, _check, _lib
|
||||
|
||||
|
||||
__all__ = [
|
||||
"adx",
|
||||
"adxr",
|
||||
"alligator",
|
||||
"amat",
|
||||
"aroon",
|
||||
"aroonosc",
|
||||
"chop",
|
||||
"dmx",
|
||||
"dx",
|
||||
"ghla",
|
||||
"ht_trendmode",
|
||||
"ichimoku",
|
||||
"impulse",
|
||||
"pfe",
|
||||
"qstick",
|
||||
"ravi",
|
||||
"supertrend",
|
||||
"ttm_squeeze",
|
||||
"ttm_trend",
|
||||
"vhf",
|
||||
"vortex",
|
||||
]
|
||||
|
||||
|
||||
def adx(high: object, low: object, close: object, period: int = 14, offset: int = 0, **kwargs) -> object:
|
||||
"""Average Directional Index."""
|
||||
period = int(period)
|
||||
offset = int(offset)
|
||||
h, idx = _arr(high); l, _ = _arr(low); c, _ = _arr(close)
|
||||
n = len(h)
|
||||
destination = _out(n)
|
||||
_check(_lib.qtl_adx(_ptr(h), _ptr(l), _ptr(c), period, n, _ptr(destination)))
|
||||
return _wrap(destination, idx, f"ADX_{period}", "dynamics", offset)
|
||||
|
||||
|
||||
def adxr(high: object, low: object, close: object, period: int = 14, offset: int = 0, **kwargs) -> object:
|
||||
"""ADX Rating."""
|
||||
period = int(period)
|
||||
offset = int(offset)
|
||||
h, idx = _arr(high); l, _ = _arr(low); c, _ = _arr(close)
|
||||
n = len(h)
|
||||
destination = _out(n)
|
||||
_check(_lib.qtl_adxr(_ptr(h), _ptr(l), _ptr(c), period, n, _ptr(destination)))
|
||||
return _wrap(destination, idx, f"ADXR_{period}", "dynamics", offset)
|
||||
|
||||
|
||||
def alligator(open: object, high: object, low: object, close: object, volume: object, jawPeriod: int = 13, jawOffset: int = 8, teethPeriod: int = 8, teethOffset: int = 5, lipsPeriod: int = 5, lipsOffset: int = 3, offset: int = 0, **kwargs) -> object:
|
||||
"""Williams Alligator."""
|
||||
jawPeriod = int(jawPeriod)
|
||||
jawOffset = int(jawOffset)
|
||||
teethPeriod = int(teethPeriod)
|
||||
teethOffset = int(teethOffset)
|
||||
lipsPeriod = int(lipsPeriod)
|
||||
lipsOffset = int(lipsOffset)
|
||||
offset = int(offset)
|
||||
o, idx = _arr(open); h, _ = _arr(high); l, _ = _arr(low)
|
||||
c, _ = _arr(close); v, _ = _arr(volume)
|
||||
n = len(o)
|
||||
dst = _out(n)
|
||||
_check(_lib.qtl_alligator(_ptr(o), _ptr(h), _ptr(l), _ptr(c), _ptr(v), jawPeriod, jawOffset, teethPeriod, teethOffset, lipsPeriod, lipsOffset, n, _ptr(dst)))
|
||||
return _wrap(dst, idx, f"ALLIGATOR_{jawPeriod}", "dynamics", offset)
|
||||
|
||||
|
||||
def amat(close: object, fastPeriod: int = 12, slowPeriod: int = 26, offset: int = 0, **kwargs) -> object:
|
||||
"""Archer Moving Average Trends."""
|
||||
fastPeriod = int(fastPeriod)
|
||||
slowPeriod = int(slowPeriod)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
trend = _out(n)
|
||||
strength = _out(n)
|
||||
_check(_lib.qtl_amat(_ptr(src), _ptr(trend), _ptr(strength), n, fastPeriod, slowPeriod))
|
||||
return _wrap_multi({"trend": trend, "strength": strength}, idx, "dynamics", offset)
|
||||
|
||||
|
||||
def aroon(high: object, low: object, period: int = 14, offset: int = 0, **kwargs) -> object:
|
||||
"""Aroon."""
|
||||
period = int(period)
|
||||
offset = int(offset)
|
||||
h, idx = _arr(high); l, _ = _arr(low)
|
||||
n = len(h)
|
||||
destination = _out(n)
|
||||
_check(_lib.qtl_aroon(_ptr(h), _ptr(l), period, n, _ptr(destination)))
|
||||
return _wrap(destination, idx, f"AROON_{period}", "dynamics", offset)
|
||||
|
||||
|
||||
def aroonosc(high: object, low: object, period: int = 14, offset: int = 0, **kwargs) -> object:
|
||||
"""Aroon Oscillator."""
|
||||
period = int(period)
|
||||
offset = int(offset)
|
||||
h, idx = _arr(high); l, _ = _arr(low)
|
||||
n = len(h)
|
||||
destination = _out(n)
|
||||
_check(_lib.qtl_aroonosc(_ptr(h), _ptr(l), period, n, _ptr(destination)))
|
||||
return _wrap(destination, idx, f"AROONOSC_{period}", "dynamics", offset)
|
||||
|
||||
|
||||
def chop(open: object, high: object, low: object, close: object, volume: object, period: int = 14, offset: int = 0, **kwargs) -> object:
|
||||
"""Choppiness Index."""
|
||||
period = int(period)
|
||||
offset = int(offset)
|
||||
o, idx = _arr(open); h, _ = _arr(high); l, _ = _arr(low)
|
||||
c, _ = _arr(close); v, _ = _arr(volume)
|
||||
n = len(o)
|
||||
dst = _out(n)
|
||||
_check(_lib.qtl_chop(_ptr(o), _ptr(h), _ptr(l), _ptr(c), _ptr(v), period, n, _ptr(dst)))
|
||||
return _wrap(dst, idx, f"CHOP_{period}", "dynamics", offset)
|
||||
|
||||
|
||||
def dmx(high: object, low: object, close: object, period: int = 14, offset: int = 0, **kwargs) -> object:
|
||||
"""Directional Movement Extended."""
|
||||
period = int(period)
|
||||
offset = int(offset)
|
||||
h, idx = _arr(high); l, _ = _arr(low); c, _ = _arr(close)
|
||||
n = len(h)
|
||||
destination = _out(n)
|
||||
_check(_lib.qtl_dmx(_ptr(h), _ptr(l), _ptr(c), period, n, _ptr(destination)))
|
||||
return _wrap(destination, idx, f"DMX_{period}", "dynamics", offset)
|
||||
|
||||
|
||||
def dx(high: object, low: object, close: object, period: int = 14, offset: int = 0, **kwargs) -> object:
|
||||
"""Directional Movement Index."""
|
||||
period = int(period)
|
||||
offset = int(offset)
|
||||
h, idx = _arr(high); l, _ = _arr(low); c, _ = _arr(close)
|
||||
n = len(h)
|
||||
destination = _out(n)
|
||||
_check(_lib.qtl_dx(_ptr(h), _ptr(l), _ptr(c), period, n, _ptr(destination)))
|
||||
return _wrap(destination, idx, f"DX_{period}", "dynamics", offset)
|
||||
|
||||
|
||||
def ghla(high: object, low: object, close: object, period: int = 14, offset: int = 0, **kwargs) -> object:
|
||||
"""Gann Hi-Lo Activator."""
|
||||
period = int(period)
|
||||
offset = int(offset)
|
||||
h, idx = _arr(high); l, _ = _arr(low); c, _ = _arr(close)
|
||||
n = len(h)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_ghla(_ptr(h), _ptr(l), _ptr(c), _ptr(output), n, period))
|
||||
return _wrap(output, idx, f"GHLA_{period}", "dynamics", offset)
|
||||
|
||||
|
||||
def ht_trendmode(close: object, offset: int = 0, **kwargs) -> object:
|
||||
"""Hilbert Transform Trend Mode."""
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_httrendmode(_ptr(src), _ptr(output), n))
|
||||
return _wrap(output, idx, "HT_TRENDMODE", "dynamics", offset)
|
||||
|
||||
|
||||
def ichimoku(open: object, high: object, low: object, close: object, volume: object, tenkanPeriod: int = 9, kijunPeriod: int = 26, senkouBPeriod: int = 52, displacement: int = 26, offset: int = 0, **kwargs) -> object:
|
||||
"""Ichimoku Cloud."""
|
||||
tenkanPeriod = int(tenkanPeriod)
|
||||
kijunPeriod = int(kijunPeriod)
|
||||
senkouBPeriod = int(senkouBPeriod)
|
||||
displacement = int(displacement)
|
||||
offset = int(offset)
|
||||
o, idx = _arr(open); h, _ = _arr(high); l, _ = _arr(low)
|
||||
c, _ = _arr(close); v, _ = _arr(volume)
|
||||
n = len(o)
|
||||
dstTenkan = _out(n)
|
||||
dstKijun = _out(n)
|
||||
dstSenkouA = _out(n)
|
||||
dstSenkouB = _out(n)
|
||||
dstChikou = _out(n)
|
||||
_check(_lib.qtl_ichimoku(_ptr(o), _ptr(h), _ptr(l), _ptr(c), _ptr(v), tenkanPeriod, kijunPeriod, senkouBPeriod, displacement, n, _ptr(dstTenkan), _ptr(dstKijun), _ptr(dstSenkouA), _ptr(dstSenkouB), _ptr(dstChikou)))
|
||||
return _wrap_multi({"dstTenkan": dstTenkan, "dstKijun": dstKijun, "dstSenkouA": dstSenkouA, "dstSenkouB": dstSenkouB, "dstChikou": dstChikou}, idx, "dynamics", offset)
|
||||
|
||||
|
||||
def impulse(close: object, emaPeriod: int = 13, macdFast: int = 12, macdSlow: int = 26, macdSignal: int = 9, offset: int = 0, **kwargs) -> object:
|
||||
"""Elder Impulse System."""
|
||||
emaPeriod = int(emaPeriod)
|
||||
macdFast = int(macdFast)
|
||||
macdSlow = int(macdSlow)
|
||||
macdSignal = int(macdSignal)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
dst = _out(n)
|
||||
_check(_lib.qtl_impulse(_ptr(src), emaPeriod, macdFast, macdSlow, macdSignal, n, _ptr(dst)))
|
||||
return _wrap(dst, idx, f"IMPULSE_{emaPeriod}", "dynamics", offset)
|
||||
|
||||
|
||||
def pfe(close: object, period: int = 14, smoothPeriod: int = 5, offset: int = 0, **kwargs) -> object:
|
||||
"""Polarized Fractal Efficiency."""
|
||||
period = int(period)
|
||||
smoothPeriod = int(smoothPeriod)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_pfe(_ptr(src), _ptr(output), n, period, smoothPeriod))
|
||||
return _wrap(output, idx, f"PFE_{period}", "dynamics", offset)
|
||||
|
||||
|
||||
def qstick(open: object, high: object, low: object, close: object, volume: object, period: int = 14, useEma: int = 0, offset: int = 0, **kwargs) -> object:
|
||||
"""QStick."""
|
||||
period = int(period)
|
||||
useEma = int(useEma)
|
||||
offset = int(offset)
|
||||
o, idx = _arr(open); h, _ = _arr(high); l, _ = _arr(low)
|
||||
c, _ = _arr(close); v, _ = _arr(volume)
|
||||
n = len(o)
|
||||
dst = _out(n)
|
||||
_check(_lib.qtl_qstick(_ptr(o), _ptr(h), _ptr(l), _ptr(c), _ptr(v), period, useEma, n, _ptr(dst)))
|
||||
return _wrap(dst, idx, f"QSTICK_{period}", "dynamics", offset)
|
||||
|
||||
|
||||
def ravi(close: object, shortPeriod: int = 12, longPeriod: int = 26, offset: int = 0, **kwargs) -> object:
|
||||
"""Range Action Verification Index."""
|
||||
shortPeriod = int(shortPeriod)
|
||||
longPeriod = int(longPeriod)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_ravi(_ptr(src), _ptr(output), n, shortPeriod, longPeriod))
|
||||
return _wrap(output, idx, f"RAVI_{shortPeriod}", "dynamics", offset)
|
||||
|
||||
|
||||
def supertrend(open: object, high: object, low: object, close: object, volume: object, period: int = 14, multiplier: float = 2.0, offset: int = 0, **kwargs) -> object:
|
||||
"""SuperTrend."""
|
||||
period = int(period)
|
||||
multiplier = float(multiplier)
|
||||
offset = int(offset)
|
||||
o, idx = _arr(open); h, _ = _arr(high); l, _ = _arr(low)
|
||||
c, _ = _arr(close); v, _ = _arr(volume)
|
||||
n = len(o)
|
||||
dst = _out(n)
|
||||
_check(_lib.qtl_super(_ptr(o), _ptr(h), _ptr(l), _ptr(c), _ptr(v), period, multiplier, n, _ptr(dst)))
|
||||
return _wrap(dst, idx, f"SUPER_{period}", "dynamics", offset)
|
||||
|
||||
|
||||
def ttm_squeeze(open: object, high: object, low: object, close: object, volume: object, bbPeriod: int = 20, bbMult: float = 2.0, kcPeriod: int = 10, kcMult: float = 1.5, momPeriod: int = 12, offset: int = 0, **kwargs) -> object:
|
||||
"""TTM Squeeze."""
|
||||
bbPeriod = int(bbPeriod)
|
||||
bbMult = float(bbMult)
|
||||
kcPeriod = int(kcPeriod)
|
||||
kcMult = float(kcMult)
|
||||
momPeriod = int(momPeriod)
|
||||
offset = int(offset)
|
||||
o, idx = _arr(open); h, _ = _arr(high); l, _ = _arr(low)
|
||||
c, _ = _arr(close); v, _ = _arr(volume)
|
||||
n = len(o)
|
||||
dst = _out(n)
|
||||
_check(_lib.qtl_ttmsqueeze(_ptr(o), _ptr(h), _ptr(l), _ptr(c), _ptr(v), bbPeriod, bbMult, kcPeriod, kcMult, momPeriod, n, _ptr(dst)))
|
||||
return _wrap(dst, idx, f"TTM_SQUEEZE_{bbPeriod}", "dynamics", offset)
|
||||
|
||||
|
||||
def ttm_trend(open: object, high: object, low: object, close: object, volume: object, period: int = 14, offset: int = 0, **kwargs) -> object:
|
||||
"""TTM Trend."""
|
||||
period = int(period)
|
||||
offset = int(offset)
|
||||
o, idx = _arr(open); h, _ = _arr(high); l, _ = _arr(low)
|
||||
c, _ = _arr(close); v, _ = _arr(volume)
|
||||
n = len(o)
|
||||
dst = _out(n)
|
||||
_check(_lib.qtl_ttmtrend(_ptr(o), _ptr(h), _ptr(l), _ptr(c), _ptr(v), period, n, _ptr(dst)))
|
||||
return _wrap(dst, idx, f"TTM_TREND_{period}", "dynamics", offset)
|
||||
|
||||
|
||||
def vhf(close: object, period: int = 14, offset: int = 0, **kwargs) -> object:
|
||||
"""Vertical Horizontal Filter."""
|
||||
period = int(period)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_vhf(_ptr(src), _ptr(output), n, period))
|
||||
return _wrap(output, idx, f"VHF_{period}", "dynamics", offset)
|
||||
|
||||
|
||||
def vortex(high: object, low: object, close: object, period: int = 14, offset: int = 0, **kwargs) -> object:
|
||||
"""Vortex Indicator."""
|
||||
period = int(period)
|
||||
offset = int(offset)
|
||||
h, idx = _arr(high); l, _ = _arr(low); c, _ = _arr(close)
|
||||
n = len(h)
|
||||
viPlus = _out(n)
|
||||
viMinus = _out(n)
|
||||
_check(_lib.qtl_vortex(_ptr(h), _ptr(l), _ptr(c), period, _ptr(viPlus), n, _ptr(viMinus)))
|
||||
return _wrap_multi({"viPlus": viPlus, "viMinus": viMinus}, idx, "dynamics", offset)
|
||||
@@ -0,0 +1,322 @@
|
||||
"""quantalib errors indicators.
|
||||
|
||||
Auto-generated — DO NOT EDIT.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
from ._helpers import _arr, _ptr, _out, _wrap, _wrap_multi, _check, _lib
|
||||
|
||||
|
||||
__all__ = [
|
||||
"huber",
|
||||
"logcosh",
|
||||
"maape",
|
||||
"mapd",
|
||||
"mase",
|
||||
"mdae",
|
||||
"mdape",
|
||||
"me",
|
||||
"mpe",
|
||||
"mrae",
|
||||
"msle",
|
||||
"pseudohuber",
|
||||
"quantileloss",
|
||||
"rae",
|
||||
"rmsle",
|
||||
"rse",
|
||||
"rsquared",
|
||||
"smape",
|
||||
"theilu",
|
||||
"tukeybiweight",
|
||||
"wmape",
|
||||
"wrmse",
|
||||
"mse",
|
||||
"rmse",
|
||||
"mae",
|
||||
"mape",
|
||||
]
|
||||
|
||||
|
||||
def huber(actual: object, predicted: object, period: int = 14, delta: float = 1.35, offset: int = 0, **kwargs) -> object:
|
||||
"""Huber Loss."""
|
||||
period = int(period)
|
||||
delta = float(delta)
|
||||
offset = int(offset)
|
||||
a, idx = _arr(actual); p, _ = _arr(predicted)
|
||||
n = len(a)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_huber(_ptr(a), _ptr(p), _ptr(output), n, period, delta))
|
||||
return _wrap(output, idx, f"HUBER_{period}", "errors", offset)
|
||||
|
||||
|
||||
def logcosh(actual: object, predicted: object, period: int = 14, offset: int = 0, **kwargs) -> object:
|
||||
"""Log-Cosh Loss."""
|
||||
period = int(period)
|
||||
offset = int(offset)
|
||||
a, idx = _arr(actual); p, _ = _arr(predicted)
|
||||
n = len(a)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_logcosh(_ptr(a), _ptr(p), _ptr(output), n, period))
|
||||
return _wrap(output, idx, f"LOGCOSH_{period}", "errors", offset)
|
||||
|
||||
|
||||
def maape(actual: object, predicted: object, period: int = 14, offset: int = 0, **kwargs) -> object:
|
||||
"""Mean Arctangent Absolute Percentage Error."""
|
||||
period = int(period)
|
||||
offset = int(offset)
|
||||
a, idx = _arr(actual); p, _ = _arr(predicted)
|
||||
n = len(a)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_maape(_ptr(a), _ptr(p), _ptr(output), n, period))
|
||||
return _wrap(output, idx, f"MAAPE_{period}", "errors", offset)
|
||||
|
||||
|
||||
def mapd(actual: object, predicted: object, period: int = 14, offset: int = 0, **kwargs) -> object:
|
||||
"""Mean Absolute Percentage Deviation."""
|
||||
period = int(period)
|
||||
offset = int(offset)
|
||||
a, idx = _arr(actual); p, _ = _arr(predicted)
|
||||
n = len(a)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_mapd(_ptr(a), _ptr(p), _ptr(output), n, period))
|
||||
return _wrap(output, idx, f"MAPD_{period}", "errors", offset)
|
||||
|
||||
|
||||
def mase(actual: object, predicted: object, period: int = 14, offset: int = 0, **kwargs) -> object:
|
||||
"""Mean Absolute Scaled Error."""
|
||||
period = int(period)
|
||||
offset = int(offset)
|
||||
a, idx = _arr(actual); p, _ = _arr(predicted)
|
||||
n = len(a)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_mase(_ptr(a), _ptr(p), _ptr(output), n, period))
|
||||
return _wrap(output, idx, f"MASE_{period}", "errors", offset)
|
||||
|
||||
|
||||
def mdae(actual: object, predicted: object, period: int = 14, offset: int = 0, **kwargs) -> object:
|
||||
"""Median Absolute Error."""
|
||||
period = int(period)
|
||||
offset = int(offset)
|
||||
a, idx = _arr(actual); p, _ = _arr(predicted)
|
||||
n = len(a)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_mdae(_ptr(a), _ptr(p), _ptr(output), n, period))
|
||||
return _wrap(output, idx, f"MDAE_{period}", "errors", offset)
|
||||
|
||||
|
||||
def mdape(actual: object, predicted: object, period: int = 14, offset: int = 0, **kwargs) -> object:
|
||||
"""Median Absolute Percentage Error."""
|
||||
period = int(period)
|
||||
offset = int(offset)
|
||||
a, idx = _arr(actual); p, _ = _arr(predicted)
|
||||
n = len(a)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_mdape(_ptr(a), _ptr(p), _ptr(output), n, period))
|
||||
return _wrap(output, idx, f"MDAPE_{period}", "errors", offset)
|
||||
|
||||
|
||||
def me(actual: object, predicted: object, period: int = 14, offset: int = 0, **kwargs) -> object:
|
||||
"""Mean Error."""
|
||||
period = int(period)
|
||||
offset = int(offset)
|
||||
a, idx = _arr(actual); p, _ = _arr(predicted)
|
||||
n = len(a)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_me(_ptr(a), _ptr(p), _ptr(output), n, period))
|
||||
return _wrap(output, idx, f"ME_{period}", "errors", offset)
|
||||
|
||||
|
||||
def mpe(actual: object, predicted: object, period: int = 14, offset: int = 0, **kwargs) -> object:
|
||||
"""Mean Percentage Error."""
|
||||
period = int(period)
|
||||
offset = int(offset)
|
||||
a, idx = _arr(actual); p, _ = _arr(predicted)
|
||||
n = len(a)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_mpe(_ptr(a), _ptr(p), _ptr(output), n, period))
|
||||
return _wrap(output, idx, f"MPE_{period}", "errors", offset)
|
||||
|
||||
|
||||
def mrae(actual: object, predicted: object, period: int = 14, offset: int = 0, **kwargs) -> object:
|
||||
"""Mean Relative Absolute Error."""
|
||||
period = int(period)
|
||||
offset = int(offset)
|
||||
a, idx = _arr(actual); p, _ = _arr(predicted)
|
||||
n = len(a)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_mrae(_ptr(a), _ptr(p), _ptr(output), n, period))
|
||||
return _wrap(output, idx, f"MRAE_{period}", "errors", offset)
|
||||
|
||||
|
||||
def msle(actual: object, predicted: object, period: int = 14, offset: int = 0, **kwargs) -> object:
|
||||
"""Mean Squared Logarithmic Error."""
|
||||
period = int(period)
|
||||
offset = int(offset)
|
||||
a, idx = _arr(actual); p, _ = _arr(predicted)
|
||||
n = len(a)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_msle(_ptr(a), _ptr(p), _ptr(output), n, period))
|
||||
return _wrap(output, idx, f"MSLE_{period}", "errors", offset)
|
||||
|
||||
|
||||
def pseudohuber(actual: object, predicted: object, period: int = 14, delta: float = 1.35, offset: int = 0, **kwargs) -> object:
|
||||
"""Pseudo-Huber Loss."""
|
||||
period = int(period)
|
||||
delta = float(delta)
|
||||
offset = int(offset)
|
||||
a, idx = _arr(actual); p, _ = _arr(predicted)
|
||||
n = len(a)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_pseudohuber(_ptr(a), _ptr(p), _ptr(output), n, period, delta))
|
||||
return _wrap(output, idx, f"PSEUDOHUBER_{period}", "errors", offset)
|
||||
|
||||
|
||||
def quantileloss(actual: object, predicted: object, period: int = 14, quantile: float = 0.5, offset: int = 0, **kwargs) -> object:
|
||||
"""Quantile Loss (Pinball Loss)."""
|
||||
period = int(period)
|
||||
quantile = float(quantile)
|
||||
offset = int(offset)
|
||||
a, idx = _arr(actual); p, _ = _arr(predicted)
|
||||
n = len(a)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_quantileloss(_ptr(a), _ptr(p), _ptr(output), n, period, quantile))
|
||||
return _wrap(output, idx, f"QUANTILELOSS_{period}", "errors", offset)
|
||||
|
||||
|
||||
def rae(actual: object, predicted: object, period: int = 14, offset: int = 0, **kwargs) -> object:
|
||||
"""Relative Absolute Error."""
|
||||
period = int(period)
|
||||
offset = int(offset)
|
||||
a, idx = _arr(actual); p, _ = _arr(predicted)
|
||||
n = len(a)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_rae(_ptr(a), _ptr(p), _ptr(output), n, period))
|
||||
return _wrap(output, idx, f"RAE_{period}", "errors", offset)
|
||||
|
||||
|
||||
def rmsle(actual: object, predicted: object, period: int = 14, offset: int = 0, **kwargs) -> object:
|
||||
"""Root Mean Squared Logarithmic Error."""
|
||||
period = int(period)
|
||||
offset = int(offset)
|
||||
a, idx = _arr(actual); p, _ = _arr(predicted)
|
||||
n = len(a)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_rmsle(_ptr(a), _ptr(p), _ptr(output), n, period))
|
||||
return _wrap(output, idx, f"RMSLE_{period}", "errors", offset)
|
||||
|
||||
|
||||
def rse(actual: object, predicted: object, period: int = 14, offset: int = 0, **kwargs) -> object:
|
||||
"""Relative Squared Error."""
|
||||
period = int(period)
|
||||
offset = int(offset)
|
||||
a, idx = _arr(actual); p, _ = _arr(predicted)
|
||||
n = len(a)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_rse(_ptr(a), _ptr(p), _ptr(output), n, period))
|
||||
return _wrap(output, idx, f"RSE_{period}", "errors", offset)
|
||||
|
||||
|
||||
def rsquared(actual: object, predicted: object, period: int = 14, offset: int = 0, **kwargs) -> object:
|
||||
"""R-Squared (Coefficient of Determination)."""
|
||||
period = int(period)
|
||||
offset = int(offset)
|
||||
a, idx = _arr(actual); p, _ = _arr(predicted)
|
||||
n = len(a)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_rsquared(_ptr(a), _ptr(p), _ptr(output), n, period))
|
||||
return _wrap(output, idx, f"RSQUARED_{period}", "errors", offset)
|
||||
|
||||
|
||||
def smape(actual: object, predicted: object, period: int = 14, offset: int = 0, **kwargs) -> object:
|
||||
"""Symmetric Mean Absolute Percentage Error."""
|
||||
period = int(period)
|
||||
offset = int(offset)
|
||||
a, idx = _arr(actual); p, _ = _arr(predicted)
|
||||
n = len(a)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_smape(_ptr(a), _ptr(p), _ptr(output), n, period))
|
||||
return _wrap(output, idx, f"SMAPE_{period}", "errors", offset)
|
||||
|
||||
|
||||
def theilu(actual: object, predicted: object, period: int = 14, offset: int = 0, **kwargs) -> object:
|
||||
"""Theil U Statistic (Error)."""
|
||||
period = int(period)
|
||||
offset = int(offset)
|
||||
a, idx = _arr(actual); p, _ = _arr(predicted)
|
||||
n = len(a)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_theilu(_ptr(a), _ptr(p), _ptr(output), n, period))
|
||||
return _wrap(output, idx, f"THEILU_{period}", "errors", offset)
|
||||
|
||||
|
||||
def tukeybiweight(actual: object, predicted: object, period: int = 14, c: float = 4.685, offset: int = 0, **kwargs) -> object:
|
||||
"""Tukey Biweight Loss."""
|
||||
period = int(period)
|
||||
c = float(c)
|
||||
offset = int(offset)
|
||||
a, idx = _arr(actual); p, _ = _arr(predicted)
|
||||
n = len(a)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_tukeybiweight(_ptr(a), _ptr(p), _ptr(output), n, period, c))
|
||||
return _wrap(output, idx, f"TUKEYBIWEIGHT_{period}", "errors", offset)
|
||||
|
||||
|
||||
def wmape(actual: object, predicted: object, period: int = 14, offset: int = 0, **kwargs) -> object:
|
||||
"""Weighted Mean Absolute Percentage Error."""
|
||||
period = int(period)
|
||||
offset = int(offset)
|
||||
a, idx = _arr(actual); p, _ = _arr(predicted)
|
||||
n = len(a)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_wmape(_ptr(a), _ptr(p), _ptr(output), n, period))
|
||||
return _wrap(output, idx, f"WMAPE_{period}", "errors", offset)
|
||||
|
||||
|
||||
def wrmse(actual: object, predicted: object, period: int = 14, offset: int = 0, **kwargs) -> object:
|
||||
"""Weighted Root Mean Squared Error."""
|
||||
period = int(period)
|
||||
offset = int(offset)
|
||||
a, idx = _arr(actual); p, _ = _arr(predicted)
|
||||
n = len(a)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_wrmse(_ptr(a), _ptr(p), _ptr(output), n, period))
|
||||
return _wrap(output, idx, f"WRMSE_{period}", "errors", offset)
|
||||
|
||||
def mse(actual: object, predicted: object, length: int = 20,
|
||||
offset: int = 0, **kwargs) -> object:
|
||||
"""Mean Squared Error."""
|
||||
length = int(length); offset = int(offset)
|
||||
a, idx = _arr(actual); p, _ = _arr(predicted)
|
||||
n = len(a); dst = _out(n)
|
||||
_check(_lib.qtl_mse(_ptr(a), _ptr(p), n, _ptr(dst), length))
|
||||
return _wrap(dst, idx, f"MSE_{length}", "errors", offset)
|
||||
|
||||
|
||||
def rmse(actual: object, predicted: object, length: int = 20,
|
||||
offset: int = 0, **kwargs) -> object:
|
||||
"""Root Mean Squared Error."""
|
||||
length = int(length); offset = int(offset)
|
||||
a, idx = _arr(actual); p, _ = _arr(predicted)
|
||||
n = len(a); dst = _out(n)
|
||||
_check(_lib.qtl_rmse(_ptr(a), _ptr(p), n, _ptr(dst), length))
|
||||
return _wrap(dst, idx, f"RMSE_{length}", "errors", offset)
|
||||
|
||||
|
||||
def mae(actual: object, predicted: object, length: int = 20,
|
||||
offset: int = 0, **kwargs) -> object:
|
||||
"""Mean Absolute Error."""
|
||||
length = int(length); offset = int(offset)
|
||||
a, idx = _arr(actual); p, _ = _arr(predicted)
|
||||
n = len(a); dst = _out(n)
|
||||
_check(_lib.qtl_mae(_ptr(a), _ptr(p), n, _ptr(dst), length))
|
||||
return _wrap(dst, idx, f"MAE_{length}", "errors", offset)
|
||||
|
||||
|
||||
def mape(actual: object, predicted: object, length: int = 20,
|
||||
offset: int = 0, **kwargs) -> object:
|
||||
"""Mean Absolute Percentage Error."""
|
||||
length = int(length); offset = int(offset)
|
||||
a, idx = _arr(actual); p, _ = _arr(predicted)
|
||||
n = len(a); dst = _out(n)
|
||||
_check(_lib.qtl_mape(_ptr(a), _ptr(p), n, _ptr(dst), length))
|
||||
return _wrap(dst, idx, f"MAPE_{length}", "errors", offset)
|
||||
@@ -0,0 +1,422 @@
|
||||
"""quantalib filters indicators.
|
||||
|
||||
Auto-generated — DO NOT EDIT.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
from ._helpers import _arr, _ptr, _out, _wrap, _wrap_multi, _check, _lib
|
||||
|
||||
|
||||
__all__ = [
|
||||
"gauss",
|
||||
"hann",
|
||||
"hp",
|
||||
"hpf",
|
||||
"kalman",
|
||||
"laguerre",
|
||||
"lms",
|
||||
"loess",
|
||||
"modf",
|
||||
"notch",
|
||||
"nw",
|
||||
"oneeuro",
|
||||
"rls",
|
||||
"rmed",
|
||||
"roofing",
|
||||
"sgf",
|
||||
"spbf",
|
||||
"ssf2",
|
||||
"ssf3",
|
||||
"usf",
|
||||
"voss",
|
||||
"wavelet",
|
||||
"wiener",
|
||||
"bessel",
|
||||
"butter2",
|
||||
"butter3",
|
||||
"cheby1",
|
||||
"cheby2",
|
||||
"elliptic",
|
||||
"edcf",
|
||||
"bpf",
|
||||
"alaguerre",
|
||||
"bilateral",
|
||||
"baxterking",
|
||||
"cfitz",
|
||||
]
|
||||
|
||||
|
||||
def gauss(close: object, sigma: float = 6.0, offset: int = 0, **kwargs) -> object:
|
||||
"""Gaussian Filter."""
|
||||
sigma = float(sigma)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_gauss(_ptr(src), _ptr(output), n, sigma))
|
||||
return _wrap(output, idx, "GAUSS", "filters", offset)
|
||||
|
||||
|
||||
def hann(close: object, length: int = 14, offset: int = 0, **kwargs) -> object:
|
||||
"""Hann Filter."""
|
||||
length = int(length)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_hann(_ptr(src), _ptr(output), n, length))
|
||||
return _wrap(output, idx, f"HANN_{length}", "filters", offset)
|
||||
|
||||
|
||||
def hp(close: object, lam: float = 1600.0, offset: int = 0, **kwargs) -> object:
|
||||
"""Hodrick-Prescott Filter."""
|
||||
lam = float(lam)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_hp(_ptr(src), _ptr(output), n, lam))
|
||||
return _wrap(output, idx, "HP", "filters", offset)
|
||||
|
||||
|
||||
def hpf(close: object, length: int = 14, offset: int = 0, **kwargs) -> object:
|
||||
"""High-Pass Filter."""
|
||||
length = int(length)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_hpf(_ptr(src), _ptr(output), n, length))
|
||||
return _wrap(output, idx, f"HPF_{length}", "filters", offset)
|
||||
|
||||
|
||||
def kalman(close: object, q: float = 0.3, r: float = 1.0, offset: int = 0, **kwargs) -> object:
|
||||
"""Kalman Filter."""
|
||||
q = float(q)
|
||||
r = float(r)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_kalman(_ptr(src), _ptr(output), n, q, r))
|
||||
return _wrap(output, idx, "KALMAN", "filters", offset)
|
||||
|
||||
|
||||
def laguerre(close: object, gamma: float = 0.7, offset: int = 0, **kwargs) -> object:
|
||||
"""Laguerre Filter."""
|
||||
gamma = float(gamma)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_laguerre(_ptr(src), _ptr(output), n, gamma))
|
||||
return _wrap(output, idx, "LAGUERRE", "filters", offset)
|
||||
|
||||
|
||||
def lms(close: object, order: int = 3, mu: float = 0.01, offset: int = 0, **kwargs) -> object:
|
||||
"""Least Mean Squares Filter."""
|
||||
order = int(order)
|
||||
mu = float(mu)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_lms(_ptr(src), _ptr(output), n, order, mu))
|
||||
return _wrap(output, idx, "LMS", "filters", offset)
|
||||
|
||||
|
||||
def loess(close: object, period: int = 14, offset: int = 0, **kwargs) -> object:
|
||||
"""LOESS Smoother."""
|
||||
period = int(period)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_loess(_ptr(src), _ptr(output), n, period))
|
||||
return _wrap(output, idx, f"LOESS_{period}", "filters", offset)
|
||||
|
||||
|
||||
def modf(close: object, period: int = 14, beta: float = 2.0, feedback: int = 0, fbWeight: float = 0.5, offset: int = 0, **kwargs) -> object:
|
||||
"""Modified Filter."""
|
||||
period = int(period)
|
||||
beta = float(beta)
|
||||
feedback = int(feedback)
|
||||
fbWeight = float(fbWeight)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_modf(_ptr(src), _ptr(output), n, period, beta, feedback, fbWeight))
|
||||
return _wrap(output, idx, f"MODF_{period}", "filters", offset)
|
||||
|
||||
|
||||
def notch(close: object, period: int = 14, q: float = 0.3, offset: int = 0, **kwargs) -> object:
|
||||
"""Notch Filter."""
|
||||
period = int(period)
|
||||
q = float(q)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_notch(_ptr(src), _ptr(output), n, period, q))
|
||||
return _wrap(output, idx, f"NOTCH_{period}", "filters", offset)
|
||||
|
||||
|
||||
def nw(close: object, period: int = 14, bandwidth: float = 0.25, offset: int = 0, **kwargs) -> object:
|
||||
"""Nadaraya-Watson Filter."""
|
||||
period = int(period)
|
||||
bandwidth = float(bandwidth)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_nw(_ptr(src), _ptr(output), n, period, bandwidth))
|
||||
return _wrap(output, idx, f"NW_{period}", "filters", offset)
|
||||
|
||||
|
||||
def oneeuro(close: object, minCutoff: float = 1.0, beta: float = 2.0, dCutoff: float = 1.0, offset: int = 0, **kwargs) -> object:
|
||||
"""1€ Filter."""
|
||||
minCutoff = float(minCutoff)
|
||||
beta = float(beta)
|
||||
dCutoff = float(dCutoff)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_oneeuro(_ptr(src), _ptr(output), n, minCutoff, beta, dCutoff))
|
||||
return _wrap(output, idx, "ONEEURO", "filters", offset)
|
||||
|
||||
|
||||
def rls(close: object, order: int = 3, lam: float = 1600.0, offset: int = 0, **kwargs) -> object:
|
||||
"""Recursive Least Squares Filter."""
|
||||
order = int(order)
|
||||
lam = float(lam)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_rls(_ptr(src), _ptr(output), n, order, lam))
|
||||
return _wrap(output, idx, "RLS", "filters", offset)
|
||||
|
||||
|
||||
def rmed(close: object, period: int = 14, offset: int = 0, **kwargs) -> object:
|
||||
"""Running Median Filter."""
|
||||
period = int(period)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_rmed(_ptr(src), _ptr(output), n, period))
|
||||
return _wrap(output, idx, f"RMED_{period}", "filters", offset)
|
||||
|
||||
|
||||
def roofing(close: object, hpLength: int = 40, ssLength: int = 10, offset: int = 0, **kwargs) -> object:
|
||||
"""Roofing Filter."""
|
||||
hpLength = int(hpLength)
|
||||
ssLength = int(ssLength)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_roofing(_ptr(src), _ptr(output), n, hpLength, ssLength))
|
||||
return _wrap(output, idx, f"ROOFING_{hpLength}", "filters", offset)
|
||||
|
||||
|
||||
def sgf(close: object, period: int = 14, polyOrder: int = 3, offset: int = 0, **kwargs) -> object:
|
||||
"""Savitzky-Golay Filter."""
|
||||
period = int(period)
|
||||
polyOrder = int(polyOrder)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_sgf(_ptr(src), _ptr(output), n, period, polyOrder))
|
||||
return _wrap(output, idx, f"SGF_{period}", "filters", offset)
|
||||
|
||||
|
||||
def spbf(close: object, shortPeriod: int = 12, longPeriod: int = 26, rmsPeriod: int = 20, offset: int = 0, **kwargs) -> object:
|
||||
"""Short-Period Bandpass Filter."""
|
||||
shortPeriod = int(shortPeriod)
|
||||
longPeriod = int(longPeriod)
|
||||
rmsPeriod = int(rmsPeriod)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_spbf(_ptr(src), _ptr(output), n, shortPeriod, longPeriod, rmsPeriod))
|
||||
return _wrap(output, idx, f"SPBF_{shortPeriod}", "filters", offset)
|
||||
|
||||
|
||||
def ssf2(close: object, period: int = 14, offset: int = 0, **kwargs) -> object:
|
||||
"""Super Smoother (2-pole)."""
|
||||
period = int(period)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_ssf2(_ptr(src), _ptr(output), n, period))
|
||||
return _wrap(output, idx, f"SSF2_{period}", "filters", offset)
|
||||
|
||||
|
||||
def ssf3(close: object, period: int = 14, initialLast: float = 0.0, offset: int = 0, **kwargs) -> object:
|
||||
"""Super Smoother (3-pole)."""
|
||||
period = int(period)
|
||||
initialLast = float(initialLast)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
destination = _out(n)
|
||||
_check(_lib.qtl_ssf3(_ptr(src), _ptr(destination), n, period, initialLast))
|
||||
return _wrap(destination, idx, f"SSF3_{period}", "filters", offset)
|
||||
|
||||
|
||||
def usf(close: object, period: int = 14, offset: int = 0, **kwargs) -> object:
|
||||
"""Universal Smoother Filter."""
|
||||
period = int(period)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_usf(_ptr(src), _ptr(output), n, period))
|
||||
return _wrap(output, idx, f"USF_{period}", "filters", offset)
|
||||
|
||||
|
||||
def voss(close: object, period: int = 14, predict: int = 3, bandwidth: float = 0.25, offset: int = 0, **kwargs) -> object:
|
||||
"""Voss Predictor."""
|
||||
period = int(period)
|
||||
predict = int(predict)
|
||||
bandwidth = float(bandwidth)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_voss(_ptr(src), _ptr(output), n, period, predict, bandwidth))
|
||||
return _wrap(output, idx, f"VOSS_{period}", "filters", offset)
|
||||
|
||||
|
||||
def wavelet(close: object, levels: int = 4, threshMult: float = 1.0, offset: int = 0, **kwargs) -> object:
|
||||
"""Wavelet Filter."""
|
||||
levels = int(levels)
|
||||
threshMult = float(threshMult)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_wavelet(_ptr(src), _ptr(output), n, levels, threshMult))
|
||||
return _wrap(output, idx, "WAVELET", "filters", offset)
|
||||
|
||||
|
||||
def wiener(close: object, period: int = 14, smoothPeriod: int = 5, offset: int = 0, **kwargs) -> object:
|
||||
"""Wiener Filter."""
|
||||
period = int(period)
|
||||
smoothPeriod = int(smoothPeriod)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
destination = _out(n)
|
||||
_check(_lib.qtl_wiener(_ptr(src), _ptr(destination), n, period, smoothPeriod))
|
||||
return _wrap(destination, idx, f"WIENER_{period}", "filters", offset)
|
||||
|
||||
def bessel(close: object, length: int = 14, offset: int = 0, **kwargs) -> object:
|
||||
"""Bessel Filter."""
|
||||
length = int(length); offset = int(offset)
|
||||
src, idx = _arr(close); n = len(src); dst = _out(n)
|
||||
_check(_lib.qtl_bessel(_ptr(src), n, _ptr(dst), length))
|
||||
return _wrap(dst, idx, f"BESSEL_{length}", "filters", offset)
|
||||
|
||||
|
||||
def butter2(close: object, length: int = 14, gain: float = 1.0,
|
||||
offset: int = 0, **kwargs) -> object:
|
||||
"""2nd-order Butterworth."""
|
||||
length = int(length); offset = int(offset)
|
||||
src, idx = _arr(close); n = len(src); dst = _out(n)
|
||||
_check(_lib.qtl_butter2(_ptr(src), n, _ptr(dst), length, float(gain)))
|
||||
return _wrap(dst, idx, f"BUTTER2_{length}", "filters", offset)
|
||||
|
||||
|
||||
def butter3(close: object, length: int = 14, gain: float = 1.0,
|
||||
offset: int = 0, **kwargs) -> object:
|
||||
"""3rd-order Butterworth."""
|
||||
length = int(length); offset = int(offset)
|
||||
src, idx = _arr(close); n = len(src); dst = _out(n)
|
||||
_check(_lib.qtl_butter3(_ptr(src), n, _ptr(dst), length, float(gain)))
|
||||
return _wrap(dst, idx, f"BUTTER3_{length}", "filters", offset)
|
||||
|
||||
|
||||
def cheby1(close: object, length: int = 14, ripple: float = 0.5,
|
||||
offset: int = 0, **kwargs) -> object:
|
||||
"""Chebyshev Type I."""
|
||||
length = int(length); offset = int(offset)
|
||||
src, idx = _arr(close); n = len(src); dst = _out(n)
|
||||
_check(_lib.qtl_cheby1(_ptr(src), n, _ptr(dst), length, float(ripple)))
|
||||
return _wrap(dst, idx, f"CHEBY1_{length}", "filters", offset)
|
||||
|
||||
|
||||
def cheby2(close: object, length: int = 14, ripple: float = 0.5,
|
||||
offset: int = 0, **kwargs) -> object:
|
||||
"""Chebyshev Type II."""
|
||||
length = int(length); offset = int(offset)
|
||||
src, idx = _arr(close); n = len(src); dst = _out(n)
|
||||
_check(_lib.qtl_cheby2(_ptr(src), n, _ptr(dst), length, float(ripple)))
|
||||
return _wrap(dst, idx, f"CHEBY2_{length}", "filters", offset)
|
||||
|
||||
|
||||
def elliptic(close: object, length: int = 14, offset: int = 0, **kwargs) -> object:
|
||||
"""Elliptic (Cauer) Filter."""
|
||||
length = int(length); offset = int(offset)
|
||||
src, idx = _arr(close); n = len(src); dst = _out(n)
|
||||
_check(_lib.qtl_elliptic(_ptr(src), n, _ptr(dst), length))
|
||||
return _wrap(dst, idx, f"ELLIPTIC_{length}", "filters", offset)
|
||||
|
||||
|
||||
def edcf(close: object, length: int = 14, offset: int = 0, **kwargs) -> object:
|
||||
"""Ehlers Distance Coefficient Filter."""
|
||||
length = int(length); offset = int(offset)
|
||||
src, idx = _arr(close); n = len(src); dst = _out(n)
|
||||
_check(_lib.qtl_edcf(_ptr(src), n, _ptr(dst), length))
|
||||
return _wrap(dst, idx, f"EDCF_{length}", "filters", offset)
|
||||
|
||||
|
||||
def bpf(close: object, length: int = 14, bandwidth: int = 5,
|
||||
offset: int = 0, **kwargs) -> object:
|
||||
"""Bandpass Filter."""
|
||||
length = int(length); offset = int(offset)
|
||||
src, idx = _arr(close); n = len(src); dst = _out(n)
|
||||
_check(_lib.qtl_bpf(_ptr(src), n, _ptr(dst), length, int(bandwidth)))
|
||||
return _wrap(dst, idx, f"BPF_{length}", "filters", offset)
|
||||
|
||||
|
||||
def alaguerre(close: object, length: int = 20, order: int = 5,
|
||||
offset: int = 0, **kwargs) -> object:
|
||||
"""Adaptive Laguerre Filter."""
|
||||
length = int(length); offset = int(offset)
|
||||
src, idx = _arr(close); n = len(src); dst = _out(n)
|
||||
_check(_lib.qtl_alaguerre(_ptr(src), n, _ptr(dst), length, int(order)))
|
||||
return _wrap(dst, idx, f"ALAGUERRE_{length}", "filters", offset)
|
||||
|
||||
|
||||
def bilateral(close: object, length: int = 14, sigma_s: float = 0.5,
|
||||
sigma_r: float = 1.0, offset: int = 0, **kwargs) -> object:
|
||||
"""Bilateral Filter."""
|
||||
length = int(length); offset = int(offset)
|
||||
src, idx = _arr(close); n = len(src); dst = _out(n)
|
||||
_check(_lib.qtl_bilateral(_ptr(src), n, _ptr(dst), length, float(sigma_s), float(sigma_r)))
|
||||
return _wrap(dst, idx, f"BILATERAL_{length}", "filters", offset)
|
||||
|
||||
|
||||
def baxterking(close: object, length: int = 12, min_period: int = 6,
|
||||
max_period: int = 32, offset: int = 0, **kwargs) -> object:
|
||||
"""Baxter-King Filter."""
|
||||
length = int(length); offset = int(offset)
|
||||
src, idx = _arr(close); n = len(src); dst = _out(n)
|
||||
_check(_lib.qtl_baxterking(_ptr(src), n, _ptr(dst), length, int(min_period), int(max_period)))
|
||||
return _wrap(dst, idx, f"BAXTERKING_{length}", "filters", offset)
|
||||
|
||||
|
||||
def cfitz(close: object, length: int = 6, bw_period: int = 32,
|
||||
offset: int = 0, **kwargs) -> object:
|
||||
"""Christiano-Fitzgerald Filter."""
|
||||
length = int(length); offset = int(offset)
|
||||
src, idx = _arr(close); n = len(src); dst = _out(n)
|
||||
_check(_lib.qtl_cfitz(_ptr(src), n, _ptr(dst), length, int(bw_period)))
|
||||
return _wrap(dst, idx, f"CFITZ_{length}", "filters", offset)
|
||||
+33
-1189
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,233 @@
|
||||
"""quantalib momentum indicators.
|
||||
|
||||
Auto-generated — DO NOT EDIT.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
from ._helpers import _arr, _ptr, _out, _wrap, _wrap_multi, _check, _lib
|
||||
|
||||
|
||||
__all__ = [
|
||||
"bop",
|
||||
"cci",
|
||||
"macd",
|
||||
"pmo",
|
||||
"ppo",
|
||||
"prs",
|
||||
"rocp",
|
||||
"rocr",
|
||||
"sam",
|
||||
"vel",
|
||||
"rsi",
|
||||
"roc",
|
||||
"mom",
|
||||
"cmo",
|
||||
"tsi",
|
||||
"apo",
|
||||
"bias",
|
||||
"cfo",
|
||||
"cfb",
|
||||
"asi",
|
||||
]
|
||||
|
||||
|
||||
def bop(open: object, high: object, low: object, close: object, offset: int = 0, **kwargs) -> object:
|
||||
"""Balance of Power."""
|
||||
offset = int(offset)
|
||||
o, idx = _arr(open); h, _ = _arr(high); l, _ = _arr(low); c, _ = _arr(close)
|
||||
n = len(o)
|
||||
destination = _out(n)
|
||||
_check(_lib.qtl_bop(_ptr(o), _ptr(h), _ptr(l), _ptr(c), _ptr(destination), n))
|
||||
return _wrap(destination, idx, "BOP", "momentum", offset)
|
||||
|
||||
|
||||
def cci(open: object, high: object, low: object, close: object, volume: object, period: int = 14, offset: int = 0, **kwargs) -> object:
|
||||
"""Commodity Channel Index."""
|
||||
period = int(period)
|
||||
offset = int(offset)
|
||||
o, idx = _arr(open); h, _ = _arr(high); l, _ = _arr(low)
|
||||
c, _ = _arr(close); v, _ = _arr(volume)
|
||||
n = len(o)
|
||||
dst = _out(n)
|
||||
_check(_lib.qtl_cci(_ptr(o), _ptr(h), _ptr(l), _ptr(c), _ptr(v), period, n, _ptr(dst)))
|
||||
return _wrap(dst, idx, f"CCI_{period}", "momentum", offset)
|
||||
|
||||
|
||||
def macd(close: object, fastPeriod: int = 12, slowPeriod: int = 26, offset: int = 0, **kwargs) -> object:
|
||||
"""Moving Average Convergence Divergence."""
|
||||
fastPeriod = int(fastPeriod)
|
||||
slowPeriod = int(slowPeriod)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
destination = _out(n)
|
||||
_check(_lib.qtl_macd(_ptr(src), _ptr(destination), n, fastPeriod, slowPeriod))
|
||||
return _wrap(destination, idx, f"MACD_{fastPeriod}", "momentum", offset)
|
||||
|
||||
|
||||
def pmo(close: object, timePeriods: int = 14, smoothPeriods: int = 14, signalPeriods: int = 14, offset: int = 0, **kwargs) -> object:
|
||||
"""Price Momentum Oscillator."""
|
||||
timePeriods = int(timePeriods)
|
||||
smoothPeriods = int(smoothPeriods)
|
||||
signalPeriods = int(signalPeriods)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_pmo(_ptr(src), _ptr(output), n, timePeriods, smoothPeriods, signalPeriods))
|
||||
return _wrap(output, idx, f"PMO_{timePeriods}", "momentum", offset)
|
||||
|
||||
|
||||
def ppo(close: object, fastPeriod: int = 12, slowPeriod: int = 26, offset: int = 0, **kwargs) -> object:
|
||||
"""Percentage Price Oscillator."""
|
||||
fastPeriod = int(fastPeriod)
|
||||
slowPeriod = int(slowPeriod)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
destination = _out(n)
|
||||
_check(_lib.qtl_ppo(_ptr(src), _ptr(destination), n, fastPeriod, slowPeriod))
|
||||
return _wrap(destination, idx, f"PPO_{fastPeriod}", "momentum", offset)
|
||||
|
||||
|
||||
def prs(x: object, y: object, smoothPeriod: int = 5, offset: int = 0, **kwargs) -> object:
|
||||
"""Price Relative Strength."""
|
||||
smoothPeriod = int(smoothPeriod)
|
||||
offset = int(offset)
|
||||
xarr, idx = _arr(x); yarr, _ = _arr(y)
|
||||
n = len(xarr)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_prs(_ptr(xarr), _ptr(yarr), _ptr(output), n, smoothPeriod))
|
||||
return _wrap(output, idx, f"PRS_{smoothPeriod}", "momentum", offset)
|
||||
|
||||
|
||||
def rocp(close: object, period: int = 14, offset: int = 0, **kwargs) -> object:
|
||||
"""Rate of Change (Percentage)."""
|
||||
period = int(period)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_rocp(_ptr(src), _ptr(output), n, period))
|
||||
return _wrap(output, idx, f"ROCP_{period}", "momentum", offset)
|
||||
|
||||
|
||||
def rocr(close: object, period: int = 14, offset: int = 0, **kwargs) -> object:
|
||||
"""Rate of Change (Ratio)."""
|
||||
period = int(period)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_rocr(_ptr(src), _ptr(output), n, period))
|
||||
return _wrap(output, idx, f"ROCR_{period}", "momentum", offset)
|
||||
|
||||
|
||||
def sam(close: object, alpha: float = 2.0, cutoff: int = 10, offset: int = 0, **kwargs) -> object:
|
||||
"""Simple Alpha Momentum."""
|
||||
alpha = float(alpha)
|
||||
cutoff = int(cutoff)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_sam(_ptr(src), _ptr(output), n, alpha, cutoff))
|
||||
return _wrap(output, idx, "SAM", "momentum", offset)
|
||||
|
||||
|
||||
def vel(close: object, period: int = 14, offset: int = 0, **kwargs) -> object:
|
||||
"""Velocity."""
|
||||
period = int(period)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_vel(_ptr(src), _ptr(output), n, period))
|
||||
return _wrap(output, idx, f"VEL_{period}", "momentum", offset)
|
||||
|
||||
def rsi(close: object, length: int = 14, offset: int = 0, **kwargs) -> object:
|
||||
"""Relative Strength Index."""
|
||||
length = int(length); offset = int(offset)
|
||||
src, idx = _arr(close); n = len(src); dst = _out(n)
|
||||
_check(_lib.qtl_rsi(_ptr(src), n, _ptr(dst), length))
|
||||
return _wrap(dst, idx, f"RSI_{length}", "momentum", offset)
|
||||
|
||||
|
||||
def roc(close: object, length: int = 10, offset: int = 0, **kwargs) -> object:
|
||||
"""Rate of Change."""
|
||||
length = int(length); offset = int(offset)
|
||||
src, idx = _arr(close); n = len(src); dst = _out(n)
|
||||
_check(_lib.qtl_roc(_ptr(src), n, _ptr(dst), length))
|
||||
return _wrap(dst, idx, f"ROC_{length}", "momentum", offset)
|
||||
|
||||
|
||||
def mom(close: object, length: int = 10, offset: int = 0, **kwargs) -> object:
|
||||
"""Momentum."""
|
||||
length = int(length); offset = int(offset)
|
||||
src, idx = _arr(close); n = len(src); dst = _out(n)
|
||||
_check(_lib.qtl_mom(_ptr(src), n, _ptr(dst), length))
|
||||
return _wrap(dst, idx, f"MOM_{length}", "momentum", offset)
|
||||
|
||||
|
||||
def cmo(close: object, length: int = 14, offset: int = 0, **kwargs) -> object:
|
||||
"""Chande Momentum Oscillator."""
|
||||
length = int(length); offset = int(offset)
|
||||
src, idx = _arr(close); n = len(src); dst = _out(n)
|
||||
_check(_lib.qtl_cmo(_ptr(src), n, _ptr(dst), length))
|
||||
return _wrap(dst, idx, f"CMO_{length}", "momentum", offset)
|
||||
|
||||
|
||||
def tsi(close: object, long_period: int = 25, short_period: int = 13,
|
||||
offset: int = 0, **kwargs) -> object:
|
||||
"""True Strength Index."""
|
||||
long_period = int(long_period); short_period = int(short_period); offset = int(offset)
|
||||
src, idx = _arr(close); n = len(src); dst = _out(n)
|
||||
_check(_lib.qtl_tsi(_ptr(src), n, _ptr(dst), long_period, short_period))
|
||||
return _wrap(dst, idx, f"TSI_{long_period}_{short_period}", "momentum", offset)
|
||||
|
||||
|
||||
def apo(close: object, fast: int = 12, slow: int = 26,
|
||||
offset: int = 0, **kwargs) -> object:
|
||||
"""Absolute Price Oscillator."""
|
||||
fast = int(fast); slow = int(slow); offset = int(offset)
|
||||
src, idx = _arr(close); n = len(src); dst = _out(n)
|
||||
_check(_lib.qtl_apo(_ptr(src), n, _ptr(dst), fast, slow))
|
||||
return _wrap(dst, idx, f"APO_{fast}_{slow}", "momentum", offset)
|
||||
|
||||
|
||||
def bias(close: object, length: int = 26, offset: int = 0, **kwargs) -> object:
|
||||
"""Bias."""
|
||||
length = int(length); offset = int(offset)
|
||||
src, idx = _arr(close); n = len(src); dst = _out(n)
|
||||
_check(_lib.qtl_bias(_ptr(src), n, _ptr(dst), length))
|
||||
return _wrap(dst, idx, f"BIAS_{length}", "momentum", offset)
|
||||
|
||||
|
||||
def cfo(close: object, length: int = 14, offset: int = 0, **kwargs) -> object:
|
||||
"""Chande Forecast Oscillator."""
|
||||
length = int(length); offset = int(offset)
|
||||
src, idx = _arr(close); n = len(src); dst = _out(n)
|
||||
_check(_lib.qtl_cfo(_ptr(src), n, _ptr(dst), length))
|
||||
return _wrap(dst, idx, f"CFO_{length}", "momentum", offset)
|
||||
|
||||
|
||||
def cfb(close: object, lengths: list | None = None,
|
||||
offset: int = 0, **kwargs) -> object:
|
||||
"""Composite Fractal Behavior."""
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close); n = len(src); dst = _out(n)
|
||||
if lengths:
|
||||
arr_t = (ctypes.c_int * len(lengths))(*lengths)
|
||||
_check(_lib.qtl_cfb(_ptr(src), n, _ptr(dst), arr_t, len(lengths)))
|
||||
else:
|
||||
_check(_lib.qtl_cfb(_ptr(src), n, _ptr(dst), None, 0))
|
||||
return _wrap(dst, idx, "CFB", "momentum", offset)
|
||||
|
||||
|
||||
def asi(open: object, high: object, low: object, close: object,
|
||||
limit: float = 3.0, offset: int = 0, **kwargs) -> object:
|
||||
"""Accumulative Swing Index."""
|
||||
o, idx = _arr(open); h, _ = _arr(high); l, _ = _arr(low); c, _ = _arr(close)
|
||||
n = len(o); dst = _out(n)
|
||||
_check(_lib.qtl_asi(_ptr(o), _ptr(h), _ptr(l), _ptr(c), n, _ptr(dst), float(limit)))
|
||||
return _wrap(dst, idx, "ASI", "momentum", int(offset))
|
||||
@@ -0,0 +1,330 @@
|
||||
"""quantalib numerics indicators.
|
||||
|
||||
Auto-generated — DO NOT EDIT.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
from ._helpers import _arr, _ptr, _out, _wrap, _wrap_multi, _check, _lib
|
||||
|
||||
|
||||
__all__ = [
|
||||
"accel",
|
||||
"fdist",
|
||||
"fft",
|
||||
"gammadist",
|
||||
"highest",
|
||||
"ifft",
|
||||
"jerk",
|
||||
"lineartrans",
|
||||
"lognormdist",
|
||||
"logtrans",
|
||||
"lowest",
|
||||
"normalize",
|
||||
"normdist",
|
||||
"poissondist",
|
||||
"relu",
|
||||
"sigmoid",
|
||||
"slope",
|
||||
"sqrttrans",
|
||||
"tdist",
|
||||
"weibulldist",
|
||||
"change",
|
||||
"exptrans",
|
||||
"betadist",
|
||||
"expdist",
|
||||
"binomdist",
|
||||
"cwt",
|
||||
"dwt",
|
||||
]
|
||||
|
||||
|
||||
def accel(close: object, offset: int = 0, **kwargs) -> object:
|
||||
"""Acceleration."""
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_accel(_ptr(src), _ptr(output), n))
|
||||
return _wrap(output, idx, "ACCEL", "numerics", offset)
|
||||
|
||||
|
||||
def fdist(close: object, d1: int = 10, d2: int = 20, period: int = 14, offset: int = 0, **kwargs) -> object:
|
||||
"""F-Distribution."""
|
||||
d1 = int(d1)
|
||||
d2 = int(d2)
|
||||
period = int(period)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_fdist(_ptr(src), _ptr(output), n, d1, d2, period))
|
||||
return _wrap(output, idx, f"FDIST_{period}", "numerics", offset)
|
||||
|
||||
|
||||
def fft(close: object, windowSize: int = 256, minPeriod: int = 6, maxPeriod: int = 48, offset: int = 0, **kwargs) -> object:
|
||||
"""Fast Fourier Transform."""
|
||||
windowSize = int(windowSize)
|
||||
minPeriod = int(minPeriod)
|
||||
maxPeriod = int(maxPeriod)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_fft(_ptr(src), _ptr(output), n, windowSize, minPeriod, maxPeriod))
|
||||
return _wrap(output, idx, f"FFT_{minPeriod}", "numerics", offset)
|
||||
|
||||
|
||||
def gammadist(close: object, alpha: float = 2.0, beta: float = 2.0, period: int = 14, offset: int = 0, **kwargs) -> object:
|
||||
"""Gamma Distribution."""
|
||||
alpha = float(alpha)
|
||||
beta = float(beta)
|
||||
period = int(period)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_gammadist(_ptr(src), _ptr(output), n, alpha, beta, period))
|
||||
return _wrap(output, idx, f"GAMMADIST_{period}", "numerics", offset)
|
||||
|
||||
|
||||
def highest(close: object, period: int = 14, offset: int = 0, **kwargs) -> object:
|
||||
"""Highest Value."""
|
||||
period = int(period)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_highest(_ptr(src), _ptr(output), n, period))
|
||||
return _wrap(output, idx, f"HIGHEST_{period}", "numerics", offset)
|
||||
|
||||
|
||||
def ifft(close: object, windowSize: int = 256, numHarmonics: int = 10, offset: int = 0, **kwargs) -> object:
|
||||
"""Inverse FFT."""
|
||||
windowSize = int(windowSize)
|
||||
numHarmonics = int(numHarmonics)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_ifft(_ptr(src), _ptr(output), n, windowSize, numHarmonics))
|
||||
return _wrap(output, idx, "IFFT", "numerics", offset)
|
||||
|
||||
|
||||
def jerk(close: object, offset: int = 0, **kwargs) -> object:
|
||||
"""Jerk (3rd derivative)."""
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_jerk(_ptr(src), _ptr(output), n))
|
||||
return _wrap(output, idx, "JERK", "numerics", offset)
|
||||
|
||||
|
||||
def lineartrans(close: object, slope: float = 1.0, intercept: float = 0.0, offset: int = 0, **kwargs) -> object:
|
||||
"""Linear Transform."""
|
||||
slope = float(slope)
|
||||
intercept = float(intercept)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_lineartrans(_ptr(src), _ptr(output), n, slope, intercept))
|
||||
return _wrap(output, idx, "LINEARTRANS", "numerics", offset)
|
||||
|
||||
|
||||
def lognormdist(close: object, mu: float = 0.01, sigma: float = 6.0, period: int = 14, offset: int = 0, **kwargs) -> object:
|
||||
"""Log-Normal Distribution."""
|
||||
mu = float(mu)
|
||||
sigma = float(sigma)
|
||||
period = int(period)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_lognormdist(_ptr(src), _ptr(output), n, mu, sigma, period))
|
||||
return _wrap(output, idx, f"LOGNORMDIST_{period}", "numerics", offset)
|
||||
|
||||
|
||||
def logtrans(close: object, offset: int = 0, **kwargs) -> object:
|
||||
"""Logarithmic Transform."""
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_logtrans(_ptr(src), _ptr(output), n))
|
||||
return _wrap(output, idx, "LOGTRANS", "numerics", offset)
|
||||
|
||||
|
||||
def lowest(close: object, period: int = 14, offset: int = 0, **kwargs) -> object:
|
||||
"""Lowest Value."""
|
||||
period = int(period)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_lowest(_ptr(src), _ptr(output), n, period))
|
||||
return _wrap(output, idx, f"LOWEST_{period}", "numerics", offset)
|
||||
|
||||
|
||||
def normalize(close: object, period: int = 14, offset: int = 0, **kwargs) -> object:
|
||||
"""Normalization."""
|
||||
period = int(period)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_normalize(_ptr(src), _ptr(output), n, period))
|
||||
return _wrap(output, idx, f"NORMALIZE_{period}", "numerics", offset)
|
||||
|
||||
|
||||
def normdist(close: object, mu: float = 0.01, sigma: float = 6.0, period: int = 14, offset: int = 0, **kwargs) -> object:
|
||||
"""Normal Distribution."""
|
||||
mu = float(mu)
|
||||
sigma = float(sigma)
|
||||
period = int(period)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_normdist(_ptr(src), _ptr(output), n, mu, sigma, period))
|
||||
return _wrap(output, idx, f"NORMDIST_{period}", "numerics", offset)
|
||||
|
||||
|
||||
def poissondist(close: object, lam: float = 1600.0, period: int = 14, threshold: int = 10, offset: int = 0, **kwargs) -> object:
|
||||
"""Poisson Distribution."""
|
||||
lam = float(lam)
|
||||
period = int(period)
|
||||
threshold = int(threshold)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_poissondist(_ptr(src), _ptr(output), n, lam, period, threshold))
|
||||
return _wrap(output, idx, f"POISSONDIST_{period}", "numerics", offset)
|
||||
|
||||
|
||||
def relu(close: object, offset: int = 0, **kwargs) -> object:
|
||||
"""ReLU Activation."""
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_relu(_ptr(src), _ptr(output), n))
|
||||
return _wrap(output, idx, "RELU", "numerics", offset)
|
||||
|
||||
|
||||
def sigmoid(close: object, k: float = 2.0, x0: float = 0.0, offset: int = 0, **kwargs) -> object:
|
||||
"""Sigmoid Transform."""
|
||||
k = float(k)
|
||||
x0 = float(x0)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_sigmoid(_ptr(src), _ptr(output), n, k, x0))
|
||||
return _wrap(output, idx, "SIGMOID", "numerics", offset)
|
||||
|
||||
|
||||
def slope(close: object, offset: int = 0, **kwargs) -> object:
|
||||
"""Slope (1st derivative)."""
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_slope(_ptr(src), _ptr(output), n))
|
||||
return _wrap(output, idx, "SLOPE", "numerics", offset)
|
||||
|
||||
|
||||
def sqrttrans(close: object, offset: int = 0, **kwargs) -> object:
|
||||
"""Square Root Transform."""
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_sqrttrans(_ptr(src), _ptr(output), n))
|
||||
return _wrap(output, idx, "SQRTTRANS", "numerics", offset)
|
||||
|
||||
|
||||
def tdist(close: object, nu: int = 10, period: int = 14, offset: int = 0, **kwargs) -> object:
|
||||
"""Student's t-Distribution."""
|
||||
nu = int(nu)
|
||||
period = int(period)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_tdist(_ptr(src), _ptr(output), n, nu, period))
|
||||
return _wrap(output, idx, f"TDIST_{period}", "numerics", offset)
|
||||
|
||||
|
||||
def weibulldist(close: object, k: float = 2.0, lam: float = 1600.0, period: int = 14, offset: int = 0, **kwargs) -> object:
|
||||
"""Weibull Distribution."""
|
||||
k = float(k)
|
||||
lam = float(lam)
|
||||
period = int(period)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_weibulldist(_ptr(src), _ptr(output), n, k, lam, period))
|
||||
return _wrap(output, idx, f"WEIBULLDIST_{period}", "numerics", offset)
|
||||
|
||||
def change(close: object, length: int = 1, offset: int = 0, **kwargs) -> object:
|
||||
"""Price Change."""
|
||||
length = int(length); offset = int(offset)
|
||||
src, idx = _arr(close); n = len(src); dst = _out(n)
|
||||
_check(_lib.qtl_change(_ptr(src), n, _ptr(dst), length))
|
||||
return _wrap(dst, idx, f"CHANGE_{length}", "numerics", offset)
|
||||
|
||||
|
||||
def exptrans(close: object, offset: int = 0, **kwargs) -> object:
|
||||
"""Exponential Transform."""
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close); n = len(src); dst = _out(n)
|
||||
_check(_lib.qtl_exptrans(_ptr(src), n, _ptr(dst)))
|
||||
return _wrap(dst, idx, "EXPTRANS", "numerics", offset)
|
||||
|
||||
|
||||
def betadist(close: object, length: int = 50, alpha: float = 2.0,
|
||||
beta: float = 2.0, offset: int = 0, **kwargs) -> object:
|
||||
"""Beta Distribution."""
|
||||
length = int(length); offset = int(offset)
|
||||
src, idx = _arr(close); n = len(src); dst = _out(n)
|
||||
_check(_lib.qtl_betadist(_ptr(src), n, _ptr(dst), length, float(alpha), float(beta)))
|
||||
return _wrap(dst, idx, f"BETADIST_{length}", "numerics", offset)
|
||||
|
||||
|
||||
def expdist(close: object, length: int = 50, lam: float = 3.0,
|
||||
offset: int = 0, **kwargs) -> object:
|
||||
"""Exponential Distribution."""
|
||||
length = int(length); offset = int(offset)
|
||||
src, idx = _arr(close); n = len(src); dst = _out(n)
|
||||
_check(_lib.qtl_expdist(_ptr(src), n, _ptr(dst), length, float(lam)))
|
||||
return _wrap(dst, idx, f"EXPDIST_{length}", "numerics", offset)
|
||||
|
||||
|
||||
def binomdist(close: object, length: int = 50, trials: int = 20,
|
||||
threshold: int = 10, offset: int = 0, **kwargs) -> object:
|
||||
"""Binomial Distribution."""
|
||||
length = int(length); offset = int(offset)
|
||||
src, idx = _arr(close); n = len(src); dst = _out(n)
|
||||
_check(_lib.qtl_binomdist(_ptr(src), n, _ptr(dst), length, int(trials), int(threshold)))
|
||||
return _wrap(dst, idx, f"BINOMDIST_{length}", "numerics", offset)
|
||||
|
||||
|
||||
def cwt(close: object, scale: float = 10.0, omega: float = 6.0,
|
||||
offset: int = 0, **kwargs) -> object:
|
||||
"""Continuous Wavelet Transform."""
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close); n = len(src); dst = _out(n)
|
||||
_check(_lib.qtl_cwt(_ptr(src), n, _ptr(dst), float(scale), float(omega)))
|
||||
return _wrap(dst, idx, "CWT", "numerics", offset)
|
||||
|
||||
|
||||
def dwt(close: object, length: int = 4, levels: int = 0,
|
||||
offset: int = 0, **kwargs) -> object:
|
||||
"""Discrete Wavelet Transform."""
|
||||
length = int(length); levels = int(levels); offset = int(offset)
|
||||
src, idx = _arr(close); n = len(src); dst = _out(n)
|
||||
_check(_lib.qtl_dwt(_ptr(src), n, _ptr(dst), length, levels))
|
||||
return _wrap(dst, idx, f"DWT_{length}", "numerics", offset)
|
||||
@@ -0,0 +1,553 @@
|
||||
"""quantalib oscillators indicators.
|
||||
|
||||
Auto-generated — DO NOT EDIT.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
from ._helpers import _arr, _ptr, _out, _wrap, _wrap_multi, _check, _lib
|
||||
|
||||
|
||||
__all__ = [
|
||||
"ac",
|
||||
"ao",
|
||||
"bbs",
|
||||
"coppock",
|
||||
"eri",
|
||||
"fi",
|
||||
"gator",
|
||||
"imi",
|
||||
"kdj",
|
||||
"kst",
|
||||
"marketfi",
|
||||
"mstoch",
|
||||
"pgo",
|
||||
"qqe",
|
||||
"reverseema",
|
||||
"rvgi",
|
||||
"smi",
|
||||
"squeeze",
|
||||
"stc",
|
||||
"stoch",
|
||||
"stochf",
|
||||
"stochrsi",
|
||||
"ttm_wave",
|
||||
"ultosc",
|
||||
"willr",
|
||||
"fisher",
|
||||
"fisher04",
|
||||
"dpo",
|
||||
"trix",
|
||||
"inertia",
|
||||
"rsx",
|
||||
"er",
|
||||
"cti",
|
||||
"reflex",
|
||||
"trendflex",
|
||||
"kri",
|
||||
"psl",
|
||||
"deco",
|
||||
"dosc",
|
||||
"dymoi",
|
||||
"crsi",
|
||||
"bbb",
|
||||
"bbi",
|
||||
"dem",
|
||||
"brar",
|
||||
]
|
||||
|
||||
|
||||
def ac(high: object, low: object, fastPeriod: int = 12, slowPeriod: int = 26, acPeriod: int = 5, offset: int = 0, **kwargs) -> object:
|
||||
"""Accelerator Oscillator."""
|
||||
fastPeriod = int(fastPeriod)
|
||||
slowPeriod = int(slowPeriod)
|
||||
acPeriod = int(acPeriod)
|
||||
offset = int(offset)
|
||||
h, idx = _arr(high); l, _ = _arr(low)
|
||||
n = len(h)
|
||||
destination = _out(n)
|
||||
_check(_lib.qtl_ac(_ptr(h), _ptr(l), _ptr(destination), n, fastPeriod, slowPeriod, acPeriod))
|
||||
return _wrap(destination, idx, f"AC_{fastPeriod}", "oscillators", offset)
|
||||
|
||||
|
||||
def ao(high: object, low: object, fastPeriod: int = 12, slowPeriod: int = 26, offset: int = 0, **kwargs) -> object:
|
||||
"""Awesome Oscillator."""
|
||||
fastPeriod = int(fastPeriod)
|
||||
slowPeriod = int(slowPeriod)
|
||||
offset = int(offset)
|
||||
h, idx = _arr(high); l, _ = _arr(low)
|
||||
n = len(h)
|
||||
destination = _out(n)
|
||||
_check(_lib.qtl_ao(_ptr(h), _ptr(l), _ptr(destination), n, fastPeriod, slowPeriod))
|
||||
return _wrap(destination, idx, f"AO_{fastPeriod}", "oscillators", offset)
|
||||
|
||||
|
||||
def bbs(high: object, low: object, close: object, bbPeriod: int = 20, bbMult: float = 2.0, offset: int = 0, **kwargs) -> object:
|
||||
"""Bollinger Band Squeeze."""
|
||||
bbPeriod = int(bbPeriod)
|
||||
bbMult = float(bbMult)
|
||||
offset = int(offset)
|
||||
h, idx = _arr(high); l, _ = _arr(low); c, _ = _arr(close)
|
||||
n = len(h)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_bbs(_ptr(h), _ptr(l), _ptr(c), _ptr(output), n, bbPeriod, bbMult))
|
||||
return _wrap(output, idx, f"BBS_{bbPeriod}", "oscillators", offset)
|
||||
|
||||
|
||||
def coppock(close: object, longRoc: int = 14, shortRoc: int = 11, wmaPeriod: int = 10, offset: int = 0, **kwargs) -> object:
|
||||
"""Coppock Curve."""
|
||||
longRoc = int(longRoc)
|
||||
shortRoc = int(shortRoc)
|
||||
wmaPeriod = int(wmaPeriod)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_coppock(_ptr(src), _ptr(output), n, longRoc, shortRoc, wmaPeriod))
|
||||
return _wrap(output, idx, f"COPPOCK_{wmaPeriod}", "oscillators", offset)
|
||||
|
||||
|
||||
def eri(close: object, period: int = 14, offset: int = 0, **kwargs) -> object:
|
||||
"""Elder Ray Index."""
|
||||
period = int(period)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
dst = _out(n)
|
||||
_check(_lib.qtl_eri(_ptr(src), period, n, _ptr(dst)))
|
||||
return _wrap(dst, idx, f"ERI_{period}", "oscillators", offset)
|
||||
|
||||
|
||||
def fi(close: object, period: int = 14, offset: int = 0, **kwargs) -> object:
|
||||
"""Force Index."""
|
||||
period = int(period)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
dst = _out(n)
|
||||
_check(_lib.qtl_fi(_ptr(src), period, n, _ptr(dst)))
|
||||
return _wrap(dst, idx, f"FI_{period}", "oscillators", offset)
|
||||
|
||||
|
||||
def gator(close: object, jawPeriod: int = 13, jawShift: int = 8, teethPeriod: int = 8, teethShift: int = 5, lipsPeriod: int = 5, lipsShift: int = 3, offset: int = 0, **kwargs) -> object:
|
||||
"""Gator Oscillator."""
|
||||
jawPeriod = int(jawPeriod)
|
||||
jawShift = int(jawShift)
|
||||
teethPeriod = int(teethPeriod)
|
||||
teethShift = int(teethShift)
|
||||
lipsPeriod = int(lipsPeriod)
|
||||
lipsShift = int(lipsShift)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_gator(_ptr(src), _ptr(output), n, jawPeriod, jawShift, teethPeriod, teethShift, lipsPeriod, lipsShift))
|
||||
return _wrap(output, idx, f"GATOR_{jawPeriod}", "oscillators", offset)
|
||||
|
||||
|
||||
def imi(open: object, high: object, low: object, close: object, volume: object, period: int = 14, offset: int = 0, **kwargs) -> object:
|
||||
"""Intraday Momentum Index."""
|
||||
period = int(period)
|
||||
offset = int(offset)
|
||||
o, idx = _arr(open); h, _ = _arr(high); l, _ = _arr(low)
|
||||
c, _ = _arr(close); v, _ = _arr(volume)
|
||||
n = len(o)
|
||||
dst = _out(n)
|
||||
_check(_lib.qtl_imi(_ptr(o), _ptr(h), _ptr(l), _ptr(c), _ptr(v), period, n, _ptr(dst)))
|
||||
return _wrap(dst, idx, f"IMI_{period}", "oscillators", offset)
|
||||
|
||||
|
||||
def kdj(high: object, low: object, close: object, length: int = 14, signal: int = 3, offset: int = 0, **kwargs) -> object:
|
||||
"""KDJ Indicator."""
|
||||
length = int(length)
|
||||
signal = int(signal)
|
||||
offset = int(offset)
|
||||
h, idx = _arr(high); l, _ = _arr(low); c, _ = _arr(close)
|
||||
n = len(h)
|
||||
kOut = _out(n)
|
||||
dOut = _out(n)
|
||||
jOut = _out(n)
|
||||
_check(_lib.qtl_kdj(_ptr(h), _ptr(l), _ptr(c), _ptr(kOut), _ptr(dOut), _ptr(jOut), n, length, signal))
|
||||
return _wrap_multi({"kOut": kOut, "dOut": dOut, "jOut": jOut}, idx, "oscillators", offset)
|
||||
|
||||
|
||||
def kst(close: object, r1: int = 10, r2: int = 15, r3: int = 20, r4: int = 30, s1: int = 10, s2: int = 10, s3: int = 10, s4: int = 15, sigPeriod: int = 9, offset: int = 0, **kwargs) -> object:
|
||||
"""Know Sure Thing."""
|
||||
r1 = int(r1)
|
||||
r2 = int(r2)
|
||||
r3 = int(r3)
|
||||
r4 = int(r4)
|
||||
s1 = int(s1)
|
||||
s2 = int(s2)
|
||||
s3 = int(s3)
|
||||
s4 = int(s4)
|
||||
sigPeriod = int(sigPeriod)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
kstOut = _out(n)
|
||||
sigOut = _out(n)
|
||||
_check(_lib.qtl_kst(_ptr(src), _ptr(kstOut), _ptr(sigOut), n, r1, r2, r3, r4, s1, s2, s3, s4, sigPeriod))
|
||||
return _wrap_multi({"kstOut": kstOut, "sigOut": sigOut}, idx, "oscillators", offset)
|
||||
|
||||
|
||||
def marketfi(high: object, low: object, volume: object, offset: int = 0, **kwargs) -> object:
|
||||
"""Market Facilitation Index."""
|
||||
offset = int(offset)
|
||||
h, idx = _arr(high); l, _ = _arr(low); v, _ = _arr(volume)
|
||||
n = len(h)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_marketfi(_ptr(h), _ptr(l), _ptr(v), _ptr(output), n))
|
||||
return _wrap(output, idx, "MARKETFI", "oscillators", offset)
|
||||
|
||||
|
||||
def mstoch(close: object, stochLength: int = 14, hpLength: int = 40, ssLength: int = 10, offset: int = 0, **kwargs) -> object:
|
||||
"""Modified Stochastic."""
|
||||
stochLength = int(stochLength)
|
||||
hpLength = int(hpLength)
|
||||
ssLength = int(ssLength)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_mstoch(_ptr(src), _ptr(output), n, stochLength, hpLength, ssLength))
|
||||
return _wrap(output, idx, f"MSTOCH_{stochLength}", "oscillators", offset)
|
||||
|
||||
|
||||
def pgo(high: object, low: object, close: object, period: int = 14, offset: int = 0, **kwargs) -> object:
|
||||
"""Pretty Good Oscillator."""
|
||||
period = int(period)
|
||||
offset = int(offset)
|
||||
h, idx = _arr(high); l, _ = _arr(low); c, _ = _arr(close)
|
||||
n = len(h)
|
||||
destination = _out(n)
|
||||
_check(_lib.qtl_pgo(_ptr(h), _ptr(l), _ptr(c), _ptr(destination), n, period))
|
||||
return _wrap(destination, idx, f"PGO_{period}", "oscillators", offset)
|
||||
|
||||
|
||||
def qqe(close: object, rsiPeriod: int = 14, smoothFactor: int = 5, qqeFactor: float = 4.236, offset: int = 0, **kwargs) -> object:
|
||||
"""Quantitative Qualitative Estimation."""
|
||||
rsiPeriod = int(rsiPeriod)
|
||||
smoothFactor = int(smoothFactor)
|
||||
qqeFactor = float(qqeFactor)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_qqe(_ptr(src), _ptr(output), n, rsiPeriod, smoothFactor, qqeFactor))
|
||||
return _wrap(output, idx, f"QQE_{rsiPeriod}", "oscillators", offset)
|
||||
|
||||
|
||||
def reverseema(close: object, period: int = 14, offset: int = 0, **kwargs) -> object:
|
||||
"""Reverse EMA."""
|
||||
period = int(period)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_reverseema(_ptr(src), _ptr(output), n, period))
|
||||
return _wrap(output, idx, f"REVERSEEMA_{period}", "oscillators", offset)
|
||||
|
||||
|
||||
def rvgi(open: object, high: object, low: object, close: object, period: int = 14, offset: int = 0, **kwargs) -> object:
|
||||
"""Relative Vigor Index."""
|
||||
period = int(period)
|
||||
offset = int(offset)
|
||||
o, idx = _arr(open); h, _ = _arr(high); l, _ = _arr(low); c, _ = _arr(close)
|
||||
n = len(o)
|
||||
rvgiOutput = _out(n)
|
||||
signalOutput = _out(n)
|
||||
_check(_lib.qtl_rvgi(_ptr(o), _ptr(h), _ptr(l), _ptr(c), _ptr(rvgiOutput), _ptr(signalOutput), n, period))
|
||||
return _wrap_multi({"rvgiOutput": rvgiOutput, "signalOutput": signalOutput}, idx, "oscillators", offset)
|
||||
|
||||
|
||||
def smi(high: object, low: object, close: object, kPeriod: int = 14, kSmooth: int = 3, dSmooth: int = 3, blau: int = 3, offset: int = 0, **kwargs) -> object:
|
||||
"""Stochastic Momentum Index."""
|
||||
kPeriod = int(kPeriod)
|
||||
kSmooth = int(kSmooth)
|
||||
dSmooth = int(dSmooth)
|
||||
blau = int(blau)
|
||||
offset = int(offset)
|
||||
h, idx = _arr(high); l, _ = _arr(low); c, _ = _arr(close)
|
||||
n = len(h)
|
||||
kOut = _out(n)
|
||||
dOut = _out(n)
|
||||
_check(_lib.qtl_smi(_ptr(h), _ptr(l), _ptr(c), _ptr(kOut), _ptr(dOut), n, kPeriod, kSmooth, dSmooth, blau))
|
||||
return _wrap_multi({"kOut": kOut, "dOut": dOut}, idx, "oscillators", offset)
|
||||
|
||||
|
||||
def squeeze(high: object, low: object, close: object, period: int = 14, bbMult: float = 2.0, kcMult: float = 1.5, offset: int = 0, **kwargs) -> object:
|
||||
"""Squeeze Momentum."""
|
||||
period = int(period)
|
||||
bbMult = float(bbMult)
|
||||
kcMult = float(kcMult)
|
||||
offset = int(offset)
|
||||
h, idx = _arr(high); l, _ = _arr(low); c, _ = _arr(close)
|
||||
n = len(h)
|
||||
momOut = _out(n)
|
||||
sqOut = _out(n)
|
||||
_check(_lib.qtl_squeeze(_ptr(h), _ptr(l), _ptr(c), _ptr(momOut), _ptr(sqOut), n, period, bbMult, kcMult))
|
||||
return _wrap_multi({"momOut": momOut, "sqOut": sqOut}, idx, "oscillators", offset)
|
||||
|
||||
|
||||
def stc(close: object, kPeriod: int = 14, dPeriod: int = 3, fastLength: int = 23, slowLength: int = 50, smoothing: int = 10, offset: int = 0, **kwargs) -> object:
|
||||
"""Schaff Trend Cycle."""
|
||||
kPeriod = int(kPeriod)
|
||||
dPeriod = int(dPeriod)
|
||||
fastLength = int(fastLength)
|
||||
slowLength = int(slowLength)
|
||||
smoothing = int(smoothing)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_stc(_ptr(src), _ptr(output), n, kPeriod, dPeriod, fastLength, slowLength, smoothing))
|
||||
return _wrap(output, idx, f"STC_{kPeriod}", "oscillators", offset)
|
||||
|
||||
|
||||
def stoch(high: object, low: object, close: object, kLength: int = 14, dPeriod: int = 3, offset: int = 0, **kwargs) -> object:
|
||||
"""Stochastic Oscillator."""
|
||||
kLength = int(kLength)
|
||||
dPeriod = int(dPeriod)
|
||||
offset = int(offset)
|
||||
h, idx = _arr(high); l, _ = _arr(low); c, _ = _arr(close)
|
||||
n = len(h)
|
||||
kOut = _out(n)
|
||||
dOut = _out(n)
|
||||
_check(_lib.qtl_stoch(_ptr(h), _ptr(l), _ptr(c), _ptr(kOut), _ptr(dOut), n, kLength, dPeriod))
|
||||
return _wrap_multi({"kOut": kOut, "dOut": dOut}, idx, "oscillators", offset)
|
||||
|
||||
|
||||
def stochf(high: object, low: object, close: object, kLength: int = 14, dPeriod: int = 3, offset: int = 0, **kwargs) -> object:
|
||||
"""Fast Stochastic."""
|
||||
kLength = int(kLength)
|
||||
dPeriod = int(dPeriod)
|
||||
offset = int(offset)
|
||||
h, idx = _arr(high); l, _ = _arr(low); c, _ = _arr(close)
|
||||
n = len(h)
|
||||
kOut = _out(n)
|
||||
dOut = _out(n)
|
||||
_check(_lib.qtl_stochf(_ptr(h), _ptr(l), _ptr(c), _ptr(kOut), _ptr(dOut), n, kLength, dPeriod))
|
||||
return _wrap_multi({"kOut": kOut, "dOut": dOut}, idx, "oscillators", offset)
|
||||
|
||||
|
||||
def stochrsi(close: object, rsiLength: int = 14, stochLength: int = 14, kSmooth: int = 3, dSmooth: int = 3, offset: int = 0, **kwargs) -> object:
|
||||
"""Stochastic RSI."""
|
||||
rsiLength = int(rsiLength)
|
||||
stochLength = int(stochLength)
|
||||
kSmooth = int(kSmooth)
|
||||
dSmooth = int(dSmooth)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_stochrsi(_ptr(src), _ptr(output), n, rsiLength, stochLength, kSmooth, dSmooth))
|
||||
return _wrap(output, idx, f"STOCHRSI_{rsiLength}", "oscillators", offset)
|
||||
|
||||
|
||||
def ttm_wave(close: object, offset: int = 0, **kwargs) -> object:
|
||||
"""TTM Wave."""
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
dst = _out(n)
|
||||
_check(_lib.qtl_ttmwave(_ptr(src), n, _ptr(dst)))
|
||||
return _wrap(dst, idx, "TTM_WAVE", "oscillators", offset)
|
||||
|
||||
|
||||
def ultosc(high: object, low: object, close: object, period1: int = 14, period2: int = 14, period3: int = 14, offset: int = 0, **kwargs) -> object:
|
||||
"""Ultimate Oscillator."""
|
||||
period1 = int(period1)
|
||||
period2 = int(period2)
|
||||
period3 = int(period3)
|
||||
offset = int(offset)
|
||||
h, idx = _arr(high); l, _ = _arr(low); c, _ = _arr(close)
|
||||
n = len(h)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_ultosc(_ptr(h), _ptr(l), _ptr(c), _ptr(output), n, period1, period2, period3))
|
||||
return _wrap(output, idx, f"ULTOSC_{period1}", "oscillators", offset)
|
||||
|
||||
|
||||
def willr(high: object, low: object, close: object, period: int = 14, offset: int = 0, **kwargs) -> object:
|
||||
"""Williams %R."""
|
||||
period = int(period)
|
||||
offset = int(offset)
|
||||
h, idx = _arr(high); l, _ = _arr(low); c, _ = _arr(close)
|
||||
n = len(h)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_willr(_ptr(h), _ptr(l), _ptr(c), _ptr(output), n, period))
|
||||
return _wrap(output, idx, f"WILLR_{period}", "oscillators", offset)
|
||||
|
||||
def fisher(close: object, length: int = 9, offset: int = 0, **kwargs) -> object:
|
||||
"""Fisher Transform."""
|
||||
length = int(length); offset = int(offset)
|
||||
src, idx = _arr(close); n = len(src); dst = _out(n)
|
||||
_check(_lib.qtl_fisher(_ptr(src), n, _ptr(dst), length))
|
||||
return _wrap(dst, idx, f"FISHER_{length}", "oscillators", offset)
|
||||
|
||||
|
||||
def fisher04(close: object, length: int = 9, offset: int = 0, **kwargs) -> object:
|
||||
"""Fisher Transform (0.4 variant)."""
|
||||
length = int(length); offset = int(offset)
|
||||
src, idx = _arr(close); n = len(src); dst = _out(n)
|
||||
_check(_lib.qtl_fisher04(_ptr(src), n, _ptr(dst), length))
|
||||
return _wrap(dst, idx, f"FISHER04_{length}", "oscillators", offset)
|
||||
|
||||
|
||||
def dpo(close: object, length: int = 20, offset: int = 0, **kwargs) -> object:
|
||||
"""Detrended Price Oscillator."""
|
||||
length = int(length); offset = int(offset)
|
||||
src, idx = _arr(close); n = len(src); dst = _out(n)
|
||||
_check(_lib.qtl_dpo(_ptr(src), n, _ptr(dst), length))
|
||||
return _wrap(dst, idx, f"DPO_{length}", "oscillators", offset)
|
||||
|
||||
|
||||
def trix(close: object, length: int = 18, offset: int = 0, **kwargs) -> object:
|
||||
"""Triple EMA Rate of Change."""
|
||||
length = int(length); offset = int(offset)
|
||||
src, idx = _arr(close); n = len(src); dst = _out(n)
|
||||
_check(_lib.qtl_trix(_ptr(src), n, _ptr(dst), length))
|
||||
return _wrap(dst, idx, f"TRIX_{length}", "oscillators", offset)
|
||||
|
||||
|
||||
def inertia(close: object, length: int = 20, offset: int = 0, **kwargs) -> object:
|
||||
"""Inertia."""
|
||||
length = int(length); offset = int(offset)
|
||||
src, idx = _arr(close); n = len(src); dst = _out(n)
|
||||
_check(_lib.qtl_inertia(_ptr(src), n, _ptr(dst), length))
|
||||
return _wrap(dst, idx, f"INERTIA_{length}", "oscillators", offset)
|
||||
|
||||
|
||||
def rsx(close: object, length: int = 14, offset: int = 0, **kwargs) -> object:
|
||||
"""Relative Strength Xtra."""
|
||||
length = int(length); offset = int(offset)
|
||||
src, idx = _arr(close); n = len(src); dst = _out(n)
|
||||
_check(_lib.qtl_rsx(_ptr(src), n, _ptr(dst), length))
|
||||
return _wrap(dst, idx, f"RSX_{length}", "oscillators", offset)
|
||||
|
||||
|
||||
def er(close: object, length: int = 10, offset: int = 0, **kwargs) -> object:
|
||||
"""Efficiency Ratio."""
|
||||
length = int(length); offset = int(offset)
|
||||
src, idx = _arr(close); n = len(src); dst = _out(n)
|
||||
_check(_lib.qtl_er(_ptr(src), n, _ptr(dst), length))
|
||||
return _wrap(dst, idx, f"ER_{length}", "oscillators", offset)
|
||||
|
||||
|
||||
def cti(close: object, length: int = 12, offset: int = 0, **kwargs) -> object:
|
||||
"""Correlation Trend Indicator."""
|
||||
length = int(length); offset = int(offset)
|
||||
src, idx = _arr(close); n = len(src); dst = _out(n)
|
||||
_check(_lib.qtl_cti(_ptr(src), n, _ptr(dst), length))
|
||||
return _wrap(dst, idx, f"CTI_{length}", "oscillators", offset)
|
||||
|
||||
|
||||
def reflex(close: object, length: int = 20, offset: int = 0, **kwargs) -> object:
|
||||
"""Reflex."""
|
||||
length = int(length); offset = int(offset)
|
||||
src, idx = _arr(close); n = len(src); dst = _out(n)
|
||||
_check(_lib.qtl_reflex(_ptr(src), n, _ptr(dst), length))
|
||||
return _wrap(dst, idx, f"REFLEX_{length}", "oscillators", offset)
|
||||
|
||||
|
||||
def trendflex(close: object, length: int = 20, offset: int = 0, **kwargs) -> object:
|
||||
"""Trendflex."""
|
||||
length = int(length); offset = int(offset)
|
||||
src, idx = _arr(close); n = len(src); dst = _out(n)
|
||||
_check(_lib.qtl_trendflex(_ptr(src), n, _ptr(dst), length))
|
||||
return _wrap(dst, idx, f"TRENDFLEX_{length}", "oscillators", offset)
|
||||
|
||||
|
||||
def kri(close: object, length: int = 20, offset: int = 0, **kwargs) -> object:
|
||||
"""Kairi Relative Index."""
|
||||
length = int(length); offset = int(offset)
|
||||
src, idx = _arr(close); n = len(src); dst = _out(n)
|
||||
_check(_lib.qtl_kri(_ptr(src), n, _ptr(dst), length))
|
||||
return _wrap(dst, idx, f"KRI_{length}", "oscillators", offset)
|
||||
|
||||
|
||||
def psl(close: object, length: int = 12, offset: int = 0, **kwargs) -> object:
|
||||
"""Psychological Line."""
|
||||
length = int(length); offset = int(offset)
|
||||
src, idx = _arr(close); n = len(src); dst = _out(n)
|
||||
_check(_lib.qtl_psl(_ptr(src), n, _ptr(dst), length))
|
||||
return _wrap(dst, idx, f"PSL_{length}", "oscillators", offset)
|
||||
|
||||
|
||||
def deco(close: object, short_period: int = 30, long_period: int = 60,
|
||||
offset: int = 0, **kwargs) -> object:
|
||||
"""DECO."""
|
||||
short_period = int(short_period); long_period = int(long_period); offset = int(offset)
|
||||
src, idx = _arr(close); n = len(src); dst = _out(n)
|
||||
_check(_lib.qtl_deco(_ptr(src), n, _ptr(dst), short_period, long_period))
|
||||
return _wrap(dst, idx, f"DECO_{short_period}_{long_period}", "oscillators", offset)
|
||||
|
||||
|
||||
def dosc(close: object, rsi_period: int = 14, ema1_period: int = 5,
|
||||
ema2_period: int = 3, signal_period: int = 9,
|
||||
offset: int = 0, **kwargs) -> object:
|
||||
"""DeMarker Oscillator."""
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close); n = len(src); dst = _out(n)
|
||||
_check(_lib.qtl_dosc(_ptr(src), n, _ptr(dst),
|
||||
int(rsi_period), int(ema1_period), int(ema2_period), int(signal_period)))
|
||||
return _wrap(dst, idx, f"DOSC_{rsi_period}", "oscillators", offset)
|
||||
|
||||
|
||||
def dymoi(close: object, base_period: int = 14, short_period: int = 5,
|
||||
long_period: int = 10, min_period: int = 3, max_period: int = 30,
|
||||
offset: int = 0, **kwargs) -> object:
|
||||
"""Dynamic Momentum Index."""
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close); n = len(src); dst = _out(n)
|
||||
_check(_lib.qtl_dymoi(_ptr(src), n, _ptr(dst),
|
||||
int(base_period), int(short_period), int(long_period),
|
||||
int(min_period), int(max_period)))
|
||||
return _wrap(dst, idx, "DYMOI", "oscillators", offset)
|
||||
|
||||
|
||||
def crsi(close: object, rsi_period: int = 3, streak_period: int = 2,
|
||||
rank_period: int = 100, offset: int = 0, **kwargs) -> object:
|
||||
"""Connors RSI."""
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close); n = len(src); dst = _out(n)
|
||||
_check(_lib.qtl_crsi(_ptr(src), n, _ptr(dst),
|
||||
int(rsi_period), int(streak_period), int(rank_period)))
|
||||
return _wrap(dst, idx, f"CRSI_{rsi_period}", "oscillators", offset)
|
||||
|
||||
|
||||
def bbb(close: object, length: int = 20, mult: float = 2.0,
|
||||
offset: int = 0, **kwargs) -> object:
|
||||
"""Bollinger Band Bounce."""
|
||||
length = int(length); mult = float(mult); offset = int(offset)
|
||||
src, idx = _arr(close); n = len(src); dst = _out(n)
|
||||
_check(_lib.qtl_bbb(_ptr(src), n, _ptr(dst), length, mult))
|
||||
return _wrap(dst, idx, f"BBB_{length}", "oscillators", offset)
|
||||
|
||||
|
||||
def bbi(close: object, p1: int = 3, p2: int = 6, p3: int = 12, p4: int = 24,
|
||||
offset: int = 0, **kwargs) -> object:
|
||||
"""Bull Bear Index."""
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close); n = len(src); dst = _out(n)
|
||||
_check(_lib.qtl_bbi(_ptr(src), n, _ptr(dst), int(p1), int(p2), int(p3), int(p4)))
|
||||
return _wrap(dst, idx, "BBI", "oscillators", offset)
|
||||
|
||||
|
||||
def dem(high: object, low: object, length: int = 14,
|
||||
offset: int = 0, **kwargs) -> object:
|
||||
"""DeMarker."""
|
||||
length = int(length)
|
||||
h, idx = _arr(high); l, _ = _arr(low)
|
||||
n = len(h); dst = _out(n)
|
||||
_check(_lib.qtl_dem(_ptr(h), _ptr(l), n, _ptr(dst), length))
|
||||
return _wrap(dst, idx, f"DEM_{length}", "oscillators", int(offset))
|
||||
|
||||
|
||||
def brar(open: object, high: object, low: object, close: object,
|
||||
length: int = 26, offset: int = 0, **kwargs) -> object:
|
||||
"""Bull-Bear Ratio (BRAR)."""
|
||||
length = int(length); offset = int(offset)
|
||||
o, idx = _arr(open); h, _ = _arr(high); l, _ = _arr(low); c, _ = _arr(close)
|
||||
n = len(o); br = _out(n); ar = _out(n)
|
||||
_check(_lib.qtl_brar(_ptr(o), _ptr(h), _ptr(l), _ptr(c), n, _ptr(br), _ptr(ar), length))
|
||||
return _wrap_multi({f"BR_{length}": br, f"AR_{length}": ar}, idx, "oscillators", offset)
|
||||
@@ -0,0 +1,156 @@
|
||||
"""quantalib reversals indicators.
|
||||
|
||||
Auto-generated — DO NOT EDIT.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
from ._helpers import _arr, _ptr, _out, _wrap, _wrap_multi, _check, _lib
|
||||
|
||||
|
||||
__all__ = [
|
||||
"chandelier",
|
||||
"ckstop",
|
||||
"fractals",
|
||||
"pivot",
|
||||
"pivotcam",
|
||||
"pivotdem",
|
||||
"pivotext",
|
||||
"pivotfib",
|
||||
"pivotwood",
|
||||
"psar",
|
||||
"swings",
|
||||
"ttm_scalper",
|
||||
]
|
||||
|
||||
|
||||
def chandelier(open: object, high: object, low: object, close: object, period: int = 14, multiplier: float = 2.0, offset: int = 0, **kwargs) -> object:
|
||||
"""Chandelier Exit."""
|
||||
period = int(period)
|
||||
multiplier = float(multiplier)
|
||||
offset = int(offset)
|
||||
o, idx = _arr(open); h, _ = _arr(high); l, _ = _arr(low); c, _ = _arr(close)
|
||||
n = len(o)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_chandelier(_ptr(o), _ptr(h), _ptr(l), _ptr(c), _ptr(output), n, period, multiplier))
|
||||
return _wrap(output, idx, f"CHANDELIER_{period}", "reversals", offset)
|
||||
|
||||
|
||||
def ckstop(open: object, high: object, low: object, close: object, atrPeriod: int = 22, multiplier: float = 2.0, stopPeriod: int = 3, offset: int = 0, **kwargs) -> object:
|
||||
"""Chuck LeBeau Stop."""
|
||||
atrPeriod = int(atrPeriod)
|
||||
multiplier = float(multiplier)
|
||||
stopPeriod = int(stopPeriod)
|
||||
offset = int(offset)
|
||||
o, idx = _arr(open); h, _ = _arr(high); l, _ = _arr(low); c, _ = _arr(close)
|
||||
n = len(o)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_ckstop(_ptr(o), _ptr(h), _ptr(l), _ptr(c), _ptr(output), n, atrPeriod, multiplier, stopPeriod))
|
||||
return _wrap(output, idx, f"CKSTOP_{atrPeriod}", "reversals", offset)
|
||||
|
||||
|
||||
def fractals(high: object, low: object, offset: int = 0, **kwargs) -> object:
|
||||
"""Williams Fractals."""
|
||||
offset = int(offset)
|
||||
h, idx = _arr(high); l, _ = _arr(low)
|
||||
n = len(h)
|
||||
upOutput = _out(n)
|
||||
downOutput = _out(n)
|
||||
_check(_lib.qtl_fractals(_ptr(h), _ptr(l), _ptr(upOutput), _ptr(downOutput), n))
|
||||
return _wrap_multi({"upOutput": upOutput, "downOutput": downOutput}, idx, "reversals", offset)
|
||||
|
||||
|
||||
def pivot(high: object, low: object, close: object, offset: int = 0, **kwargs) -> object:
|
||||
"""Pivot Points (Traditional)."""
|
||||
offset = int(offset)
|
||||
h, idx = _arr(high); l, _ = _arr(low); c, _ = _arr(close)
|
||||
n = len(h)
|
||||
ppOutput = _out(n)
|
||||
_check(_lib.qtl_pivot(_ptr(h), _ptr(l), _ptr(c), _ptr(ppOutput), n))
|
||||
return _wrap(ppOutput, idx, "PIVOT", "reversals", offset)
|
||||
|
||||
|
||||
def pivotcam(high: object, low: object, close: object, offset: int = 0, **kwargs) -> object:
|
||||
"""Camarilla Pivot Points."""
|
||||
offset = int(offset)
|
||||
h, idx = _arr(high); l, _ = _arr(low); c, _ = _arr(close)
|
||||
n = len(h)
|
||||
ppOutput = _out(n)
|
||||
_check(_lib.qtl_pivotcam(_ptr(h), _ptr(l), _ptr(c), _ptr(ppOutput), n))
|
||||
return _wrap(ppOutput, idx, "PIVOTCAM", "reversals", offset)
|
||||
|
||||
|
||||
def pivotdem(open: object, high: object, low: object, close: object, offset: int = 0, **kwargs) -> object:
|
||||
"""DeMark Pivot Points."""
|
||||
offset = int(offset)
|
||||
o, idx = _arr(open); h, _ = _arr(high); l, _ = _arr(low); c, _ = _arr(close)
|
||||
n = len(o)
|
||||
ppOutput = _out(n)
|
||||
_check(_lib.qtl_pivotdem(_ptr(o), _ptr(h), _ptr(l), _ptr(c), _ptr(ppOutput), n))
|
||||
return _wrap(ppOutput, idx, "PIVOTDEM", "reversals", offset)
|
||||
|
||||
|
||||
def pivotext(high: object, low: object, close: object, offset: int = 0, **kwargs) -> object:
|
||||
"""Extended Pivot Points."""
|
||||
offset = int(offset)
|
||||
h, idx = _arr(high); l, _ = _arr(low); c, _ = _arr(close)
|
||||
n = len(h)
|
||||
ppOutput = _out(n)
|
||||
_check(_lib.qtl_pivotext(_ptr(h), _ptr(l), _ptr(c), _ptr(ppOutput), n))
|
||||
return _wrap(ppOutput, idx, "PIVOTEXT", "reversals", offset)
|
||||
|
||||
|
||||
def pivotfib(high: object, low: object, close: object, offset: int = 0, **kwargs) -> object:
|
||||
"""Fibonacci Pivot Points."""
|
||||
offset = int(offset)
|
||||
h, idx = _arr(high); l, _ = _arr(low); c, _ = _arr(close)
|
||||
n = len(h)
|
||||
ppOutput = _out(n)
|
||||
_check(_lib.qtl_pivotfib(_ptr(h), _ptr(l), _ptr(c), _ptr(ppOutput), n))
|
||||
return _wrap(ppOutput, idx, "PIVOTFIB", "reversals", offset)
|
||||
|
||||
|
||||
def pivotwood(high: object, low: object, close: object, offset: int = 0, **kwargs) -> object:
|
||||
"""Woodie Pivot Points."""
|
||||
offset = int(offset)
|
||||
h, idx = _arr(high); l, _ = _arr(low); c, _ = _arr(close)
|
||||
n = len(h)
|
||||
ppOutput = _out(n)
|
||||
_check(_lib.qtl_pivotwood(_ptr(h), _ptr(l), _ptr(c), _ptr(ppOutput), n))
|
||||
return _wrap(ppOutput, idx, "PIVOTWOOD", "reversals", offset)
|
||||
|
||||
|
||||
def psar(open: object, high: object, low: object, close: object, afStart: float = 0.02, afIncrement: float = 0.02, afMax: float = 0.2, offset: int = 0, **kwargs) -> object:
|
||||
"""Parabolic SAR."""
|
||||
afStart = float(afStart)
|
||||
afIncrement = float(afIncrement)
|
||||
afMax = float(afMax)
|
||||
offset = int(offset)
|
||||
o, idx = _arr(open); h, _ = _arr(high); l, _ = _arr(low); c, _ = _arr(close)
|
||||
n = len(o)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_psar(_ptr(o), _ptr(h), _ptr(l), _ptr(c), _ptr(output), n, afStart, afIncrement, afMax))
|
||||
return _wrap(output, idx, "PSAR", "reversals", offset)
|
||||
|
||||
|
||||
def swings(high: object, low: object, lookback: int = 5, offset: int = 0, **kwargs) -> object:
|
||||
"""Swing High/Low."""
|
||||
lookback = int(lookback)
|
||||
offset = int(offset)
|
||||
h, idx = _arr(high); l, _ = _arr(low)
|
||||
n = len(h)
|
||||
highOutput = _out(n)
|
||||
lowOutput = _out(n)
|
||||
_check(_lib.qtl_swings(_ptr(h), _ptr(l), _ptr(highOutput), _ptr(lowOutput), n, lookback))
|
||||
return _wrap_multi({"highOutput": highOutput, "lowOutput": lowOutput}, idx, "reversals", offset)
|
||||
|
||||
|
||||
def ttm_scalper(high: object, low: object, close: object, useCloses: int = 0, offset: int = 0, **kwargs) -> object:
|
||||
"""TTM Scalper."""
|
||||
useCloses = int(useCloses)
|
||||
offset = int(offset)
|
||||
h, idx = _arr(high); l, _ = _arr(low); c, _ = _arr(close)
|
||||
n = len(h)
|
||||
highOutput = _out(n)
|
||||
lowOutput = _out(n)
|
||||
_check(_lib.qtl_ttmscalper(_ptr(h), _ptr(l), _ptr(c), _ptr(highOutput), _ptr(lowOutput), n, useCloses))
|
||||
return _wrap_multi({"highOutput": highOutput, "lowOutput": lowOutput}, idx, "reversals", offset)
|
||||
@@ -0,0 +1,394 @@
|
||||
"""quantalib statistics indicators.
|
||||
|
||||
Auto-generated — DO NOT EDIT.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
from ._helpers import _arr, _ptr, _out, _wrap, _wrap_multi, _check, _lib
|
||||
|
||||
|
||||
__all__ = [
|
||||
"acf",
|
||||
"geomean",
|
||||
"granger",
|
||||
"harmean",
|
||||
"hurst",
|
||||
"iqr",
|
||||
"jb",
|
||||
"kendall",
|
||||
"kurtosis",
|
||||
"linreg",
|
||||
"meandev",
|
||||
"median",
|
||||
"mode",
|
||||
"pacf",
|
||||
"percentile",
|
||||
"polyfit",
|
||||
"quantile",
|
||||
"skew",
|
||||
"spearman",
|
||||
"stderr",
|
||||
"sum",
|
||||
"theil",
|
||||
"trim",
|
||||
"wavg",
|
||||
"wins",
|
||||
"ztest",
|
||||
"zscore",
|
||||
"cma",
|
||||
"entropy",
|
||||
"correlation",
|
||||
"covariance",
|
||||
"cointegration",
|
||||
]
|
||||
|
||||
|
||||
def acf(close: object, period: int = 14, lag: int = 10, offset: int = 0, **kwargs) -> object:
|
||||
"""Autocorrelation Function."""
|
||||
period = int(period)
|
||||
lag = int(lag)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_acf(_ptr(src), _ptr(output), n, period, lag))
|
||||
return _wrap(output, idx, f"ACF_{period}", "statistics", offset)
|
||||
|
||||
|
||||
def geomean(close: object, period: int = 14, offset: int = 0, **kwargs) -> object:
|
||||
"""Geometric Mean."""
|
||||
period = int(period)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_geomean(_ptr(src), _ptr(output), n, period))
|
||||
return _wrap(output, idx, f"GEOMEAN_{period}", "statistics", offset)
|
||||
|
||||
|
||||
def granger(x: object, y: object, period: int = 14, offset: int = 0, **kwargs) -> object:
|
||||
"""Granger Causality."""
|
||||
period = int(period)
|
||||
offset = int(offset)
|
||||
xarr, idx = _arr(x); yarr, _ = _arr(y)
|
||||
n = len(xarr)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_granger(_ptr(yarr), _ptr(xarr), _ptr(output), n, period))
|
||||
return _wrap(output, idx, f"GRANGER_{period}", "statistics", offset)
|
||||
|
||||
|
||||
def harmean(close: object, period: int = 14, offset: int = 0, **kwargs) -> object:
|
||||
"""Harmonic Mean."""
|
||||
period = int(period)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_harmean(_ptr(src), _ptr(output), n, period))
|
||||
return _wrap(output, idx, f"HARMEAN_{period}", "statistics", offset)
|
||||
|
||||
|
||||
def hurst(close: object, period: int = 14, offset: int = 0, **kwargs) -> object:
|
||||
"""Hurst Exponent."""
|
||||
period = int(period)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_hurst(_ptr(src), _ptr(output), n, period))
|
||||
return _wrap(output, idx, f"HURST_{period}", "statistics", offset)
|
||||
|
||||
|
||||
def iqr(close: object, period: int = 14, offset: int = 0, **kwargs) -> object:
|
||||
"""Interquartile Range."""
|
||||
period = int(period)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_iqr(_ptr(src), _ptr(output), n, period))
|
||||
return _wrap(output, idx, f"IQR_{period}", "statistics", offset)
|
||||
|
||||
|
||||
def jb(close: object, period: int = 14, offset: int = 0, **kwargs) -> object:
|
||||
"""Jarque-Bera Test."""
|
||||
period = int(period)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_jb(_ptr(src), _ptr(output), n, period))
|
||||
return _wrap(output, idx, f"JB_{period}", "statistics", offset)
|
||||
|
||||
|
||||
def kendall(x: object, y: object, period: int = 14, offset: int = 0, **kwargs) -> object:
|
||||
"""Kendall Rank Correlation."""
|
||||
period = int(period)
|
||||
offset = int(offset)
|
||||
xarr, idx = _arr(x); yarr, _ = _arr(y)
|
||||
n = len(xarr)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_kendall(_ptr(xarr), _ptr(yarr), _ptr(output), n, period))
|
||||
return _wrap(output, idx, f"KENDALL_{period}", "statistics", offset)
|
||||
|
||||
|
||||
def kurtosis(close: object, period: int = 14, isPopulation: int = 0, offset: int = 0, **kwargs) -> object:
|
||||
"""Kurtosis."""
|
||||
period = int(period)
|
||||
isPopulation = int(isPopulation)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_kurtosis(_ptr(src), _ptr(output), n, period, isPopulation))
|
||||
return _wrap(output, idx, f"KURTOSIS_{period}", "statistics", offset)
|
||||
|
||||
|
||||
def linreg(close: object, period: int = 14, initialLastValid: float = 0.0, offset: int = 0, **kwargs) -> object:
|
||||
"""Linear Regression."""
|
||||
period = int(period)
|
||||
initialLastValid = float(initialLastValid)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_linreg(_ptr(src), _ptr(output), n, period, initialLastValid))
|
||||
return _wrap(output, idx, f"LINREG_{period}", "statistics", offset)
|
||||
|
||||
|
||||
def meandev(close: object, period: int = 14, offset: int = 0, **kwargs) -> object:
|
||||
"""Mean Deviation."""
|
||||
period = int(period)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_meandev(_ptr(src), _ptr(output), n, period))
|
||||
return _wrap(output, idx, f"MEANDEV_{period}", "statistics", offset)
|
||||
|
||||
|
||||
def median(close: object, period: int = 14, offset: int = 0, **kwargs) -> object:
|
||||
"""Rolling Median."""
|
||||
period = int(period)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_median(_ptr(src), _ptr(output), n, period))
|
||||
return _wrap(output, idx, f"MEDIAN_{period}", "statistics", offset)
|
||||
|
||||
|
||||
def mode(close: object, period: int = 14, offset: int = 0, **kwargs) -> object:
|
||||
"""Rolling Mode."""
|
||||
period = int(period)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_mode(_ptr(src), _ptr(output), n, period))
|
||||
return _wrap(output, idx, f"MODE_{period}", "statistics", offset)
|
||||
|
||||
|
||||
def pacf(close: object, period: int = 14, lag: int = 10, offset: int = 0, **kwargs) -> object:
|
||||
"""Partial Autocorrelation Function."""
|
||||
period = int(period)
|
||||
lag = int(lag)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_pacf(_ptr(src), _ptr(output), n, period, lag))
|
||||
return _wrap(output, idx, f"PACF_{period}", "statistics", offset)
|
||||
|
||||
|
||||
def percentile(close: object, period: int = 14, percent: float = 50.0, offset: int = 0, **kwargs) -> object:
|
||||
"""Rolling Percentile."""
|
||||
period = int(period)
|
||||
percent = float(percent)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_percentile(_ptr(src), _ptr(output), n, period, percent))
|
||||
return _wrap(output, idx, f"PERCENTILE_{period}", "statistics", offset)
|
||||
|
||||
|
||||
def polyfit(close: object, period: int = 14, degree: int = 2, initialLastValid: float = 0.0, offset: int = 0, **kwargs) -> object:
|
||||
"""Polynomial Fit."""
|
||||
period = int(period)
|
||||
degree = int(degree)
|
||||
initialLastValid = float(initialLastValid)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_polyfit(_ptr(src), _ptr(output), n, period, degree, initialLastValid))
|
||||
return _wrap(output, idx, f"POLYFIT_{period}", "statistics", offset)
|
||||
|
||||
|
||||
def quantile(close: object, period: int = 14, quantileLevel: float = 0.5, offset: int = 0, **kwargs) -> object:
|
||||
"""Rolling Quantile."""
|
||||
period = int(period)
|
||||
quantileLevel = float(quantileLevel)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_quantile(_ptr(src), _ptr(output), n, period, quantileLevel))
|
||||
return _wrap(output, idx, f"QUANTILE_{period}", "statistics", offset)
|
||||
|
||||
|
||||
def skew(close: object, period: int = 14, isPopulation: int = 0, offset: int = 0, **kwargs) -> object:
|
||||
"""Skewness."""
|
||||
period = int(period)
|
||||
isPopulation = int(isPopulation)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_skew(_ptr(src), _ptr(output), n, period, isPopulation))
|
||||
return _wrap(output, idx, f"SKEW_{period}", "statistics", offset)
|
||||
|
||||
|
||||
def spearman(x: object, y: object, period: int = 14, offset: int = 0, **kwargs) -> object:
|
||||
"""Spearman Rank Correlation."""
|
||||
period = int(period)
|
||||
offset = int(offset)
|
||||
xarr, idx = _arr(x); yarr, _ = _arr(y)
|
||||
n = len(xarr)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_spearman(_ptr(xarr), _ptr(yarr), _ptr(output), n, period))
|
||||
return _wrap(output, idx, f"SPEARMAN_{period}", "statistics", offset)
|
||||
|
||||
|
||||
def stderr(close: object, period: int = 14, offset: int = 0, **kwargs) -> object:
|
||||
"""Standard Error."""
|
||||
period = int(period)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_stderr(_ptr(src), _ptr(output), n, period))
|
||||
return _wrap(output, idx, f"STDERR_{period}", "statistics", offset)
|
||||
|
||||
|
||||
def sum(close: object, period: int = 14, offset: int = 0, **kwargs) -> object:
|
||||
"""Rolling Sum."""
|
||||
period = int(period)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_sum(_ptr(src), _ptr(output), n, period))
|
||||
return _wrap(output, idx, f"SUM_{period}", "statistics", offset)
|
||||
|
||||
|
||||
def theil(close: object, period: int = 14, offset: int = 0, **kwargs) -> object:
|
||||
"""Theil U Statistic."""
|
||||
period = int(period)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_theil(_ptr(src), _ptr(output), n, period))
|
||||
return _wrap(output, idx, f"THEIL_{period}", "statistics", offset)
|
||||
|
||||
|
||||
def trim(close: object, period: int = 14, trimPct: float = 0.1, offset: int = 0, **kwargs) -> object:
|
||||
"""Trimmed Mean."""
|
||||
period = int(period)
|
||||
trimPct = float(trimPct)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_trim(_ptr(src), _ptr(output), n, period, trimPct))
|
||||
return _wrap(output, idx, f"TRIM_{period}", "statistics", offset)
|
||||
|
||||
|
||||
def wavg(close: object, period: int = 14, offset: int = 0, **kwargs) -> object:
|
||||
"""Weighted Average."""
|
||||
period = int(period)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_wavg(_ptr(src), _ptr(output), n, period))
|
||||
return _wrap(output, idx, f"WAVG_{period}", "statistics", offset)
|
||||
|
||||
|
||||
def wins(close: object, period: int = 14, winPct: float = 0.05, offset: int = 0, **kwargs) -> object:
|
||||
"""Winsorized Mean."""
|
||||
period = int(period)
|
||||
winPct = float(winPct)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_wins(_ptr(src), _ptr(output), n, period, winPct))
|
||||
return _wrap(output, idx, f"WINS_{period}", "statistics", offset)
|
||||
|
||||
|
||||
def ztest(close: object, period: int = 14, mu0: float = 0.0, offset: int = 0, **kwargs) -> object:
|
||||
"""Z-Test."""
|
||||
period = int(period)
|
||||
mu0 = float(mu0)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_ztest(_ptr(src), _ptr(output), n, period, mu0))
|
||||
return _wrap(output, idx, f"ZTEST_{period}", "statistics", offset)
|
||||
|
||||
def zscore(close: object, length: int = 20, offset: int = 0, **kwargs) -> object:
|
||||
"""Z-Score."""
|
||||
length = int(length); offset = int(offset)
|
||||
src, idx = _arr(close); n = len(src); dst = _out(n)
|
||||
_check(_lib.qtl_zscore(_ptr(src), n, _ptr(dst), length))
|
||||
return _wrap(dst, idx, f"ZSCORE_{length}", "statistics", offset)
|
||||
|
||||
|
||||
def cma(close: object, offset: int = 0, **kwargs) -> object:
|
||||
"""Cumulative Moving Average."""
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close); n = len(src); dst = _out(n)
|
||||
_check(_lib.qtl_cma(_ptr(src), n, _ptr(dst)))
|
||||
return _wrap(dst, idx, "CMA", "statistics", offset)
|
||||
|
||||
|
||||
def entropy(close: object, length: int = 10, offset: int = 0, **kwargs) -> object:
|
||||
"""Shannon Entropy."""
|
||||
length = int(length); offset = int(offset)
|
||||
src, idx = _arr(close); n = len(src); dst = _out(n)
|
||||
_check(_lib.qtl_entropy(_ptr(src), n, _ptr(dst), length))
|
||||
return _wrap(dst, idx, f"ENTROPY_{length}", "statistics", offset)
|
||||
|
||||
|
||||
def correlation(x: object, y: object, length: int = 20,
|
||||
offset: int = 0, **kwargs) -> object:
|
||||
"""Pearson Correlation."""
|
||||
length = int(length); offset = int(offset)
|
||||
xarr, idx = _arr(x); yarr, _ = _arr(y)
|
||||
n = len(xarr); dst = _out(n)
|
||||
_check(_lib.qtl_correlation(_ptr(xarr), _ptr(yarr), n, _ptr(dst), length))
|
||||
return _wrap(dst, idx, f"CORR_{length}", "statistics", offset)
|
||||
|
||||
|
||||
def covariance(x: object, y: object, length: int = 20,
|
||||
is_sample: bool = True, offset: int = 0, **kwargs) -> object:
|
||||
"""Covariance."""
|
||||
length = int(length); offset = int(offset)
|
||||
xarr, idx = _arr(x); yarr, _ = _arr(y)
|
||||
n = len(xarr); dst = _out(n)
|
||||
_check(_lib.qtl_covariance(_ptr(xarr), _ptr(yarr), n, _ptr(dst), length, int(is_sample)))
|
||||
return _wrap(dst, idx, f"COV_{length}", "statistics", offset)
|
||||
|
||||
|
||||
def cointegration(x: object, y: object, length: int = 20,
|
||||
offset: int = 0, **kwargs) -> object:
|
||||
"""Cointegration."""
|
||||
length = int(length); offset = int(offset)
|
||||
xarr, idx = _arr(x); yarr, _ = _arr(y)
|
||||
n = len(xarr); dst = _out(n)
|
||||
_check(_lib.qtl_cointegration(_ptr(xarr), _ptr(yarr), n, _ptr(dst), length))
|
||||
return _wrap(dst, idx, f"COINT_{length}", "statistics", offset)
|
||||
@@ -0,0 +1,371 @@
|
||||
"""quantalib trends_fir indicators.
|
||||
|
||||
Auto-generated — DO NOT EDIT.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
from ._helpers import _arr, _ptr, _out, _wrap, _wrap_multi, _check, _lib
|
||||
|
||||
|
||||
__all__ = [
|
||||
"fwma",
|
||||
"gwma",
|
||||
"hamma",
|
||||
"hend",
|
||||
"ilrs",
|
||||
"kaiser",
|
||||
"lanczos",
|
||||
"nlma",
|
||||
"nyqma",
|
||||
"pma",
|
||||
"pwma",
|
||||
"qrma",
|
||||
"rwma",
|
||||
"sma",
|
||||
"wma",
|
||||
"hma",
|
||||
"trima",
|
||||
"swma",
|
||||
"dwma",
|
||||
"blma",
|
||||
"alma",
|
||||
"lsma",
|
||||
"sgma",
|
||||
"sinema",
|
||||
"hanma",
|
||||
"parzen",
|
||||
"tsf",
|
||||
"conv",
|
||||
"bwma",
|
||||
"crma",
|
||||
"sp15",
|
||||
"tukey_w",
|
||||
"rain",
|
||||
"afirma",
|
||||
]
|
||||
|
||||
|
||||
def fwma(close: object, period: int = 14, offset: int = 0, **kwargs) -> object:
|
||||
"""Fibonacci Weighted Moving Average."""
|
||||
period = int(period)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_fwma(_ptr(src), _ptr(output), n, period))
|
||||
return _wrap(output, idx, f"FWMA_{period}", "trends_fir", offset)
|
||||
|
||||
|
||||
def gwma(close: object, period: int = 14, sigma: float = 6.0, offset: int = 0, **kwargs) -> object:
|
||||
"""Gaussian Weighted Moving Average."""
|
||||
period = int(period)
|
||||
sigma = float(sigma)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_gwma(_ptr(src), _ptr(output), n, period, sigma))
|
||||
return _wrap(output, idx, f"GWMA_{period}", "trends_fir", offset)
|
||||
|
||||
|
||||
def hamma(close: object, period: int = 14, offset: int = 0, **kwargs) -> object:
|
||||
"""Hamming Moving Average."""
|
||||
period = int(period)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_hamma(_ptr(src), _ptr(output), n, period))
|
||||
return _wrap(output, idx, f"HAMMA_{period}", "trends_fir", offset)
|
||||
|
||||
|
||||
def hend(close: object, period: int = 14, nanValue: float = 0.0, offset: int = 0, **kwargs) -> object:
|
||||
"""Henderson Moving Average."""
|
||||
period = int(period)
|
||||
nanValue = float(nanValue)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_hend(_ptr(src), _ptr(output), n, period, nanValue))
|
||||
return _wrap(output, idx, f"HEND_{period}", "trends_fir", offset)
|
||||
|
||||
|
||||
def ilrs(close: object, period: int = 14, offset: int = 0, **kwargs) -> object:
|
||||
"""Integral of Linear Regression Slope."""
|
||||
period = int(period)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_ilrs(_ptr(src), _ptr(output), n, period))
|
||||
return _wrap(output, idx, f"ILRS_{period}", "trends_fir", offset)
|
||||
|
||||
|
||||
def kaiser(close: object, period: int = 14, beta: float = 2.0, nanValue: float = 0.0, offset: int = 0, **kwargs) -> object:
|
||||
"""Kaiser Window Moving Average."""
|
||||
period = int(period)
|
||||
beta = float(beta)
|
||||
nanValue = float(nanValue)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_kaiser(_ptr(src), _ptr(output), n, period, beta, nanValue))
|
||||
return _wrap(output, idx, f"KAISER_{period}", "trends_fir", offset)
|
||||
|
||||
|
||||
def lanczos(close: object, period: int = 14, nanValue: float = 0.0, offset: int = 0, **kwargs) -> object:
|
||||
"""Lanczos Moving Average."""
|
||||
period = int(period)
|
||||
nanValue = float(nanValue)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_lanczos(_ptr(src), _ptr(output), n, period, nanValue))
|
||||
return _wrap(output, idx, f"LANCZOS_{period}", "trends_fir", offset)
|
||||
|
||||
|
||||
def nlma(close: object, period: int = 14, offset: int = 0, **kwargs) -> object:
|
||||
"""Non-Lag Moving Average."""
|
||||
period = int(period)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_nlma(_ptr(src), _ptr(output), n, period))
|
||||
return _wrap(output, idx, f"NLMA_{period}", "trends_fir", offset)
|
||||
|
||||
|
||||
def nyqma(close: object, period: int = 14, nyquistPeriod: int = 2, offset: int = 0, **kwargs) -> object:
|
||||
"""Nyquist Moving Average."""
|
||||
period = int(period)
|
||||
nyquistPeriod = int(nyquistPeriod)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_nyqma(_ptr(src), _ptr(output), n, period, nyquistPeriod))
|
||||
return _wrap(output, idx, f"NYQMA_{period}", "trends_fir", offset)
|
||||
|
||||
|
||||
def pma(close: object, period: int = 14, offset: int = 0, **kwargs) -> object:
|
||||
"""Predictive Moving Average."""
|
||||
period = int(period)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
pmaOutput = _out(n)
|
||||
triggerOutput = _out(n)
|
||||
_check(_lib.qtl_pma(_ptr(src), _ptr(pmaOutput), _ptr(triggerOutput), n, period))
|
||||
return _wrap_multi({"pmaOutput": pmaOutput, "triggerOutput": triggerOutput}, idx, "trends_fir", offset)
|
||||
|
||||
|
||||
def pwma(close: object, period: int = 14, offset: int = 0, **kwargs) -> object:
|
||||
"""Pascal Weighted Moving Average."""
|
||||
period = int(period)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_pwma(_ptr(src), _ptr(output), n, period))
|
||||
return _wrap(output, idx, f"PWMA_{period}", "trends_fir", offset)
|
||||
|
||||
|
||||
def qrma(close: object, period: int = 14, initialLastValid: float = 0.0, offset: int = 0, **kwargs) -> object:
|
||||
"""Quick Reaction Moving Average."""
|
||||
period = int(period)
|
||||
initialLastValid = float(initialLastValid)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_qrma(_ptr(src), _ptr(output), n, period, initialLastValid))
|
||||
return _wrap(output, idx, f"QRMA_{period}", "trends_fir", offset)
|
||||
|
||||
|
||||
def rwma(high: object, low: object, close: object, period: int = 14, offset: int = 0, **kwargs) -> object:
|
||||
"""Range Weighted Moving Average."""
|
||||
period = int(period)
|
||||
offset = int(offset)
|
||||
h, idx = _arr(high); l, _ = _arr(low); c, _ = _arr(close)
|
||||
n = len(h)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_rwma(_ptr(c), _ptr(h), _ptr(l), _ptr(output), n, period))
|
||||
return _wrap(output, idx, f"RWMA_{period}", "trends_fir", offset)
|
||||
|
||||
def sma(close: object, length: int = 10, offset: int = 0, **kwargs) -> object:
|
||||
"""Simple Moving Average."""
|
||||
length = int(length); offset = int(offset)
|
||||
src, idx = _arr(close); n = len(src); dst = _out(n)
|
||||
_check(_lib.qtl_sma(_ptr(src), n, _ptr(dst), length))
|
||||
return _wrap(dst, idx, f"SMA_{length}", "trends_fir", offset)
|
||||
|
||||
|
||||
def wma(close: object, length: int = 10, offset: int = 0, **kwargs) -> object:
|
||||
"""Weighted Moving Average."""
|
||||
length = int(length); offset = int(offset)
|
||||
src, idx = _arr(close); n = len(src); dst = _out(n)
|
||||
_check(_lib.qtl_wma(_ptr(src), n, _ptr(dst), length))
|
||||
return _wrap(dst, idx, f"WMA_{length}", "trends_fir", offset)
|
||||
|
||||
|
||||
def hma(close: object, length: int = 9, offset: int = 0, **kwargs) -> object:
|
||||
"""Hull Moving Average."""
|
||||
length = int(length); offset = int(offset)
|
||||
src, idx = _arr(close); n = len(src); dst = _out(n)
|
||||
_check(_lib.qtl_hma(_ptr(src), n, _ptr(dst), length))
|
||||
return _wrap(dst, idx, f"HMA_{length}", "trends_fir", offset)
|
||||
|
||||
|
||||
def trima(close: object, length: int = 10, offset: int = 0, **kwargs) -> object:
|
||||
"""Triangular Moving Average."""
|
||||
length = int(length); offset = int(offset)
|
||||
src, idx = _arr(close); n = len(src); dst = _out(n)
|
||||
_check(_lib.qtl_trima(_ptr(src), n, _ptr(dst), length))
|
||||
return _wrap(dst, idx, f"TRIMA_{length}", "trends_fir", offset)
|
||||
|
||||
|
||||
def swma(close: object, length: int = 10, offset: int = 0, **kwargs) -> object:
|
||||
"""Symmetric Weighted Moving Average."""
|
||||
length = int(length); offset = int(offset)
|
||||
src, idx = _arr(close); n = len(src); dst = _out(n)
|
||||
_check(_lib.qtl_swma(_ptr(src), n, _ptr(dst), length))
|
||||
return _wrap(dst, idx, f"SWMA_{length}", "trends_fir", offset)
|
||||
|
||||
|
||||
def dwma(close: object, length: int = 10, offset: int = 0, **kwargs) -> object:
|
||||
"""Double Weighted Moving Average."""
|
||||
length = int(length); offset = int(offset)
|
||||
src, idx = _arr(close); n = len(src); dst = _out(n)
|
||||
_check(_lib.qtl_dwma(_ptr(src), n, _ptr(dst), length))
|
||||
return _wrap(dst, idx, f"DWMA_{length}", "trends_fir", offset)
|
||||
|
||||
|
||||
def blma(close: object, length: int = 10, offset: int = 0, **kwargs) -> object:
|
||||
"""Blackman Moving Average."""
|
||||
length = int(length); offset = int(offset)
|
||||
src, idx = _arr(close); n = len(src); dst = _out(n)
|
||||
_check(_lib.qtl_blma(_ptr(src), n, _ptr(dst), length))
|
||||
return _wrap(dst, idx, f"BLMA_{length}", "trends_fir", offset)
|
||||
|
||||
|
||||
def alma(close: object, length: int = 10, alma_offset: float = 0.85,
|
||||
sigma: float = 6.0, offset: int = 0, **kwargs) -> object:
|
||||
"""Arnaud Legoux Moving Average."""
|
||||
length = int(length); offset = int(offset)
|
||||
src, idx = _arr(close); n = len(src); dst = _out(n)
|
||||
_check(_lib.qtl_alma(_ptr(src), n, _ptr(dst), length, float(alma_offset), float(sigma)))
|
||||
return _wrap(dst, idx, f"ALMA_{length}", "trends_fir", offset)
|
||||
|
||||
|
||||
def lsma(close: object, length: int = 25, offset: int = 0, **kwargs) -> object:
|
||||
"""Least Squares Moving Average."""
|
||||
length = int(length); offset = int(offset)
|
||||
src, idx = _arr(close); n = len(src); dst = _out(n)
|
||||
_check(_lib.qtl_lsma(_ptr(src), n, _ptr(dst), length, 0, 1.0))
|
||||
return _wrap(dst, idx, f"LSMA_{length}", "trends_fir", offset)
|
||||
|
||||
|
||||
def sgma(close: object, length: int = 10, offset: int = 0, **kwargs) -> object:
|
||||
"""Savitzky-Golay Moving Average."""
|
||||
length = int(length); offset = int(offset)
|
||||
src, idx = _arr(close); n = len(src); dst = _out(n)
|
||||
_check(_lib.qtl_sgma(_ptr(src), n, _ptr(dst), length))
|
||||
return _wrap(dst, idx, f"SGMA_{length}", "trends_fir", offset)
|
||||
|
||||
|
||||
def sinema(close: object, length: int = 10, offset: int = 0, **kwargs) -> object:
|
||||
"""Sine-weighted Moving Average."""
|
||||
length = int(length); offset = int(offset)
|
||||
src, idx = _arr(close); n = len(src); dst = _out(n)
|
||||
_check(_lib.qtl_sinema(_ptr(src), n, _ptr(dst), length))
|
||||
return _wrap(dst, idx, f"SINEMA_{length}", "trends_fir", offset)
|
||||
|
||||
|
||||
def hanma(close: object, length: int = 10, offset: int = 0, **kwargs) -> object:
|
||||
"""Hann-weighted Moving Average."""
|
||||
length = int(length); offset = int(offset)
|
||||
src, idx = _arr(close); n = len(src); dst = _out(n)
|
||||
_check(_lib.qtl_hanma(_ptr(src), n, _ptr(dst), length))
|
||||
return _wrap(dst, idx, f"HANMA_{length}", "trends_fir", offset)
|
||||
|
||||
|
||||
def parzen(close: object, length: int = 10, offset: int = 0, **kwargs) -> object:
|
||||
"""Parzen-weighted Moving Average."""
|
||||
length = int(length); offset = int(offset)
|
||||
src, idx = _arr(close); n = len(src); dst = _out(n)
|
||||
_check(_lib.qtl_parzen(_ptr(src), n, _ptr(dst), length))
|
||||
return _wrap(dst, idx, f"PARZEN_{length}", "trends_fir", offset)
|
||||
|
||||
|
||||
def tsf(close: object, length: int = 14, offset: int = 0, **kwargs) -> object:
|
||||
"""Time Series Forecast."""
|
||||
length = int(length); offset = int(offset)
|
||||
src, idx = _arr(close); n = len(src); dst = _out(n)
|
||||
_check(_lib.qtl_tsf(_ptr(src), n, _ptr(dst), length))
|
||||
return _wrap(dst, idx, f"TSF_{length}", "trends_fir", offset)
|
||||
|
||||
|
||||
def conv(close: object, kernel: list | None = None,
|
||||
offset: int = 0, **kwargs) -> object:
|
||||
"""Convolution with custom kernel."""
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close); n = len(src); dst = _out(n)
|
||||
if kernel is None:
|
||||
kernel = [1.0]
|
||||
k = np.ascontiguousarray(kernel, dtype=_F64)
|
||||
_check(_lib.qtl_conv(_ptr(src), n, _ptr(dst), _ptr(k), len(k)))
|
||||
return _wrap(dst, idx, "CONV", "trends_fir", offset)
|
||||
|
||||
|
||||
def bwma(close: object, length: int = 10, order: int = 0,
|
||||
offset: int = 0, **kwargs) -> object:
|
||||
"""Butterworth-weighted Moving Average."""
|
||||
length = int(length); offset = int(offset)
|
||||
src, idx = _arr(close); n = len(src); dst = _out(n)
|
||||
_check(_lib.qtl_bwma(_ptr(src), n, _ptr(dst), length, int(order)))
|
||||
return _wrap(dst, idx, f"BWMA_{length}", "trends_fir", offset)
|
||||
|
||||
|
||||
def crma(close: object, length: int = 10, volume_factor: float = 1.0,
|
||||
offset: int = 0, **kwargs) -> object:
|
||||
"""Cosine-Ramp Moving Average."""
|
||||
length = int(length); offset = int(offset)
|
||||
src, idx = _arr(close); n = len(src); dst = _out(n)
|
||||
_check(_lib.qtl_crma(_ptr(src), n, _ptr(dst), length, float(volume_factor)))
|
||||
return _wrap(dst, idx, f"CRMA_{length}", "trends_fir", offset)
|
||||
|
||||
|
||||
def sp15(close: object, length: int = 15, offset: int = 0, **kwargs) -> object:
|
||||
"""SP-15 Moving Average."""
|
||||
length = int(length); offset = int(offset)
|
||||
src, idx = _arr(close); n = len(src); dst = _out(n)
|
||||
_check(_lib.qtl_sp15(_ptr(src), n, _ptr(dst), length))
|
||||
return _wrap(dst, idx, f"SP15_{length}", "trends_fir", offset)
|
||||
|
||||
|
||||
def tukey_w(close: object, length: int = 10, offset: int = 0, **kwargs) -> object:
|
||||
"""Tukey-windowed Moving Average."""
|
||||
length = int(length); offset = int(offset)
|
||||
src, idx = _arr(close); n = len(src); dst = _out(n)
|
||||
_check(_lib.qtl_tukey_w(_ptr(src), n, _ptr(dst), length))
|
||||
return _wrap(dst, idx, f"TUKEY_{length}", "trends_fir", offset)
|
||||
|
||||
|
||||
def rain(close: object, length: int = 10, offset: int = 0, **kwargs) -> object:
|
||||
"""RAIN Moving Average."""
|
||||
length = int(length); offset = int(offset)
|
||||
src, idx = _arr(close); n = len(src); dst = _out(n)
|
||||
_check(_lib.qtl_rain(_ptr(src), n, _ptr(dst), length))
|
||||
return _wrap(dst, idx, f"RAIN_{length}", "trends_fir", offset)
|
||||
|
||||
|
||||
def afirma(close: object, length: int = 10, window_type: int = 0,
|
||||
use_simd: bool = False, offset: int = 0, **kwargs) -> object:
|
||||
"""Adaptive FIR Moving Average."""
|
||||
length = int(length); offset = int(offset)
|
||||
src, idx = _arr(close); n = len(src); dst = _out(n)
|
||||
_check(_lib.qtl_afirma(_ptr(src), n, _ptr(dst), length, int(window_type), int(use_simd)))
|
||||
return _wrap(dst, idx, f"AFIRMA_{length}", "trends_fir", offset)
|
||||
@@ -0,0 +1,473 @@
|
||||
"""quantalib trends_iir indicators.
|
||||
|
||||
Auto-generated — DO NOT EDIT.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
from ._helpers import _arr, _ptr, _out, _wrap, _wrap_multi, _check, _lib
|
||||
|
||||
|
||||
__all__ = [
|
||||
"adxvma",
|
||||
"frama",
|
||||
"holt",
|
||||
"htit",
|
||||
"hwma",
|
||||
"jma",
|
||||
"kama",
|
||||
"ltma",
|
||||
"mama",
|
||||
"mavp",
|
||||
"mcnma",
|
||||
"mgdi",
|
||||
"mma",
|
||||
"nma",
|
||||
"qema",
|
||||
"rema",
|
||||
"rgma",
|
||||
"rma",
|
||||
"t3",
|
||||
"trama",
|
||||
"vama",
|
||||
"vidya",
|
||||
"yzvama",
|
||||
"zldema",
|
||||
"zlema",
|
||||
"zltema",
|
||||
"ema",
|
||||
"ema_alpha",
|
||||
"dema",
|
||||
"dema_alpha",
|
||||
"tema",
|
||||
"lema",
|
||||
"hema",
|
||||
"ahrens",
|
||||
"decycler",
|
||||
"dsma",
|
||||
"gdema",
|
||||
"coral",
|
||||
"agc",
|
||||
"ccyc",
|
||||
]
|
||||
|
||||
|
||||
def adxvma(open: object, high: object, low: object, close: object, volume: object, period: int = 14, offset: int = 0, **kwargs) -> object:
|
||||
"""ADX Variable Moving Average."""
|
||||
period = int(period)
|
||||
offset = int(offset)
|
||||
o, idx = _arr(open); h, _ = _arr(high); l, _ = _arr(low)
|
||||
c, _ = _arr(close); v, _ = _arr(volume)
|
||||
n = len(o)
|
||||
dst = _out(n)
|
||||
_check(_lib.qtl_adxvma(_ptr(o), _ptr(h), _ptr(l), _ptr(c), _ptr(v), period, n, _ptr(dst)))
|
||||
return _wrap(dst, idx, f"ADXVMA_{period}", "trends_iir", offset)
|
||||
|
||||
|
||||
def frama(close: object, period: int = 14, offset: int = 0, **kwargs) -> object:
|
||||
"""Fractal Adaptive Moving Average."""
|
||||
period = int(period)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_frama(_ptr(src), _ptr(output), n, period))
|
||||
return _wrap(output, idx, f"FRAMA_{period}", "trends_iir", offset)
|
||||
|
||||
|
||||
def holt(close: object, period: int = 14, gamma: float = 0.7, offset: int = 0, **kwargs) -> object:
|
||||
"""Holt Exponential Smoothing."""
|
||||
period = int(period)
|
||||
gamma = float(gamma)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_holt(_ptr(src), _ptr(output), n, period, gamma))
|
||||
return _wrap(output, idx, f"HOLT_{period}", "trends_iir", offset)
|
||||
|
||||
|
||||
def htit(close: object, offset: int = 0, **kwargs) -> object:
|
||||
"""Hilbert Transform Instantaneous Trendline."""
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_htit(_ptr(src), _ptr(output), n))
|
||||
return _wrap(output, idx, "HTIT", "trends_iir", offset)
|
||||
|
||||
|
||||
def hwma(close: object, period: int = 14, offset: int = 0, **kwargs) -> object:
|
||||
"""Holt-Winter Moving Average."""
|
||||
period = int(period)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_hwma(_ptr(src), _ptr(output), n, period))
|
||||
return _wrap(output, idx, f"HWMA_{period}", "trends_iir", offset)
|
||||
|
||||
|
||||
def jma(close: object, period: int = 14, phase: int = 0, power: float = 1.0, offset: int = 0, **kwargs) -> object:
|
||||
"""Jurik Moving Average."""
|
||||
period = int(period)
|
||||
phase = int(phase)
|
||||
power = float(power)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_jma(_ptr(src), _ptr(output), n, period, phase, power))
|
||||
return _wrap(output, idx, f"JMA_{period}", "trends_iir", offset)
|
||||
|
||||
|
||||
def kama(close: object, period: int = 14, fastPeriod: int = 12, slowPeriod: int = 26, offset: int = 0, **kwargs) -> object:
|
||||
"""Kaufman Adaptive Moving Average."""
|
||||
period = int(period)
|
||||
fastPeriod = int(fastPeriod)
|
||||
slowPeriod = int(slowPeriod)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_kama(_ptr(src), _ptr(output), n, period, fastPeriod, slowPeriod))
|
||||
return _wrap(output, idx, f"KAMA_{period}", "trends_iir", offset)
|
||||
|
||||
|
||||
def ltma(close: object, period: int = 14, offset: int = 0, **kwargs) -> object:
|
||||
"""Low-Lag Triple Moving Average."""
|
||||
period = int(period)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_ltma(_ptr(src), _ptr(output), n, period))
|
||||
return _wrap(output, idx, f"LTMA_{period}", "trends_iir", offset)
|
||||
|
||||
|
||||
def mama(close: object, fastLimit: float = 0.5, slowLimit: float = 0.05, offset: int = 0, **kwargs) -> object:
|
||||
"""MESA Adaptive Moving Average."""
|
||||
fastLimit = float(fastLimit)
|
||||
slowLimit = float(slowLimit)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
famaOutput = _out(n)
|
||||
_check(_lib.qtl_mama(_ptr(src), _ptr(output), fastLimit, n, slowLimit, _ptr(famaOutput)))
|
||||
return _wrap_multi({"output": output, "famaOutput": famaOutput}, idx, "trends_iir", offset)
|
||||
|
||||
|
||||
def mavp(x: object, periods: object, minPeriod: int = 6, maxPeriod: int = 48, offset: int = 0, **kwargs) -> object:
|
||||
"""Moving Average Variable Period."""
|
||||
minPeriod = int(minPeriod)
|
||||
maxPeriod = int(maxPeriod)
|
||||
offset = int(offset)
|
||||
xarr, idx = _arr(x); yarr, _ = _arr(periods)
|
||||
n = len(xarr)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_mavp(_ptr(xarr), _ptr(yarr), _ptr(output), n, minPeriod, maxPeriod))
|
||||
return _wrap(output, idx, f"MAVP_{minPeriod}", "trends_iir", offset)
|
||||
|
||||
|
||||
def mcnma(close: object, period: int = 14, offset: int = 0, **kwargs) -> object:
|
||||
"""McNicholl Moving Average."""
|
||||
period = int(period)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_mcnma(_ptr(src), _ptr(output), n, period))
|
||||
return _wrap(output, idx, f"MCNMA_{period}", "trends_iir", offset)
|
||||
|
||||
|
||||
def mgdi(close: object, period: int = 14, k: float = 2.0, offset: int = 0, **kwargs) -> object:
|
||||
"""McGinley Dynamic."""
|
||||
period = int(period)
|
||||
k = float(k)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_mgdi(_ptr(src), _ptr(output), n, period, k))
|
||||
return _wrap(output, idx, f"MGDI_{period}", "trends_iir", offset)
|
||||
|
||||
|
||||
def mma(close: object, period: int = 14, offset: int = 0, **kwargs) -> object:
|
||||
"""Modified Moving Average."""
|
||||
period = int(period)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_mma(_ptr(src), _ptr(output), n, period))
|
||||
return _wrap(output, idx, f"MMA_{period}", "trends_iir", offset)
|
||||
|
||||
|
||||
def nma(close: object, period: int = 14, offset: int = 0, **kwargs) -> object:
|
||||
"""Normalized Moving Average."""
|
||||
period = int(period)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_nma(_ptr(src), _ptr(output), n, period))
|
||||
return _wrap(output, idx, f"NMA_{period}", "trends_iir", offset)
|
||||
|
||||
|
||||
def qema(close: object, period: int = 14, offset: int = 0, **kwargs) -> object:
|
||||
"""Quadruple EMA."""
|
||||
period = int(period)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_qema(_ptr(src), _ptr(output), n, period))
|
||||
return _wrap(output, idx, f"QEMA_{period}", "trends_iir", offset)
|
||||
|
||||
|
||||
def rema(close: object, period: int = 14, lam: float = 1600.0, offset: int = 0, **kwargs) -> object:
|
||||
"""Regularized EMA."""
|
||||
period = int(period)
|
||||
lam = float(lam)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_rema(_ptr(src), _ptr(output), n, period, lam))
|
||||
return _wrap(output, idx, f"REMA_{period}", "trends_iir", offset)
|
||||
|
||||
|
||||
def rgma(close: object, period: int = 14, passes: int = 3, offset: int = 0, **kwargs) -> object:
|
||||
"""Recursive Gaussian Moving Average."""
|
||||
period = int(period)
|
||||
passes = int(passes)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_rgma(_ptr(src), _ptr(output), n, period, passes))
|
||||
return _wrap(output, idx, f"RGMA_{period}", "trends_iir", offset)
|
||||
|
||||
|
||||
def rma(close: object, period: int = 14, offset: int = 0, **kwargs) -> object:
|
||||
"""Rolling Moving Average."""
|
||||
period = int(period)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_rma(_ptr(src), _ptr(output), n, period))
|
||||
return _wrap(output, idx, f"RMA_{period}", "trends_iir", offset)
|
||||
|
||||
|
||||
def t3(close: object, period: int = 14, vfactor: float = 0.7, offset: int = 0, **kwargs) -> object:
|
||||
"""Tillson T3."""
|
||||
period = int(period)
|
||||
vfactor = float(vfactor)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_t3(_ptr(src), _ptr(output), n, period, vfactor))
|
||||
return _wrap(output, idx, f"T3_{period}", "trends_iir", offset)
|
||||
|
||||
|
||||
def trama(close: object, period: int = 14, offset: int = 0, **kwargs) -> object:
|
||||
"""Triangular Adaptive Moving Average."""
|
||||
period = int(period)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_trama(_ptr(src), _ptr(output), n, period))
|
||||
return _wrap(output, idx, f"TRAMA_{period}", "trends_iir", offset)
|
||||
|
||||
|
||||
def vama(open: object, high: object, low: object, close: object, volume: object, baseLength: int = 20, shortAtrPeriod: int = 14, longAtrPeriod: int = 50, minLength: int = 5, maxLength: int = 50, offset: int = 0, **kwargs) -> object:
|
||||
"""Volume Adjusted Moving Average."""
|
||||
baseLength = int(baseLength)
|
||||
shortAtrPeriod = int(shortAtrPeriod)
|
||||
longAtrPeriod = int(longAtrPeriod)
|
||||
minLength = int(minLength)
|
||||
maxLength = int(maxLength)
|
||||
offset = int(offset)
|
||||
o, idx = _arr(open); h, _ = _arr(high); l, _ = _arr(low)
|
||||
c, _ = _arr(close); v, _ = _arr(volume)
|
||||
n = len(o)
|
||||
dst = _out(n)
|
||||
_check(_lib.qtl_vama(_ptr(o), _ptr(h), _ptr(l), _ptr(c), _ptr(v), baseLength, shortAtrPeriod, longAtrPeriod, minLength, maxLength, n, _ptr(dst)))
|
||||
return _wrap(dst, idx, f"VAMA_{baseLength}", "trends_iir", offset)
|
||||
|
||||
|
||||
def vidya(close: object, period: int = 14, offset: int = 0, **kwargs) -> object:
|
||||
"""Variable Index Dynamic Average."""
|
||||
period = int(period)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_vidya(_ptr(src), _ptr(output), n, period))
|
||||
return _wrap(output, idx, f"VIDYA_{period}", "trends_iir", offset)
|
||||
|
||||
|
||||
def yzvama(open: object, high: object, low: object, close: object, volume: object, yzvShortPeriod: int = 10, yzvLongPeriod: int = 100, percentileLookback: int = 252, minLength: int = 5, maxLength: int = 50, offset: int = 0, **kwargs) -> object:
|
||||
"""Yang Zhang Volatility Adaptive MA."""
|
||||
yzvShortPeriod = int(yzvShortPeriod)
|
||||
yzvLongPeriod = int(yzvLongPeriod)
|
||||
percentileLookback = int(percentileLookback)
|
||||
minLength = int(minLength)
|
||||
maxLength = int(maxLength)
|
||||
offset = int(offset)
|
||||
o, idx = _arr(open); h, _ = _arr(high); l, _ = _arr(low)
|
||||
c, _ = _arr(close); v, _ = _arr(volume)
|
||||
n = len(o)
|
||||
dst = _out(n)
|
||||
_check(_lib.qtl_yzvama(_ptr(o), _ptr(h), _ptr(l), _ptr(c), _ptr(v), yzvShortPeriod, yzvLongPeriod, percentileLookback, minLength, maxLength, n, _ptr(dst)))
|
||||
return _wrap(dst, idx, f"YZVAMA_{yzvShortPeriod}", "trends_iir", offset)
|
||||
|
||||
|
||||
def zldema(close: object, period: int = 14, offset: int = 0, **kwargs) -> object:
|
||||
"""Zero-Lag Double EMA."""
|
||||
period = int(period)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_zldema(_ptr(src), _ptr(output), n, period))
|
||||
return _wrap(output, idx, f"ZLDEMA_{period}", "trends_iir", offset)
|
||||
|
||||
|
||||
def zlema(close: object, period: int = 14, offset: int = 0, **kwargs) -> object:
|
||||
"""Zero-Lag EMA."""
|
||||
period = int(period)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_zlema(_ptr(src), _ptr(output), n, period))
|
||||
return _wrap(output, idx, f"ZLEMA_{period}", "trends_iir", offset)
|
||||
|
||||
|
||||
def zltema(close: object, period: int = 14, offset: int = 0, **kwargs) -> object:
|
||||
"""Zero-Lag Triple EMA."""
|
||||
period = int(period)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_zltema(_ptr(src), _ptr(output), n, period))
|
||||
return _wrap(output, idx, f"ZLTEMA_{period}", "trends_iir", offset)
|
||||
|
||||
def ema(close: object, length: int = 10, offset: int = 0, **kwargs) -> object:
|
||||
"""Exponential Moving Average."""
|
||||
length = int(length); offset = int(offset)
|
||||
src, idx = _arr(close); n = len(src); dst = _out(n)
|
||||
_check(_lib.qtl_ema(_ptr(src), n, _ptr(dst), length))
|
||||
return _wrap(dst, idx, f"EMA_{length}", "trends_iir", offset)
|
||||
|
||||
|
||||
def ema_alpha(close: object, alpha: float = 0.1, offset: int = 0, **kwargs) -> object:
|
||||
"""EMA with explicit alpha."""
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close); n = len(src); dst = _out(n)
|
||||
_check(_lib.qtl_ema_alpha(_ptr(src), n, _ptr(dst), float(alpha)))
|
||||
return _wrap(dst, idx, f"EMA_a{alpha:.4f}", "trends_iir", offset)
|
||||
|
||||
|
||||
def dema(close: object, length: int = 10, offset: int = 0, **kwargs) -> object:
|
||||
"""Double Exponential Moving Average."""
|
||||
length = int(length); offset = int(offset)
|
||||
src, idx = _arr(close); n = len(src); dst = _out(n)
|
||||
_check(_lib.qtl_dema(_ptr(src), n, _ptr(dst), length))
|
||||
return _wrap(dst, idx, f"DEMA_{length}", "trends_iir", offset)
|
||||
|
||||
|
||||
def dema_alpha(close: object, alpha: float = 0.1, offset: int = 0, **kwargs) -> object:
|
||||
"""DEMA with explicit alpha."""
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close); n = len(src); dst = _out(n)
|
||||
_check(_lib.qtl_dema_alpha(_ptr(src), n, _ptr(dst), float(alpha)))
|
||||
return _wrap(dst, idx, f"DEMA_a{alpha:.4f}", "trends_iir", offset)
|
||||
|
||||
|
||||
def tema(close: object, length: int = 10, offset: int = 0, **kwargs) -> object:
|
||||
"""Triple Exponential Moving Average."""
|
||||
length = int(length); offset = int(offset)
|
||||
src, idx = _arr(close); n = len(src); dst = _out(n)
|
||||
_check(_lib.qtl_tema(_ptr(src), n, _ptr(dst), length))
|
||||
return _wrap(dst, idx, f"TEMA_{length}", "trends_iir", offset)
|
||||
|
||||
|
||||
def lema(close: object, length: int = 10, offset: int = 0, **kwargs) -> object:
|
||||
"""Laguerre-based EMA."""
|
||||
length = int(length); offset = int(offset)
|
||||
src, idx = _arr(close); n = len(src); dst = _out(n)
|
||||
_check(_lib.qtl_lema(_ptr(src), n, _ptr(dst), length))
|
||||
return _wrap(dst, idx, f"LEMA_{length}", "trends_iir", offset)
|
||||
|
||||
|
||||
def hema(close: object, length: int = 10, offset: int = 0, **kwargs) -> object:
|
||||
"""Henderson EMA."""
|
||||
length = int(length); offset = int(offset)
|
||||
src, idx = _arr(close); n = len(src); dst = _out(n)
|
||||
_check(_lib.qtl_hema(_ptr(src), n, _ptr(dst), length))
|
||||
return _wrap(dst, idx, f"HEMA_{length}", "trends_iir", offset)
|
||||
|
||||
|
||||
def ahrens(close: object, length: int = 10, offset: int = 0, **kwargs) -> object:
|
||||
"""Ahrens Moving Average."""
|
||||
length = int(length); offset = int(offset)
|
||||
src, idx = _arr(close); n = len(src); dst = _out(n)
|
||||
_check(_lib.qtl_ahrens(_ptr(src), n, _ptr(dst), length))
|
||||
return _wrap(dst, idx, f"AHRENS_{length}", "trends_iir", offset)
|
||||
|
||||
|
||||
def decycler(close: object, length: int = 20, offset: int = 0, **kwargs) -> object:
|
||||
"""Simple Decycler."""
|
||||
length = int(length); offset = int(offset)
|
||||
src, idx = _arr(close); n = len(src); dst = _out(n)
|
||||
_check(_lib.qtl_decycler(_ptr(src), n, _ptr(dst), length))
|
||||
return _wrap(dst, idx, f"DECYCLER_{length}", "trends_iir", offset)
|
||||
|
||||
|
||||
def dsma(close: object, length: int = 10, factor: float = 0.5,
|
||||
offset: int = 0, **kwargs) -> object:
|
||||
"""Deviation-Scaled Moving Average."""
|
||||
length = int(length); offset = int(offset)
|
||||
src, idx = _arr(close); n = len(src); dst = _out(n)
|
||||
_check(_lib.qtl_dsma(_ptr(src), n, _ptr(dst), length, float(factor)))
|
||||
return _wrap(dst, idx, f"DSMA_{length}", "trends_iir", offset)
|
||||
|
||||
|
||||
def gdema(close: object, length: int = 10, vfactor: float = 1.0,
|
||||
offset: int = 0, **kwargs) -> object:
|
||||
"""Generalized DEMA."""
|
||||
length = int(length); offset = int(offset)
|
||||
src, idx = _arr(close); n = len(src); dst = _out(n)
|
||||
_check(_lib.qtl_gdema(_ptr(src), n, _ptr(dst), length, float(vfactor)))
|
||||
return _wrap(dst, idx, f"GDEMA_{length}", "trends_iir", offset)
|
||||
|
||||
|
||||
def coral(close: object, length: int = 10, friction: float = 0.4,
|
||||
offset: int = 0, **kwargs) -> object:
|
||||
"""CORAL Trend."""
|
||||
length = int(length); offset = int(offset)
|
||||
src, idx = _arr(close); n = len(src); dst = _out(n)
|
||||
_check(_lib.qtl_coral(_ptr(src), n, _ptr(dst), length, float(friction)))
|
||||
return _wrap(dst, idx, f"CORAL_{length}", "trends_iir", offset)
|
||||
|
||||
|
||||
def agc(close: object, alpha: float = 0.1, offset: int = 0, **kwargs) -> object:
|
||||
"""Automatic Gain Control."""
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close); n = len(src); dst = _out(n)
|
||||
_check(_lib.qtl_agc(_ptr(src), n, _ptr(dst), float(alpha)))
|
||||
return _wrap(dst, idx, f"AGC_a{alpha:.4f}", "trends_iir", offset)
|
||||
|
||||
|
||||
def ccyc(close: object, alpha: float = 0.1, offset: int = 0, **kwargs) -> object:
|
||||
"""Cyber Cycle."""
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close); n = len(src); dst = _out(n)
|
||||
_check(_lib.qtl_ccyc(_ptr(src), n, _ptr(dst), float(alpha)))
|
||||
return _wrap(dst, idx, f"CCYC_a{alpha:.4f}", "trends_iir", offset)
|
||||
@@ -0,0 +1,341 @@
|
||||
"""quantalib volatility indicators.
|
||||
|
||||
Auto-generated — DO NOT EDIT.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
from ._helpers import _arr, _ptr, _out, _wrap, _wrap_multi, _check, _lib
|
||||
|
||||
|
||||
__all__ = [
|
||||
"adr",
|
||||
"atr",
|
||||
"atrn",
|
||||
"gkv",
|
||||
"hlv",
|
||||
"hv",
|
||||
"jvolty",
|
||||
"jvoltyn",
|
||||
"massi",
|
||||
"natr",
|
||||
"rsv",
|
||||
"rv",
|
||||
"rvi",
|
||||
"ui",
|
||||
"vov",
|
||||
"vr",
|
||||
"yzv",
|
||||
"tr",
|
||||
"bbw",
|
||||
"bbwn",
|
||||
"bbwp",
|
||||
"stddev",
|
||||
"variance",
|
||||
"etherm",
|
||||
"ccv",
|
||||
"cv",
|
||||
"cvi",
|
||||
"ewma",
|
||||
]
|
||||
|
||||
|
||||
def adr(open: object, high: object, low: object, close: object, volume: object, period: int = 14, method: int = 0, offset: int = 0, **kwargs) -> object:
|
||||
"""Average Daily Range."""
|
||||
period = int(period)
|
||||
method = int(method)
|
||||
offset = int(offset)
|
||||
o, idx = _arr(open); h, _ = _arr(high); l, _ = _arr(low)
|
||||
c, _ = _arr(close); v, _ = _arr(volume)
|
||||
n = len(o)
|
||||
dst = _out(n)
|
||||
_check(_lib.qtl_adr(_ptr(o), _ptr(h), _ptr(l), _ptr(c), _ptr(v), period, method, n, _ptr(dst)))
|
||||
return _wrap(dst, idx, f"ADR_{period}", "volatility", offset)
|
||||
|
||||
|
||||
def atr(open: object, high: object, low: object, close: object, volume: object, period: int = 14, offset: int = 0, **kwargs) -> object:
|
||||
"""Average True Range."""
|
||||
period = int(period)
|
||||
offset = int(offset)
|
||||
o, idx = _arr(open); h, _ = _arr(high); l, _ = _arr(low)
|
||||
c, _ = _arr(close); v, _ = _arr(volume)
|
||||
n = len(o)
|
||||
dst = _out(n)
|
||||
_check(_lib.qtl_atr(_ptr(o), _ptr(h), _ptr(l), _ptr(c), _ptr(v), period, n, _ptr(dst)))
|
||||
return _wrap(dst, idx, f"ATR_{period}", "volatility", offset)
|
||||
|
||||
|
||||
def atrn(open: object, high: object, low: object, close: object, volume: object, period: int = 14, offset: int = 0, **kwargs) -> object:
|
||||
"""Normalized ATR."""
|
||||
period = int(period)
|
||||
offset = int(offset)
|
||||
o, idx = _arr(open); h, _ = _arr(high); l, _ = _arr(low)
|
||||
c, _ = _arr(close); v, _ = _arr(volume)
|
||||
n = len(o)
|
||||
dst = _out(n)
|
||||
_check(_lib.qtl_atrn(_ptr(o), _ptr(h), _ptr(l), _ptr(c), _ptr(v), period, n, _ptr(dst)))
|
||||
return _wrap(dst, idx, f"ATRN_{period}", "volatility", offset)
|
||||
|
||||
|
||||
def gkv(open: object, high: object, low: object, close: object, period: int = 14, annualize: int = 1, annualPeriods: int = 252, offset: int = 0, **kwargs) -> object:
|
||||
"""Garman-Klass Volatility."""
|
||||
period = int(period)
|
||||
annualize = int(annualize)
|
||||
annualPeriods = int(annualPeriods)
|
||||
offset = int(offset)
|
||||
o, idx = _arr(open); h, _ = _arr(high); l, _ = _arr(low); c, _ = _arr(close)
|
||||
n = len(o)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_gkv(_ptr(o), _ptr(h), _ptr(l), _ptr(c), _ptr(output), n, period, annualize, annualPeriods))
|
||||
return _wrap(output, idx, f"GKV_{period}", "volatility", offset)
|
||||
|
||||
|
||||
def hlv(high: object, low: object, period: int = 14, annualize: int = 1, annualPeriods: int = 252, offset: int = 0, **kwargs) -> object:
|
||||
"""High-Low Volatility."""
|
||||
period = int(period)
|
||||
annualize = int(annualize)
|
||||
annualPeriods = int(annualPeriods)
|
||||
offset = int(offset)
|
||||
h, idx = _arr(high); l, _ = _arr(low)
|
||||
n = len(h)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_hlv(_ptr(h), _ptr(l), _ptr(output), n, period, annualize, annualPeriods))
|
||||
return _wrap(output, idx, f"HLV_{period}", "volatility", offset)
|
||||
|
||||
|
||||
def hv(close: object, period: int = 14, annualize: int = 1, annualPeriods: int = 252, offset: int = 0, **kwargs) -> object:
|
||||
"""Historical Volatility."""
|
||||
period = int(period)
|
||||
annualize = int(annualize)
|
||||
annualPeriods = int(annualPeriods)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_hv(_ptr(src), _ptr(output), n, period, annualize, annualPeriods))
|
||||
return _wrap(output, idx, f"HV_{period}", "volatility", offset)
|
||||
|
||||
|
||||
def jvolty(close: object, period: int = 14, offset: int = 0, **kwargs) -> object:
|
||||
"""Jurik Volatility."""
|
||||
period = int(period)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_jvolty(_ptr(src), _ptr(output), n, period))
|
||||
return _wrap(output, idx, f"JVOLTY_{period}", "volatility", offset)
|
||||
|
||||
|
||||
def jvoltyn(close: object, period: int = 14, offset: int = 0, **kwargs) -> object:
|
||||
"""Jurik Volatility Normalized."""
|
||||
period = int(period)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_jvoltyn(_ptr(src), _ptr(output), n, period))
|
||||
return _wrap(output, idx, f"JVOLTYN_{period}", "volatility", offset)
|
||||
|
||||
|
||||
def massi(close: object, emaLength: int = 9, sumLength: int = 25, offset: int = 0, **kwargs) -> object:
|
||||
"""Mass Index."""
|
||||
emaLength = int(emaLength)
|
||||
sumLength = int(sumLength)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_massi(_ptr(src), _ptr(output), n, emaLength, sumLength))
|
||||
return _wrap(output, idx, f"MASSI_{emaLength}", "volatility", offset)
|
||||
|
||||
|
||||
def natr(open: object, high: object, low: object, close: object, volume: object, period: int = 14, offset: int = 0, **kwargs) -> object:
|
||||
"""Normalized ATR."""
|
||||
period = int(period)
|
||||
offset = int(offset)
|
||||
o, idx = _arr(open); h, _ = _arr(high); l, _ = _arr(low)
|
||||
c, _ = _arr(close); v, _ = _arr(volume)
|
||||
n = len(o)
|
||||
dst = _out(n)
|
||||
_check(_lib.qtl_natr(_ptr(o), _ptr(h), _ptr(l), _ptr(c), _ptr(v), period, n, _ptr(dst)))
|
||||
return _wrap(dst, idx, f"NATR_{period}", "volatility", offset)
|
||||
|
||||
|
||||
def rsv(open: object, high: object, low: object, close: object, period: int = 14, annualize: int = 1, annualPeriods: int = 252, offset: int = 0, **kwargs) -> object:
|
||||
"""Rogers-Satchell Volatility."""
|
||||
period = int(period)
|
||||
annualize = int(annualize)
|
||||
annualPeriods = int(annualPeriods)
|
||||
offset = int(offset)
|
||||
o, idx = _arr(open); h, _ = _arr(high); l, _ = _arr(low); c, _ = _arr(close)
|
||||
n = len(o)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_rsv(_ptr(o), _ptr(h), _ptr(l), _ptr(c), _ptr(output), n, period, annualize, annualPeriods))
|
||||
return _wrap(output, idx, f"RSV_{period}", "volatility", offset)
|
||||
|
||||
|
||||
def rv(close: object, period: int = 14, smoothingPeriod: int = 14, annualize: int = 1, annualPeriods: int = 252, offset: int = 0, **kwargs) -> object:
|
||||
"""Realized Volatility."""
|
||||
period = int(period)
|
||||
smoothingPeriod = int(smoothingPeriod)
|
||||
annualize = int(annualize)
|
||||
annualPeriods = int(annualPeriods)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_rv(_ptr(src), _ptr(output), n, period, smoothingPeriod, annualize, annualPeriods))
|
||||
return _wrap(output, idx, f"RV_{period}", "volatility", offset)
|
||||
|
||||
|
||||
def rvi(close: object, stdevLength: int = 10, rmaLength: int = 14, offset: int = 0, **kwargs) -> object:
|
||||
"""Relative Volatility Index."""
|
||||
stdevLength = int(stdevLength)
|
||||
rmaLength = int(rmaLength)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_rvi(_ptr(src), _ptr(output), n, stdevLength, rmaLength))
|
||||
return _wrap(output, idx, f"RVI_{stdevLength}", "volatility", offset)
|
||||
|
||||
|
||||
def ui(close: object, period: int = 14, offset: int = 0, **kwargs) -> object:
|
||||
"""Ulcer Index."""
|
||||
period = int(period)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_ui(_ptr(src), _ptr(output), n, period))
|
||||
return _wrap(output, idx, f"UI_{period}", "volatility", offset)
|
||||
|
||||
|
||||
def vov(close: object, volatilityPeriod: int = 20, vovPeriod: int = 20, offset: int = 0, **kwargs) -> object:
|
||||
"""Volatility of Volatility."""
|
||||
volatilityPeriod = int(volatilityPeriod)
|
||||
vovPeriod = int(vovPeriod)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_vov(_ptr(src), _ptr(output), n, volatilityPeriod, vovPeriod))
|
||||
return _wrap(output, idx, f"VOV_{volatilityPeriod}", "volatility", offset)
|
||||
|
||||
|
||||
def vr(high: object, low: object, close: object, period: int = 14, offset: int = 0, **kwargs) -> object:
|
||||
"""Volatility Ratio."""
|
||||
period = int(period)
|
||||
offset = int(offset)
|
||||
h, idx = _arr(high); l, _ = _arr(low); c, _ = _arr(close)
|
||||
n = len(h)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_vr(_ptr(h), _ptr(l), _ptr(c), _ptr(output), n, period))
|
||||
return _wrap(output, idx, f"VR_{period}", "volatility", offset)
|
||||
|
||||
|
||||
def yzv(open: object, high: object, low: object, close: object, period: int = 14, offset: int = 0, **kwargs) -> object:
|
||||
"""Yang-Zhang Volatility."""
|
||||
period = int(period)
|
||||
offset = int(offset)
|
||||
o, idx = _arr(open); h, _ = _arr(high); l, _ = _arr(low); c, _ = _arr(close)
|
||||
n = len(o)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_yzv(_ptr(o), _ptr(h), _ptr(l), _ptr(c), _ptr(output), n, period))
|
||||
return _wrap(output, idx, f"YZV_{period}", "volatility", offset)
|
||||
|
||||
def tr(high: object, low: object, close: object, offset: int = 0, **kwargs) -> object:
|
||||
"""True Range."""
|
||||
h, idx = _arr(high); l, _ = _arr(low); c, _ = _arr(close)
|
||||
n = len(h); dst = _out(n)
|
||||
_check(_lib.qtl_tr(_ptr(h), _ptr(l), _ptr(c), n, _ptr(dst)))
|
||||
return _wrap(dst, idx, "TR", "volatility", int(offset))
|
||||
|
||||
|
||||
def bbw(close: object, length: int = 20, mult: float = 2.0,
|
||||
offset: int = 0, **kwargs) -> object:
|
||||
"""Bollinger Band Width."""
|
||||
length = int(length); mult = float(mult); offset = int(offset)
|
||||
src, idx = _arr(close); n = len(src); dst = _out(n)
|
||||
_check(_lib.qtl_bbw(_ptr(src), n, _ptr(dst), length, mult))
|
||||
return _wrap(dst, idx, f"BBW_{length}", "volatility", offset)
|
||||
|
||||
|
||||
def bbwn(close: object, length: int = 20, mult: float = 2.0,
|
||||
lookback: int = 252, offset: int = 0, **kwargs) -> object:
|
||||
"""Bollinger Band Width Normalized."""
|
||||
length = int(length); mult = float(mult); lookback = int(lookback); offset = int(offset)
|
||||
src, idx = _arr(close); n = len(src); dst = _out(n)
|
||||
_check(_lib.qtl_bbwn(_ptr(src), n, _ptr(dst), length, mult, lookback))
|
||||
return _wrap(dst, idx, f"BBWN_{length}", "volatility", offset)
|
||||
|
||||
|
||||
def bbwp(close: object, length: int = 20, mult: float = 2.0,
|
||||
lookback: int = 252, offset: int = 0, **kwargs) -> object:
|
||||
"""Bollinger Band Width Percentile."""
|
||||
length = int(length); mult = float(mult); lookback = int(lookback); offset = int(offset)
|
||||
src, idx = _arr(close); n = len(src); dst = _out(n)
|
||||
_check(_lib.qtl_bbwp(_ptr(src), n, _ptr(dst), length, mult, lookback))
|
||||
return _wrap(dst, idx, f"BBWP_{length}", "volatility", offset)
|
||||
|
||||
|
||||
def stddev(close: object, length: int = 20, offset: int = 0, **kwargs) -> object:
|
||||
"""Standard Deviation."""
|
||||
length = int(length); offset = int(offset)
|
||||
src, idx = _arr(close); n = len(src); dst = _out(n)
|
||||
_check(_lib.qtl_stddev(_ptr(src), n, _ptr(dst), length))
|
||||
return _wrap(dst, idx, f"STDDEV_{length}", "volatility", offset)
|
||||
|
||||
|
||||
def variance(close: object, length: int = 20, offset: int = 0, **kwargs) -> object:
|
||||
"""Variance."""
|
||||
length = int(length); offset = int(offset)
|
||||
src, idx = _arr(close); n = len(src); dst = _out(n)
|
||||
_check(_lib.qtl_variance(_ptr(src), n, _ptr(dst), length))
|
||||
return _wrap(dst, idx, f"VAR_{length}", "volatility", offset)
|
||||
|
||||
|
||||
def etherm(high: object, low: object, length: int = 14,
|
||||
offset: int = 0, **kwargs) -> object:
|
||||
"""Elder Thermometer."""
|
||||
length = int(length)
|
||||
h, idx = _arr(high); l, _ = _arr(low)
|
||||
n = len(h); dst = _out(n)
|
||||
_check(_lib.qtl_etherm(_ptr(h), _ptr(l), n, _ptr(dst), length))
|
||||
return _wrap(dst, idx, f"ETHERM_{length}", "volatility", int(offset))
|
||||
|
||||
|
||||
def ccv(close: object, short_period: int = 20, long_period: int = 1,
|
||||
offset: int = 0, **kwargs) -> object:
|
||||
"""Close-to-Close Volatility."""
|
||||
short_period = int(short_period); long_period = int(long_period); offset = int(offset)
|
||||
src, idx = _arr(close); n = len(src); dst = _out(n)
|
||||
_check(_lib.qtl_ccv(_ptr(src), n, _ptr(dst), short_period, long_period))
|
||||
return _wrap(dst, idx, f"CCV_{short_period}", "volatility", offset)
|
||||
|
||||
|
||||
def cv(close: object, length: int = 20, min_vol: float = 0.2,
|
||||
max_vol: float = 0.7, offset: int = 0, **kwargs) -> object:
|
||||
"""Coefficient of Variation."""
|
||||
length = int(length); offset = int(offset)
|
||||
src, idx = _arr(close); n = len(src); dst = _out(n)
|
||||
_check(_lib.qtl_cv(_ptr(src), n, _ptr(dst), length, float(min_vol), float(max_vol)))
|
||||
return _wrap(dst, idx, f"CV_{length}", "volatility", offset)
|
||||
|
||||
|
||||
def cvi(close: object, ema_period: int = 10, roc_period: int = 10,
|
||||
offset: int = 0, **kwargs) -> object:
|
||||
"""Chaikin Volatility Index."""
|
||||
ema_period = int(ema_period); roc_period = int(roc_period); offset = int(offset)
|
||||
src, idx = _arr(close); n = len(src); dst = _out(n)
|
||||
_check(_lib.qtl_cvi(_ptr(src), n, _ptr(dst), ema_period, roc_period))
|
||||
return _wrap(dst, idx, f"CVI_{ema_period}", "volatility", offset)
|
||||
|
||||
|
||||
def ewma(close: object, length: int = 20, is_pop: int = 1,
|
||||
ann_factor: int = 252, offset: int = 0, **kwargs) -> object:
|
||||
"""Exponentially Weighted Moving Average (volatility)."""
|
||||
length = int(length); offset = int(offset)
|
||||
src, idx = _arr(close); n = len(src); dst = _out(n)
|
||||
_check(_lib.qtl_ewma(_ptr(src), n, _ptr(dst), length, int(is_pop), int(ann_factor)))
|
||||
return _wrap(dst, idx, f"EWMA_{length}", "volatility", offset)
|
||||
@@ -0,0 +1,317 @@
|
||||
"""quantalib volume indicators.
|
||||
|
||||
Auto-generated — DO NOT EDIT.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
from ._helpers import _arr, _ptr, _out, _wrap, _wrap_multi, _check, _lib
|
||||
|
||||
|
||||
__all__ = [
|
||||
"adl",
|
||||
"adosc",
|
||||
"iii",
|
||||
"kvo",
|
||||
"twap",
|
||||
"va",
|
||||
"vo",
|
||||
"vroc",
|
||||
"vwad",
|
||||
"vwap",
|
||||
"wad",
|
||||
"obv",
|
||||
"pvt",
|
||||
"pvr",
|
||||
"vf",
|
||||
"nvi",
|
||||
"pvi",
|
||||
"tvi",
|
||||
"pvd",
|
||||
"vwma",
|
||||
"evwma",
|
||||
"efi",
|
||||
"aobv",
|
||||
"mfi",
|
||||
"cmf",
|
||||
"eom",
|
||||
"pvo",
|
||||
]
|
||||
|
||||
|
||||
def adl(high: object, low: object, close: object, volume: object, offset: int = 0, **kwargs) -> object:
|
||||
"""Accumulation/Distribution Line."""
|
||||
offset = int(offset)
|
||||
h, idx = _arr(high); l, _ = _arr(low); c, _ = _arr(close); v, _ = _arr(volume)
|
||||
n = len(h)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_adl(_ptr(h), _ptr(l), _ptr(c), _ptr(v), _ptr(output), n))
|
||||
return _wrap(output, idx, "ADL", "volume", offset)
|
||||
|
||||
|
||||
def adosc(high: object, low: object, close: object, volume: object, fastPeriod: int = 12, slowPeriod: int = 26, offset: int = 0, **kwargs) -> object:
|
||||
"""Accumulation/Distribution Oscillator."""
|
||||
fastPeriod = int(fastPeriod)
|
||||
slowPeriod = int(slowPeriod)
|
||||
offset = int(offset)
|
||||
h, idx = _arr(high); l, _ = _arr(low); c, _ = _arr(close); v, _ = _arr(volume)
|
||||
n = len(h)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_adosc(_ptr(h), _ptr(l), _ptr(c), _ptr(v), _ptr(output), n, fastPeriod, slowPeriod))
|
||||
return _wrap(output, idx, f"ADOSC_{fastPeriod}", "volume", offset)
|
||||
|
||||
|
||||
def iii(high: object, low: object, close: object, volume: object, period: int = 14, cumulative: int = 0, offset: int = 0, **kwargs) -> object:
|
||||
"""Intraday Intensity Index."""
|
||||
period = int(period)
|
||||
cumulative = int(cumulative)
|
||||
offset = int(offset)
|
||||
h, idx = _arr(high); l, _ = _arr(low); c, _ = _arr(close); v, _ = _arr(volume)
|
||||
n = len(h)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_iii(_ptr(h), _ptr(l), _ptr(c), _ptr(v), _ptr(output), n, period, cumulative))
|
||||
return _wrap(output, idx, f"III_{period}", "volume", offset)
|
||||
|
||||
|
||||
def kvo(high: object, low: object, close: object, volume: object, fastPeriod: int = 12, slowPeriod: int = 26, signalPeriod: int = 9, offset: int = 0, **kwargs) -> object:
|
||||
"""Klinger Volume Oscillator."""
|
||||
fastPeriod = int(fastPeriod)
|
||||
slowPeriod = int(slowPeriod)
|
||||
signalPeriod = int(signalPeriod)
|
||||
offset = int(offset)
|
||||
h, idx = _arr(high); l, _ = _arr(low); c, _ = _arr(close); v, _ = _arr(volume)
|
||||
n = len(h)
|
||||
output = _out(n)
|
||||
signal = _out(n)
|
||||
_check(_lib.qtl_kvo(_ptr(h), _ptr(l), _ptr(c), _ptr(v), _ptr(output), _ptr(signal), n, fastPeriod, slowPeriod, signalPeriod))
|
||||
return _wrap_multi({"output": output, "signal": signal}, idx, "volume", offset)
|
||||
|
||||
|
||||
def twap(close: object, period: int = 14, offset: int = 0, **kwargs) -> object:
|
||||
"""Time Weighted Average Price."""
|
||||
period = int(period)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_twap(_ptr(src), _ptr(output), n, period))
|
||||
return _wrap(output, idx, f"TWAP_{period}", "volume", offset)
|
||||
|
||||
|
||||
def va(high: object, low: object, close: object, volume: object, offset: int = 0, **kwargs) -> object:
|
||||
"""Volume Accumulation."""
|
||||
offset = int(offset)
|
||||
h, idx = _arr(high); l, _ = _arr(low); c, _ = _arr(close); v, _ = _arr(volume)
|
||||
n = len(h)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_va(_ptr(h), _ptr(l), _ptr(c), _ptr(v), _ptr(output), n))
|
||||
return _wrap(output, idx, "VA", "volume", offset)
|
||||
|
||||
|
||||
def vo(volume: object, shortPeriod: int = 12, longPeriod: int = 26, offset: int = 0, **kwargs) -> object:
|
||||
"""Volume Oscillator."""
|
||||
shortPeriod = int(shortPeriod)
|
||||
longPeriod = int(longPeriod)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(volume)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_vo(_ptr(src), _ptr(output), n, shortPeriod, longPeriod))
|
||||
return _wrap(output, idx, f"VO_{shortPeriod}", "volume", offset)
|
||||
|
||||
|
||||
def vroc(volume: object, period: int = 14, usePercent: int = 1, offset: int = 0, **kwargs) -> object:
|
||||
"""Volume Rate of Change."""
|
||||
period = int(period)
|
||||
usePercent = int(usePercent)
|
||||
offset = int(offset)
|
||||
src, idx = _arr(volume)
|
||||
n = len(src)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_vroc(_ptr(src), _ptr(output), n, period, usePercent))
|
||||
return _wrap(output, idx, f"VROC_{period}", "volume", offset)
|
||||
|
||||
|
||||
def vwad(high: object, low: object, close: object, volume: object, period: int = 14, offset: int = 0, **kwargs) -> object:
|
||||
"""Volume Weighted Accumulation/Distribution."""
|
||||
period = int(period)
|
||||
offset = int(offset)
|
||||
h, idx = _arr(high); l, _ = _arr(low); c, _ = _arr(close); v, _ = _arr(volume)
|
||||
n = len(h)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_vwad(_ptr(h), _ptr(l), _ptr(c), _ptr(v), _ptr(output), n, period))
|
||||
return _wrap(output, idx, f"VWAD_{period}", "volume", offset)
|
||||
|
||||
|
||||
def vwap(high: object, low: object, close: object, volume: object, period: int = 14, offset: int = 0, **kwargs) -> object:
|
||||
"""Volume Weighted Average Price."""
|
||||
period = int(period)
|
||||
offset = int(offset)
|
||||
h, idx = _arr(high); l, _ = _arr(low); c, _ = _arr(close); v, _ = _arr(volume)
|
||||
n = len(h)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_vwap(_ptr(h), _ptr(l), _ptr(c), _ptr(v), _ptr(output), n, period))
|
||||
return _wrap(output, idx, f"VWAP_{period}", "volume", offset)
|
||||
|
||||
|
||||
def wad(high: object, low: object, close: object, volume: object, offset: int = 0, **kwargs) -> object:
|
||||
"""Williams Accumulation/Distribution."""
|
||||
offset = int(offset)
|
||||
h, idx = _arr(high); l, _ = _arr(low); c, _ = _arr(close); v, _ = _arr(volume)
|
||||
n = len(h)
|
||||
output = _out(n)
|
||||
_check(_lib.qtl_wad(_ptr(h), _ptr(l), _ptr(c), _ptr(v), _ptr(output), n))
|
||||
return _wrap(output, idx, "WAD", "volume", offset)
|
||||
|
||||
def obv(close: object, volume: object, offset: int = 0, **kwargs) -> object:
|
||||
"""On-Balance Volume."""
|
||||
offset = int(offset)
|
||||
c, idx = _arr(close); v, _ = _arr(volume)
|
||||
n = len(c); dst = _out(n)
|
||||
_check(_lib.qtl_obv(_ptr(c), _ptr(v), n, _ptr(dst)))
|
||||
return _wrap(dst, idx, "OBV", "volume", offset)
|
||||
|
||||
|
||||
def pvt(close: object, volume: object, offset: int = 0, **kwargs) -> object:
|
||||
"""Price Volume Trend."""
|
||||
offset = int(offset)
|
||||
c, idx = _arr(close); v, _ = _arr(volume)
|
||||
n = len(c); dst = _out(n)
|
||||
_check(_lib.qtl_pvt(_ptr(c), _ptr(v), n, _ptr(dst)))
|
||||
return _wrap(dst, idx, "PVT", "volume", offset)
|
||||
|
||||
|
||||
def pvr(close: object, volume: object, offset: int = 0, **kwargs) -> object:
|
||||
"""Price Volume Rank."""
|
||||
offset = int(offset)
|
||||
c, idx = _arr(close); v, _ = _arr(volume)
|
||||
n = len(c); dst = _out(n)
|
||||
_check(_lib.qtl_pvr(_ptr(c), _ptr(v), n, _ptr(dst)))
|
||||
return _wrap(dst, idx, "PVR", "volume", offset)
|
||||
|
||||
|
||||
def vf(close: object, volume: object, offset: int = 0, **kwargs) -> object:
|
||||
"""Volume Flow."""
|
||||
offset = int(offset)
|
||||
c, idx = _arr(close); v, _ = _arr(volume)
|
||||
n = len(c); dst = _out(n)
|
||||
_check(_lib.qtl_vf(_ptr(c), _ptr(v), n, _ptr(dst)))
|
||||
return _wrap(dst, idx, "VF", "volume", offset)
|
||||
|
||||
|
||||
def nvi(close: object, volume: object, offset: int = 0, **kwargs) -> object:
|
||||
"""Negative Volume Index."""
|
||||
offset = int(offset)
|
||||
c, idx = _arr(close); v, _ = _arr(volume)
|
||||
n = len(c); dst = _out(n)
|
||||
_check(_lib.qtl_nvi(_ptr(c), _ptr(v), n, _ptr(dst)))
|
||||
return _wrap(dst, idx, "NVI", "volume", offset)
|
||||
|
||||
|
||||
def pvi(close: object, volume: object, offset: int = 0, **kwargs) -> object:
|
||||
"""Positive Volume Index."""
|
||||
offset = int(offset)
|
||||
c, idx = _arr(close); v, _ = _arr(volume)
|
||||
n = len(c); dst = _out(n)
|
||||
_check(_lib.qtl_pvi(_ptr(c), _ptr(v), n, _ptr(dst)))
|
||||
return _wrap(dst, idx, "PVI", "volume", offset)
|
||||
|
||||
|
||||
def tvi(close: object, volume: object, length: int = 14,
|
||||
offset: int = 0, **kwargs) -> object:
|
||||
"""Trade Volume Index."""
|
||||
length = int(length); offset = int(offset)
|
||||
c, idx = _arr(close); v, _ = _arr(volume)
|
||||
n = len(c); dst = _out(n)
|
||||
_check(_lib.qtl_tvi(_ptr(c), _ptr(v), n, _ptr(dst), length))
|
||||
return _wrap(dst, idx, f"TVI_{length}", "volume", offset)
|
||||
|
||||
|
||||
def pvd(close: object, volume: object, length: int = 14,
|
||||
offset: int = 0, **kwargs) -> object:
|
||||
"""Price Volume Divergence."""
|
||||
length = int(length); offset = int(offset)
|
||||
c, idx = _arr(close); v, _ = _arr(volume)
|
||||
n = len(c); dst = _out(n)
|
||||
_check(_lib.qtl_pvd(_ptr(c), _ptr(v), n, _ptr(dst), length))
|
||||
return _wrap(dst, idx, f"PVD_{length}", "volume", offset)
|
||||
|
||||
|
||||
def vwma(close: object, volume: object, length: int = 20,
|
||||
offset: int = 0, **kwargs) -> object:
|
||||
"""Volume Weighted Moving Average."""
|
||||
length = int(length); offset = int(offset)
|
||||
c, idx = _arr(close); v, _ = _arr(volume)
|
||||
n = len(c); dst = _out(n)
|
||||
_check(_lib.qtl_vwma(_ptr(c), _ptr(v), n, _ptr(dst), length))
|
||||
return _wrap(dst, idx, f"VWMA_{length}", "volume", offset)
|
||||
|
||||
|
||||
def evwma(close: object, volume: object, length: int = 20,
|
||||
offset: int = 0, **kwargs) -> object:
|
||||
"""Elastic Volume Weighted Moving Average."""
|
||||
length = int(length); offset = int(offset)
|
||||
c, idx = _arr(close); v, _ = _arr(volume)
|
||||
n = len(c); dst = _out(n)
|
||||
_check(_lib.qtl_evwma(_ptr(c), _ptr(v), n, _ptr(dst), length))
|
||||
return _wrap(dst, idx, f"EVWMA_{length}", "volume", offset)
|
||||
|
||||
|
||||
def efi(close: object, volume: object, length: int = 13,
|
||||
offset: int = 0, **kwargs) -> object:
|
||||
"""Elder Force Index."""
|
||||
length = int(length); offset = int(offset)
|
||||
c, idx = _arr(close); v, _ = _arr(volume)
|
||||
n = len(c); dst = _out(n)
|
||||
_check(_lib.qtl_efi(_ptr(c), _ptr(v), n, _ptr(dst), length))
|
||||
return _wrap(dst, idx, f"EFI_{length}", "volume", offset)
|
||||
|
||||
|
||||
def aobv(close: object, volume: object, offset: int = 0, **kwargs) -> object:
|
||||
"""Archer OBV -> (fast, slow) or DataFrame."""
|
||||
offset = int(offset)
|
||||
c, idx = _arr(close); v, _ = _arr(volume)
|
||||
n = len(c); obv_out = _out(n); sig = _out(n)
|
||||
_check(_lib.qtl_aobv(_ptr(c), _ptr(v), n, _ptr(obv_out), _ptr(sig)))
|
||||
return _wrap_multi({"AOBV": obv_out, "AOBV_SIG": sig}, idx, "volume", offset)
|
||||
|
||||
|
||||
def mfi(high: object, low: object, close: object, volume: object,
|
||||
length: int = 14, offset: int = 0, **kwargs) -> object:
|
||||
"""Money Flow Index."""
|
||||
length = int(length); offset = int(offset)
|
||||
h, idx = _arr(high); l, _ = _arr(low); c, _ = _arr(close); v, _ = _arr(volume)
|
||||
n = len(h); dst = _out(n)
|
||||
_check(_lib.qtl_mfi(_ptr(h), _ptr(l), _ptr(c), _ptr(v), n, _ptr(dst), length))
|
||||
return _wrap(dst, idx, f"MFI_{length}", "volume", offset)
|
||||
|
||||
|
||||
def cmf(high: object, low: object, close: object, volume: object,
|
||||
length: int = 20, offset: int = 0, **kwargs) -> object:
|
||||
"""Chaikin Money Flow."""
|
||||
length = int(length); offset = int(offset)
|
||||
h, idx = _arr(high); l, _ = _arr(low); c, _ = _arr(close); v, _ = _arr(volume)
|
||||
n = len(h); dst = _out(n)
|
||||
_check(_lib.qtl_cmf(_ptr(h), _ptr(l), _ptr(c), _ptr(v), n, _ptr(dst), length))
|
||||
return _wrap(dst, idx, f"CMF_{length}", "volume", offset)
|
||||
|
||||
|
||||
def eom(high: object, low: object, volume: object,
|
||||
length: int = 14, offset: int = 0, **kwargs) -> object:
|
||||
"""Ease of Movement."""
|
||||
length = int(length); offset = int(offset)
|
||||
h, idx = _arr(high); l, _ = _arr(low); v, _ = _arr(volume)
|
||||
n = len(h); dst = _out(n)
|
||||
_check(_lib.qtl_eom(_ptr(h), _ptr(l), _ptr(v), n, _ptr(dst), length, 1e9))
|
||||
return _wrap(dst, idx, f"EOM_{length}", "volume", offset)
|
||||
|
||||
|
||||
def pvo(volume: object, fast: int = 12, slow: int = 26, signal: int = 9,
|
||||
offset: int = 0, **kwargs) -> object:
|
||||
"""Percentage Volume Oscillator -> (pvo, signal, histogram) or DataFrame."""
|
||||
fast = int(fast); slow = int(slow); signal = int(signal); offset = int(offset)
|
||||
v, idx = _arr(volume); n = len(v)
|
||||
pvo_out = _out(n); sig = _out(n); hist = _out(n)
|
||||
_check(_lib.qtl_pvo(_ptr(v), n, _ptr(pvo_out), _ptr(sig), _ptr(hist), fast, slow, signal))
|
||||
return _wrap_multi(
|
||||
{f"PVO_{fast}_{slow}_{signal}": pvo_out, f"PVOs_{fast}_{slow}_{signal}": sig, f"PVOh_{fast}_{slow}_{signal}": hist},
|
||||
idx, "volume", offset)
|
||||
@@ -0,0 +1,44 @@
|
||||
"""test_category_labels.py — Verify consistent category labels across all modules."""
|
||||
from __future__ import annotations
|
||||
|
||||
import importlib
|
||||
import inspect
|
||||
import re
|
||||
import pytest
|
||||
|
||||
CATEGORY_MODULES = {
|
||||
"quantalib.channels": "channels",
|
||||
"quantalib.core": "core",
|
||||
"quantalib.cycles": "cycles",
|
||||
"quantalib.dynamics": "dynamics",
|
||||
"quantalib.errors": "errors",
|
||||
"quantalib.filters": "filters",
|
||||
"quantalib.momentum": "momentum",
|
||||
"quantalib.numerics": "numerics",
|
||||
"quantalib.oscillators": "oscillators",
|
||||
"quantalib.reversals": "reversals",
|
||||
"quantalib.statistics": "statistics",
|
||||
"quantalib.trends_fir": "trends_fir",
|
||||
"quantalib.trends_iir": "trends_iir",
|
||||
"quantalib.volatility": "volatility",
|
||||
"quantalib.volume": "volume",
|
||||
}
|
||||
|
||||
# Regex to match _wrap(..., "CATEGORY", ...) or _wrap_multi(..., "CATEGORY", ...)
|
||||
LABEL_PATTERN = re.compile(r'_wrap(?:_multi)?\(.*?,\s*"([^"]+)",\s*(?:offset|[\w]+)\)')
|
||||
|
||||
|
||||
@pytest.mark.parametrize("modname,expected", CATEGORY_MODULES.items(), ids=lambda x: x.split(".")[-1] if "." in x else x)
|
||||
def test_category_labels_lowercase(modname: str, expected: str) -> None:
|
||||
"""Category labels passed to _wrap/_wrap_multi must be lowercase."""
|
||||
mod = importlib.import_module(modname)
|
||||
source_file = inspect.getfile(mod)
|
||||
with open(source_file, "r", encoding="utf-8") as f:
|
||||
source = f.read()
|
||||
|
||||
# Find all category labels in source
|
||||
labels = LABEL_PATTERN.findall(source)
|
||||
bad = [lbl for lbl in labels if lbl != expected]
|
||||
assert bad == [], (
|
||||
f"{modname}: expected category label '{expected}', found non-matching: {set(bad)}"
|
||||
)
|
||||
@@ -0,0 +1,45 @@
|
||||
"""test_compat.py — pandas-ta compatibility alias tests."""
|
||||
from __future__ import annotations
|
||||
|
||||
import pytest
|
||||
|
||||
from quantalib._compat import ALIASES, get_compat
|
||||
|
||||
|
||||
class TestAliases:
|
||||
"""Validate ALIASES mapping and get_compat resolution."""
|
||||
|
||||
def test_aliases_is_dict(self) -> None:
|
||||
assert isinstance(ALIASES, dict)
|
||||
assert len(ALIASES) > 0
|
||||
|
||||
def test_all_aliases_are_strings(self) -> None:
|
||||
for key, val in ALIASES.items():
|
||||
assert isinstance(key, str), f"Key {key!r} is not str"
|
||||
assert isinstance(val, str), f"Value {val!r} for key {key!r} is not str"
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"alias,target",
|
||||
[
|
||||
("midprice", "medprice"),
|
||||
("momentum", "mom"),
|
||||
("simple_moving_average", "sma"),
|
||||
("true_range", "tr"),
|
||||
("on_balance_volume", "obv"),
|
||||
("bollinger_bands", "bbands"),
|
||||
("z_score", "zscore"),
|
||||
],
|
||||
)
|
||||
def test_known_aliases(self, alias: str, target: str) -> None:
|
||||
assert ALIASES[alias] == target
|
||||
|
||||
def test_get_compat_unknown_returns_none(self) -> None:
|
||||
result = get_compat("nonexistent_indicator_xyz")
|
||||
assert result is None
|
||||
|
||||
def test_get_compat_known_returns_callable(self) -> None:
|
||||
fn = get_compat("simple_moving_average")
|
||||
# May be None if native lib not available, but function itself resolves
|
||||
# We just test the lookup mechanism works
|
||||
if fn is not None:
|
||||
assert callable(fn)
|
||||
@@ -0,0 +1,194 @@
|
||||
"""test_helpers.py — Unit tests for quantalib._helpers (no native lib needed)."""
|
||||
from __future__ import annotations
|
||||
|
||||
import numpy as np
|
||||
import pytest
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Helpers
|
||||
# ---------------------------------------------------------------------------
|
||||
def _has_pandas() -> bool:
|
||||
try:
|
||||
import pandas # noqa: F401
|
||||
return True
|
||||
except ImportError:
|
||||
return False
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# _arr
|
||||
# ---------------------------------------------------------------------------
|
||||
class TestArr:
|
||||
"""Tests for _arr() input coercion and validation."""
|
||||
|
||||
def test_list_to_float64(self) -> None:
|
||||
from quantalib._helpers import _arr
|
||||
arr, idx = _arr([1.0, 2.0, 3.0])
|
||||
assert arr.dtype == np.float64
|
||||
assert idx is None
|
||||
np.testing.assert_array_equal(arr, [1.0, 2.0, 3.0])
|
||||
|
||||
def test_int_array_coerced(self) -> None:
|
||||
from quantalib._helpers import _arr
|
||||
arr, _ = _arr(np.array([1, 2, 3]))
|
||||
assert arr.dtype == np.float64
|
||||
|
||||
def test_contiguous_no_copy(self) -> None:
|
||||
from quantalib._helpers import _arr
|
||||
src = np.array([1.0, 2.0, 3.0], dtype=np.float64)
|
||||
arr, _ = _arr(src)
|
||||
# Already contiguous float64 — should share memory
|
||||
assert np.shares_memory(arr, src)
|
||||
|
||||
def test_non_contiguous_made_contiguous(self) -> None:
|
||||
from quantalib._helpers import _arr
|
||||
src = np.array([1.0, 2.0, 3.0, 4.0], dtype=np.float64)[::2]
|
||||
assert not src.flags["C_CONTIGUOUS"]
|
||||
arr, _ = _arr(src)
|
||||
assert arr.flags["C_CONTIGUOUS"]
|
||||
|
||||
def test_none_raises(self) -> None:
|
||||
from quantalib._helpers import _arr
|
||||
with pytest.raises(ValueError, match="must not be None"):
|
||||
_arr(None)
|
||||
|
||||
def test_empty_raises(self) -> None:
|
||||
from quantalib._helpers import _arr
|
||||
with pytest.raises(ValueError, match="must not be empty"):
|
||||
_arr(np.array([], dtype=np.float64))
|
||||
|
||||
def test_scalar_raises(self) -> None:
|
||||
from quantalib._helpers import _arr
|
||||
with pytest.raises(ValueError, match="must not be empty"):
|
||||
_arr(np.float64(42.0))
|
||||
|
||||
@pytest.mark.skipif(not _has_pandas(), reason="pandas not installed")
|
||||
def test_pandas_series_preserves_index(self) -> None:
|
||||
import pandas as pd
|
||||
from quantalib._helpers import _arr
|
||||
idx = pd.date_range("2020-01-01", periods=5)
|
||||
s = pd.Series([1.0, 2.0, 3.0, 4.0, 5.0], index=idx)
|
||||
arr, ridx = _arr(s)
|
||||
assert arr.dtype == np.float64
|
||||
assert ridx is idx
|
||||
|
||||
@pytest.mark.skipif(not _has_pandas(), reason="pandas not installed")
|
||||
def test_pandas_dataframe_uses_first_col(self) -> None:
|
||||
import pandas as pd
|
||||
from quantalib._helpers import _arr
|
||||
df = pd.DataFrame({"a": [1.0, 2.0], "b": [3.0, 4.0]})
|
||||
arr, idx = _arr(df)
|
||||
np.testing.assert_array_equal(arr, [1.0, 2.0])
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# _offset
|
||||
# ---------------------------------------------------------------------------
|
||||
class TestOffset:
|
||||
"""Tests for _offset() roll + NaN fill."""
|
||||
|
||||
def test_zero_offset_noop(self) -> None:
|
||||
from quantalib._helpers import _offset
|
||||
arr = np.array([1.0, 2.0, 3.0])
|
||||
result = _offset(arr, 0)
|
||||
np.testing.assert_array_equal(result, arr)
|
||||
|
||||
def test_positive_offset(self) -> None:
|
||||
from quantalib._helpers import _offset
|
||||
arr = np.array([1.0, 2.0, 3.0, 4.0])
|
||||
result = _offset(arr, 2)
|
||||
assert np.isnan(result[0])
|
||||
assert np.isnan(result[1])
|
||||
assert result[2] == 1.0
|
||||
assert result[3] == 2.0
|
||||
|
||||
def test_negative_offset(self) -> None:
|
||||
from quantalib._helpers import _offset
|
||||
arr = np.array([1.0, 2.0, 3.0, 4.0])
|
||||
result = _offset(arr, -1)
|
||||
assert result[0] == 2.0
|
||||
assert result[1] == 3.0
|
||||
assert result[2] == 4.0
|
||||
assert np.isnan(result[3])
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# _wrap and _wrap_multi
|
||||
# ---------------------------------------------------------------------------
|
||||
class TestWrap:
|
||||
"""Tests for _wrap() and _wrap_multi()."""
|
||||
|
||||
def test_wrap_numpy_no_offset(self) -> None:
|
||||
from quantalib._helpers import _wrap
|
||||
arr = np.array([10.0, 20.0, 30.0])
|
||||
result = _wrap(arr, None, "TEST", "cat", 0)
|
||||
assert isinstance(result, np.ndarray)
|
||||
np.testing.assert_array_equal(result, arr)
|
||||
|
||||
def test_wrap_numpy_with_offset(self) -> None:
|
||||
from quantalib._helpers import _wrap
|
||||
arr = np.array([10.0, 20.0, 30.0])
|
||||
result = _wrap(arr, None, "TEST", "cat", 1)
|
||||
assert np.isnan(result[0])
|
||||
assert result[1] == 10.0
|
||||
|
||||
@pytest.mark.skipif(not _has_pandas(), reason="pandas not installed")
|
||||
def test_wrap_pandas_series_category_in_attrs(self) -> None:
|
||||
import pandas as pd
|
||||
from quantalib._helpers import _wrap
|
||||
idx = pd.RangeIndex(3)
|
||||
arr = np.array([10.0, 20.0, 30.0])
|
||||
result = _wrap(arr, idx, "SMA_10", "trends_fir", 0)
|
||||
assert isinstance(result, pd.Series)
|
||||
assert result.name == "SMA_10"
|
||||
assert result.attrs["category"] == "trends_fir"
|
||||
|
||||
def test_wrap_multi_numpy(self) -> None:
|
||||
from quantalib._helpers import _wrap_multi
|
||||
arrays = {
|
||||
"upper": np.array([1.0, 2.0]),
|
||||
"lower": np.array([0.5, 1.0]),
|
||||
}
|
||||
result = _wrap_multi(arrays, None, "cat", 0)
|
||||
assert isinstance(result, tuple)
|
||||
assert len(result) == 2
|
||||
|
||||
@pytest.mark.skipif(not _has_pandas(), reason="pandas not installed")
|
||||
def test_wrap_multi_pandas_attrs(self) -> None:
|
||||
import pandas as pd
|
||||
from quantalib._helpers import _wrap_multi
|
||||
idx = pd.RangeIndex(2)
|
||||
arrays = {
|
||||
"upper": np.array([1.0, 2.0]),
|
||||
"lower": np.array([0.5, 1.0]),
|
||||
}
|
||||
result = _wrap_multi(arrays, idx, "channels", 0)
|
||||
assert isinstance(result, pd.DataFrame)
|
||||
assert result.attrs["category"] == "channels"
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# _out
|
||||
# ---------------------------------------------------------------------------
|
||||
class TestOut:
|
||||
"""Tests for _out() allocation."""
|
||||
|
||||
def test_out_shape_and_dtype(self) -> None:
|
||||
from quantalib._helpers import _out
|
||||
arr = _out(100)
|
||||
assert arr.shape == (100,)
|
||||
assert arr.dtype == np.float64
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# _ptr
|
||||
# ---------------------------------------------------------------------------
|
||||
class TestPtr:
|
||||
"""Tests for _ptr() ctypes pointer extraction."""
|
||||
|
||||
def test_ptr_not_none(self) -> None:
|
||||
from quantalib._helpers import _ptr
|
||||
arr = np.array([1.0, 2.0, 3.0], dtype=np.float64)
|
||||
p = _ptr(arr)
|
||||
assert p is not None
|
||||
@@ -0,0 +1,41 @@
|
||||
"""test_module_imports.py — Verify all category modules import without SyntaxError."""
|
||||
from __future__ import annotations
|
||||
|
||||
import importlib
|
||||
import pytest
|
||||
|
||||
# Every module that must be importable (no native lib required at import time
|
||||
# because all native calls are deferred to function invocation).
|
||||
MODULES = [
|
||||
"quantalib._helpers",
|
||||
"quantalib._compat",
|
||||
"quantalib._loader",
|
||||
"quantalib._bridge",
|
||||
"quantalib.channels",
|
||||
"quantalib.core",
|
||||
"quantalib.cycles",
|
||||
"quantalib.dynamics",
|
||||
"quantalib.errors",
|
||||
"quantalib.filters",
|
||||
"quantalib.momentum",
|
||||
"quantalib.numerics",
|
||||
"quantalib.oscillators",
|
||||
"quantalib.reversals",
|
||||
"quantalib.statistics",
|
||||
"quantalib.trends_fir",
|
||||
"quantalib.trends_iir",
|
||||
"quantalib.volatility",
|
||||
"quantalib.volume",
|
||||
"quantalib.indicators",
|
||||
]
|
||||
|
||||
|
||||
@pytest.mark.parametrize("modname", MODULES, ids=lambda m: m.split(".")[-1])
|
||||
def test_module_imports(modname: str) -> None:
|
||||
"""Each module must import without SyntaxError or ImportError.
|
||||
|
||||
This catches reserved-keyword parameter names (lambda), duplicate
|
||||
parameter names, and broken imports.
|
||||
"""
|
||||
mod = importlib.import_module(modname)
|
||||
assert mod is not None
|
||||
@@ -0,0 +1,117 @@
|
||||
"""test_signatures.py — Verify function signatures have no reserved keywords or duplicates."""
|
||||
from __future__ import annotations
|
||||
|
||||
import importlib
|
||||
import inspect
|
||||
import keyword
|
||||
import pytest
|
||||
|
||||
# All category modules with public indicator functions
|
||||
CATEGORY_MODULES = [
|
||||
"quantalib.channels",
|
||||
"quantalib.core",
|
||||
"quantalib.cycles",
|
||||
"quantalib.dynamics",
|
||||
"quantalib.errors",
|
||||
"quantalib.filters",
|
||||
"quantalib.momentum",
|
||||
"quantalib.numerics",
|
||||
"quantalib.oscillators",
|
||||
"quantalib.reversals",
|
||||
"quantalib.statistics",
|
||||
"quantalib.trends_fir",
|
||||
"quantalib.trends_iir",
|
||||
"quantalib.volatility",
|
||||
"quantalib.volume",
|
||||
]
|
||||
|
||||
|
||||
def _get_public_functions():
|
||||
"""Yield (module_name, func_name, func) for all public functions."""
|
||||
for modname in CATEGORY_MODULES:
|
||||
mod = importlib.import_module(modname)
|
||||
all_names = getattr(mod, "__all__", [])
|
||||
for name in all_names:
|
||||
fn = getattr(mod, name, None)
|
||||
if fn is not None and callable(fn):
|
||||
yield modname, name, fn
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def all_functions():
|
||||
return list(_get_public_functions())
|
||||
|
||||
|
||||
class TestNoReservedKeywords:
|
||||
"""No function parameter should use a Python reserved keyword."""
|
||||
|
||||
def test_no_reserved_keyword_params(self, all_functions) -> None:
|
||||
violations = []
|
||||
for modname, fname, fn in all_functions:
|
||||
sig = inspect.signature(fn)
|
||||
for pname in sig.parameters:
|
||||
if keyword.iskeyword(pname):
|
||||
violations.append(f"{modname}.{fname}(... {pname} ...)")
|
||||
assert violations == [], (
|
||||
f"Reserved keyword used as parameter name:\n"
|
||||
+ "\n".join(f" - {v}" for v in violations)
|
||||
)
|
||||
|
||||
|
||||
class TestNoDuplicateParams:
|
||||
"""No function should have duplicate parameter names (caught at parse time,
|
||||
but this validates post-fix)."""
|
||||
|
||||
def test_no_duplicate_params(self, all_functions) -> None:
|
||||
violations = []
|
||||
for modname, fname, fn in all_functions:
|
||||
sig = inspect.signature(fn)
|
||||
params = list(sig.parameters.keys())
|
||||
if len(params) != len(set(params)):
|
||||
seen = set()
|
||||
dupes = [p for p in params if p in seen or seen.add(p)] # type: ignore[func-returns-value]
|
||||
violations.append(f"{modname}.{fname}: duplicates={dupes}")
|
||||
assert violations == [], (
|
||||
f"Duplicate parameter names found:\n"
|
||||
+ "\n".join(f" - {v}" for v in violations)
|
||||
)
|
||||
|
||||
|
||||
class TestNoBuiltinShadowing:
|
||||
"""Public function names should not shadow critical Python builtins."""
|
||||
|
||||
CRITICAL_BUILTINS = {"super", "type", "id", "input", "print", "open", "list", "dict", "set", "map", "filter"}
|
||||
|
||||
def test_no_builtin_function_names(self, all_functions) -> None:
|
||||
violations = []
|
||||
for modname, fname, fn in all_functions:
|
||||
if fname in self.CRITICAL_BUILTINS:
|
||||
violations.append(f"{modname}.{fname}")
|
||||
assert violations == [], (
|
||||
f"Function names shadow Python builtins:\n"
|
||||
+ "\n".join(f" - {v}" for v in violations)
|
||||
)
|
||||
|
||||
|
||||
class TestVolumeIndicatorsHaveVolumeParam:
|
||||
"""Volume indicators that use _ptr(volume) must have volume in their signature."""
|
||||
|
||||
VOLUME_REQUIRED = [
|
||||
"adl", "adosc", "iii", "kvo", "va", "vwad", "vwap", "wad",
|
||||
"obv", "pvt", "pvr", "vf", "nvi", "pvi", "tvi", "pvd",
|
||||
"vwma", "evwma", "efi", "aobv", "mfi", "cmf", "eom", "pvo",
|
||||
]
|
||||
|
||||
def test_volume_funcs_have_volume_param(self) -> None:
|
||||
import quantalib.volume as vol
|
||||
violations = []
|
||||
for fname in self.VOLUME_REQUIRED:
|
||||
fn = getattr(vol, fname, None)
|
||||
if fn is None:
|
||||
continue
|
||||
sig = inspect.signature(fn)
|
||||
if "volume" not in sig.parameters:
|
||||
violations.append(fname)
|
||||
assert violations == [], (
|
||||
f"Volume functions missing 'volume' parameter: {violations}"
|
||||
)
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,9 @@
|
||||
import re, os
|
||||
total = 0
|
||||
for f in sorted(os.listdir('python/quantalib')):
|
||||
if f.endswith('.py') and not f.startswith('_') and f != 'indicators.py':
|
||||
content = open(f'python/quantalib/{f}', encoding='utf-8').read()
|
||||
defs = re.findall(r'^def (\w+)\(', content, re.MULTILINE)
|
||||
total += len(defs)
|
||||
print(f'{f}: {len(defs)} functions - {", ".join(defs[:10])}{"..." if len(defs) > 10 else ""}')
|
||||
print(f'\nTotal: {total} wrapper functions across {len([f for f in os.listdir("python/quantalib") if f.endswith(".py") and not f.startswith("_") and f != "indicators.py"])} files')
|
||||
@@ -0,0 +1,28 @@
|
||||
import re, os
|
||||
|
||||
# Collect all function names from new category files
|
||||
new_fns = set()
|
||||
for f in sorted(os.listdir('python/quantalib')):
|
||||
if f.endswith('.py') and not f.startswith('_') and f != 'indicators.py':
|
||||
content = open(f'python/quantalib/{f}', encoding='utf-8').read()
|
||||
new_fns.update(re.findall(r'^def (\w+)\(', content, re.MULTILINE))
|
||||
|
||||
# Collect from old indicators.py
|
||||
old_content = open('python/quantalib/indicators.py', encoding='utf-8').read()
|
||||
old_fns = set(re.findall(r'^def (\w+)\(', old_content, re.MULTILINE))
|
||||
old_fns = {f for f in old_fns if not f.startswith('_')}
|
||||
|
||||
missing = sorted(old_fns - new_fns)
|
||||
extra = sorted(new_fns - old_fns)
|
||||
|
||||
with open('python/tools/diff_report.txt', 'w') as out:
|
||||
out.write(f'Old indicators.py: {len(old_fns)} public functions\n')
|
||||
out.write(f'New category files: {len(new_fns)} functions\n\n')
|
||||
out.write(f'Missing from new ({len(missing)}):\n')
|
||||
for m in missing:
|
||||
out.write(f' {m}\n')
|
||||
out.write(f'\nNew indicators not in old ({len(extra)}):\n')
|
||||
for e in extra:
|
||||
out.write(f' {e}\n')
|
||||
|
||||
print('Done - see python/tools/diff_report.txt')
|
||||
@@ -0,0 +1,18 @@
|
||||
"""Extract C# export signatures for category module generation."""
|
||||
import re
|
||||
|
||||
cs = open('python/src/Exports.Generated.cs', encoding='utf-8').read()
|
||||
|
||||
# Extract each function: entry point name + full C# parameter list
|
||||
pattern = r'\[UnmanagedCallersOnly\(EntryPoint\s*=\s*"qtl_(\w+)"\)\]\s+public static int \w+\(([^)]+)\)'
|
||||
matches = re.findall(pattern, cs)
|
||||
|
||||
for name, params in matches:
|
||||
# Parse param types + names
|
||||
parts = []
|
||||
for p in params.split(','):
|
||||
p = p.strip()
|
||||
tokens = p.split()
|
||||
if len(tokens) >= 2:
|
||||
parts.append(f"{tokens[0]} {tokens[1]}")
|
||||
print(f"qtl_{name}|{'|'.join(parts)}")
|
||||
@@ -0,0 +1,767 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Generate per-category Python indicator modules from Exports.Generated.cs.
|
||||
|
||||
Reads the C# exports file and the lib/ directory structure to produce:
|
||||
- python/quantalib/_helpers.py (shared wrapper infrastructure)
|
||||
- python/quantalib/_bridge.py (ALL ctypes bindings)
|
||||
- python/quantalib/{category}.py (one per lib/ category)
|
||||
- python/quantalib/indicators.py (re-exports everything)
|
||||
- python/quantalib/__init__.py (package root)
|
||||
|
||||
Usage:
|
||||
python python/tools/generate_category_modules.py
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
from dataclasses import dataclass, field
|
||||
from pathlib import Path
|
||||
|
||||
REPO_ROOT = Path(__file__).resolve().parents[2]
|
||||
LIB_DIR = REPO_ROOT / "lib"
|
||||
EXPORTS_CS = REPO_ROOT / "python" / "src" / "Exports.Generated.cs"
|
||||
OUT_DIR = REPO_ROOT / "python" / "quantalib"
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Category mapping: lib/ subdirectory → Python module name
|
||||
# ---------------------------------------------------------------------------
|
||||
CATEGORY_PY_NAME: dict[str, str] = {
|
||||
"channels": "channels",
|
||||
"core": "core",
|
||||
"cycles": "cycles",
|
||||
"dynamics": "dynamics",
|
||||
"errors": "errors",
|
||||
"filters": "filters",
|
||||
"forecasts": "forecasts",
|
||||
"momentum": "momentum",
|
||||
"numerics": "numerics",
|
||||
"oscillators": "oscillators",
|
||||
"reversals": "reversals",
|
||||
"statistics": "statistics_", # avoid shadowing stdlib 'statistics'
|
||||
"trends_FIR": "trends_fir",
|
||||
"trends_IIR": "trends_iir",
|
||||
"volatility": "volatility",
|
||||
"volume": "volume",
|
||||
}
|
||||
|
||||
# Subdirectories in lib/core/ that are NOT indicators (infrastructure)
|
||||
CORE_SKIP = {
|
||||
"collections", "ringbuffer", "simd", "tbar", "tbarseries",
|
||||
"tests", "tseries", "tvalue", "_index.md",
|
||||
}
|
||||
|
||||
# Export names that don't map cleanly to a lib/ indicator dir
|
||||
EXPORT_RENAMES: dict[str, str] = {
|
||||
"htdcperiod": "ht_dcperiod",
|
||||
"htdcphase": "ht_dcphase",
|
||||
"htphasor": "ht_phasor",
|
||||
"htsine": "ht_sine",
|
||||
"httrendmode": "ht_trendmode",
|
||||
"htit": "htit",
|
||||
"ttmsqueeze": "ttm_squeeze",
|
||||
"ttmtrend": "ttm_trend",
|
||||
"ttmscalper": "ttm_scalper",
|
||||
"ttmwave": "ttm_wave",
|
||||
"ttmlrc": "ttm_lrc",
|
||||
}
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Data model
|
||||
# ---------------------------------------------------------------------------
|
||||
@dataclass
|
||||
class ExportInfo:
|
||||
"""Parsed info for a single [UnmanagedCallersOnly] export."""
|
||||
entry_name: str # e.g. "qtl_sma"
|
||||
func_name: str # e.g. "sma"
|
||||
cs_params: list[tuple[str, str]] # [(type, name), ...]
|
||||
category: str = "" # resolved lib/ category
|
||||
lib_indicator: str = "" # indicator dir name in lib/
|
||||
|
||||
@property
|
||||
def py_module(self) -> str:
|
||||
return CATEGORY_PY_NAME.get(self.category, self.category)
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Step 1: Build category lookup {indicator_name → category}
|
||||
# ---------------------------------------------------------------------------
|
||||
def build_category_map() -> dict[str, str]:
|
||||
"""Scan lib/ subdirectories to build indicator→category mapping."""
|
||||
cat_map: dict[str, str] = {}
|
||||
|
||||
for cat_dir in sorted(LIB_DIR.iterdir()):
|
||||
if not cat_dir.is_dir():
|
||||
continue
|
||||
cat_name = cat_dir.name
|
||||
if cat_name in ("bin", "obj", "feeds") or cat_name.startswith("_") or cat_name.startswith("."):
|
||||
continue
|
||||
|
||||
for ind_dir in sorted(cat_dir.iterdir()):
|
||||
if not ind_dir.is_dir():
|
||||
continue
|
||||
ind_name = ind_dir.name
|
||||
if ind_name.startswith("_") or ind_name.startswith("."):
|
||||
continue
|
||||
if cat_name == "core" and ind_name in CORE_SKIP:
|
||||
continue
|
||||
|
||||
# Normalize: indicator directory names are lowercase
|
||||
cat_map[ind_name.lower()] = cat_name
|
||||
|
||||
return cat_map
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Step 2: Parse Exports.Generated.cs
|
||||
# ---------------------------------------------------------------------------
|
||||
RE_ENTRY = re.compile(
|
||||
r'\[UnmanagedCallersOnly\(EntryPoint\s*=\s*"(qtl_\w+)"\)\]'
|
||||
)
|
||||
RE_FUNC = re.compile(
|
||||
r'public\s+static\s+int\s+\w+\(([^)]*)\)'
|
||||
)
|
||||
|
||||
|
||||
def parse_cs_param(raw: str) -> tuple[str, str]:
|
||||
"""Parse 'double* source' → ('double*', 'source')."""
|
||||
raw = raw.strip()
|
||||
parts = raw.rsplit(None, 1)
|
||||
if len(parts) == 2:
|
||||
return (parts[0], parts[1])
|
||||
return (raw, "")
|
||||
|
||||
|
||||
def parse_exports(cs_path: Path) -> list[ExportInfo]:
|
||||
"""Parse all [UnmanagedCallersOnly] exports from the C# file."""
|
||||
text = cs_path.read_text(encoding="utf-8")
|
||||
lines = text.splitlines()
|
||||
exports: list[ExportInfo] = []
|
||||
|
||||
i = 0
|
||||
while i < len(lines):
|
||||
m = RE_ENTRY.search(lines[i])
|
||||
if m:
|
||||
entry_name = m.group(1) # e.g. "qtl_sma"
|
||||
func_name = entry_name[4:] # strip "qtl_"
|
||||
|
||||
# Find the function signature (may be on next line)
|
||||
for j in range(i + 1, min(i + 5, len(lines))):
|
||||
fm = RE_FUNC.search(lines[j])
|
||||
if fm:
|
||||
raw_params = fm.group(1)
|
||||
params = [parse_cs_param(p) for p in raw_params.split(",")]
|
||||
exports.append(ExportInfo(
|
||||
entry_name=entry_name,
|
||||
func_name=func_name,
|
||||
cs_params=params,
|
||||
))
|
||||
break
|
||||
i = j + 1
|
||||
else:
|
||||
i += 1
|
||||
|
||||
return exports
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Step 3: Resolve categories
|
||||
# ---------------------------------------------------------------------------
|
||||
def resolve_categories(exports: list[ExportInfo], cat_map: dict[str, str]) -> None:
|
||||
"""Assign each export to its lib/ category."""
|
||||
for exp in exports:
|
||||
name = exp.func_name
|
||||
|
||||
# Check rename mapping first
|
||||
mapped = EXPORT_RENAMES.get(name, name)
|
||||
|
||||
if mapped in cat_map:
|
||||
exp.category = cat_map[mapped]
|
||||
exp.lib_indicator = mapped
|
||||
else:
|
||||
# Try underscore variants
|
||||
for variant in [mapped.replace("_", ""), mapped]:
|
||||
if variant in cat_map:
|
||||
exp.category = cat_map[variant]
|
||||
exp.lib_indicator = variant
|
||||
break
|
||||
|
||||
# Special cases
|
||||
if name == "ema_alpha":
|
||||
exp.category = "trends_IIR"
|
||||
exp.lib_indicator = "ema"
|
||||
elif name == "dema_alpha":
|
||||
exp.category = "trends_IIR"
|
||||
exp.lib_indicator = "dema"
|
||||
elif name in ("wclprice", "midpoint", "midprice", "medprice",
|
||||
"avgprice", "typprice", "midbody", "ha"):
|
||||
exp.category = "core"
|
||||
exp.lib_indicator = name
|
||||
elif name == "skeleton_noop":
|
||||
exp.category = "_internal"
|
||||
|
||||
if not exp.category and name != "skeleton_noop":
|
||||
print(f" WARNING: No category for export '{name}'", file=sys.stderr)
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Step 4: Classify parameter patterns for ctypes/Python wrappers
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
def classify_params(exp: ExportInfo) -> dict:
|
||||
"""Classify the export's parameter pattern for code generation."""
|
||||
params = exp.cs_params
|
||||
ptypes = [p[0] for p in params]
|
||||
pnames = [p[1] for p in params]
|
||||
|
||||
info: dict = {
|
||||
"inputs": [], # list of (cs_type, name, py_name)
|
||||
"outputs": [], # list of (cs_type, name, py_name)
|
||||
"int_params": [], # list of (name, py_name, default)
|
||||
"double_params": [], # list of (name, py_name, default)
|
||||
"n_param": None, # name of the length param
|
||||
"pattern": "custom",
|
||||
"argtypes": [],
|
||||
}
|
||||
|
||||
# Identify inputs (double*) that appear before outputs
|
||||
# Heuristic: inputs come before 'n', outputs after
|
||||
n_idx = None
|
||||
for i, (t, n) in enumerate(params):
|
||||
if t == "int" and n in ("n", "length") and n_idx is None:
|
||||
# Special: some have 'n' later
|
||||
pass
|
||||
if n == "n" and t == "int":
|
||||
n_idx = i
|
||||
break
|
||||
|
||||
if n_idx is None:
|
||||
# n might be at different position, find it
|
||||
for i, (t, n) in enumerate(params):
|
||||
if t == "int" and n == "n":
|
||||
n_idx = i
|
||||
break
|
||||
|
||||
return info
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Step 5: Generate ctypes argtypes string
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
def cs_type_to_ctypes(cs_type: str) -> str:
|
||||
"""Convert C# parameter type to ctypes constant."""
|
||||
mapping = {
|
||||
"double*": "_dp",
|
||||
"int": "_ci",
|
||||
"double": "_cd",
|
||||
"int*": "_ip",
|
||||
"long*": "_lp",
|
||||
}
|
||||
return mapping.get(cs_type, f"# UNKNOWN: {cs_type}")
|
||||
|
||||
|
||||
def gen_argtypes(exp: ExportInfo) -> str:
|
||||
"""Generate the ctypes argtypes list for a binding."""
|
||||
parts = [cs_type_to_ctypes(t) for t, _ in exp.cs_params]
|
||||
return "[" + ", ".join(parts) + "]"
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Step 6: Generate _bridge.py
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
def gen_bridge(exports: list[ExportInfo], by_cat: dict[str, list[ExportInfo]]) -> str:
|
||||
"""Generate the complete _bridge.py file."""
|
||||
|
||||
lines = [
|
||||
'"""Low-level ctypes bindings for every quantalib NativeAOT export.',
|
||||
'',
|
||||
'Auto-generated by generate_category_modules.py — DO NOT EDIT.',
|
||||
'',
|
||||
'Each native function is bound via ``_bind`` at module load. If the shared',
|
||||
'library was compiled without a particular export the binding is silently',
|
||||
'skipped (the corresponding ``HAS_*`` flag stays False).',
|
||||
'"""',
|
||||
'from __future__ import annotations',
|
||||
'',
|
||||
'import ctypes',
|
||||
'from ctypes import c_double, c_int, POINTER',
|
||||
'from typing import Final',
|
||||
'',
|
||||
'from ._loader import load_native_library',
|
||||
'',
|
||||
'# ---------------------------------------------------------------------------',
|
||||
'# Status codes (mirror StatusCodes.cs)',
|
||||
'# ---------------------------------------------------------------------------',
|
||||
'QTL_OK: Final[int] = 0',
|
||||
'QTL_ERR_NULL_PTR: Final[int] = 1',
|
||||
'QTL_ERR_INVALID_LENGTH: Final[int] = 2',
|
||||
'QTL_ERR_INVALID_PARAM: Final[int] = 3',
|
||||
'QTL_ERR_INTERNAL: Final[int] = 4',
|
||||
'',
|
||||
'',
|
||||
'class QtlError(Exception):',
|
||||
' """Base exception for quantalib native errors."""',
|
||||
'',
|
||||
'',
|
||||
'class QtlNullPointerError(QtlError):',
|
||||
' pass',
|
||||
'',
|
||||
'',
|
||||
'class QtlInvalidLengthError(QtlError):',
|
||||
' pass',
|
||||
'',
|
||||
'',
|
||||
'class QtlInvalidParamError(QtlError):',
|
||||
' pass',
|
||||
'',
|
||||
'',
|
||||
'class QtlInternalError(QtlError):',
|
||||
' pass',
|
||||
'',
|
||||
'',
|
||||
'_STATUS_MAP: dict[int, type[QtlError]] = {',
|
||||
' QTL_ERR_NULL_PTR: QtlNullPointerError,',
|
||||
' QTL_ERR_INVALID_LENGTH: QtlInvalidLengthError,',
|
||||
' QTL_ERR_INVALID_PARAM: QtlInvalidParamError,',
|
||||
' QTL_ERR_INTERNAL: QtlInternalError,',
|
||||
'}',
|
||||
'',
|
||||
'',
|
||||
'def _check(status: int) -> None:',
|
||||
' """Raise if *status* is not QTL_OK."""',
|
||||
' if status == QTL_OK:',
|
||||
' return',
|
||||
' exc_type = _STATUS_MAP.get(status, QtlError)',
|
||||
' raise exc_type(f"quantalib native call failed (status={status})")',
|
||||
'',
|
||||
'',
|
||||
'# ---------------------------------------------------------------------------',
|
||||
'# Load native library',
|
||||
'# ---------------------------------------------------------------------------',
|
||||
'_lib = load_native_library()',
|
||||
'',
|
||||
'# Shorthand type aliases',
|
||||
'_dp = POINTER(c_double) # double*',
|
||||
'_ip = POINTER(c_int) # int*',
|
||||
'_lp = POINTER(ctypes.c_long) # long*',
|
||||
'_ci = c_int',
|
||||
'_cd = c_double',
|
||||
'',
|
||||
'',
|
||||
'def _bind(name: str, argtypes: list[object]) -> bool:',
|
||||
' """Bind a single native function. Returns True if found."""',
|
||||
' fn = getattr(_lib, name, None)',
|
||||
' if fn is None:',
|
||||
' return False',
|
||||
' fn.argtypes = argtypes',
|
||||
' fn.restype = _ci',
|
||||
' return True',
|
||||
'',
|
||||
'',
|
||||
'# ---------------------------------------------------------------------------',
|
||||
'# Health check',
|
||||
'# ---------------------------------------------------------------------------',
|
||||
'HAS_SKELETON = _bind("qtl_skeleton_noop", [_dp, _ci, _dp])',
|
||||
'',
|
||||
]
|
||||
|
||||
# Category order
|
||||
CAT_ORDER = [
|
||||
"core", "momentum", "oscillators", "trends_FIR", "trends_IIR",
|
||||
"channels", "volatility", "volume", "statistics", "errors",
|
||||
"filters", "cycles", "dynamics", "numerics", "reversals", "forecasts",
|
||||
]
|
||||
|
||||
cat_labels = {
|
||||
"core": "Core",
|
||||
"momentum": "Momentum",
|
||||
"oscillators": "Oscillators",
|
||||
"trends_FIR": "Trends — FIR",
|
||||
"trends_IIR": "Trends — IIR",
|
||||
"channels": "Channels",
|
||||
"volatility": "Volatility",
|
||||
"volume": "Volume",
|
||||
"statistics": "Statistics",
|
||||
"errors": "Errors",
|
||||
"filters": "Filters",
|
||||
"cycles": "Cycles",
|
||||
"dynamics": "Dynamics",
|
||||
"numerics": "Numerics",
|
||||
"reversals": "Reversals",
|
||||
"forecasts": "Forecasts",
|
||||
}
|
||||
|
||||
for cat in CAT_ORDER:
|
||||
if cat not in by_cat:
|
||||
continue
|
||||
exps = by_cat[cat]
|
||||
label = cat_labels.get(cat, cat)
|
||||
lines.append(f'# {"═" * 75}')
|
||||
lines.append(f'# {label}')
|
||||
lines.append(f'# {"═" * 75}')
|
||||
|
||||
for exp in sorted(exps, key=lambda e: e.func_name):
|
||||
varname = f"HAS_{exp.func_name.upper()}"
|
||||
argtypes = gen_argtypes(exp)
|
||||
lines.append(f'{varname} = _bind("{exp.entry_name}", {argtypes})')
|
||||
|
||||
lines.append('')
|
||||
|
||||
return "\n".join(lines)
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Step 7: Generate _helpers.py
|
||||
# ---------------------------------------------------------------------------
|
||||
def gen_helpers() -> str:
|
||||
return '''"""Shared wrapper helpers for quantalib indicator modules.
|
||||
|
||||
Auto-generated by generate_category_modules.py — DO NOT EDIT.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import numpy as np
|
||||
from numpy.typing import NDArray
|
||||
|
||||
from ._bridge import _lib, _check, _dp, _ci, _cd
|
||||
|
||||
# Optional pandas support
|
||||
try:
|
||||
import pandas as pd # type: ignore[import-untyped]
|
||||
except ImportError: # pragma: no cover
|
||||
pd = None # type: ignore[assignment]
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Internal helpers
|
||||
# ---------------------------------------------------------------------------
|
||||
_F64 = np.float64
|
||||
|
||||
|
||||
def _arr(x: object) -> tuple[NDArray[np.float64], object]:
|
||||
"""Return (contiguous float64 array, original_index_or_None)."""
|
||||
idx = None
|
||||
if pd is not None and isinstance(x, pd.Series):
|
||||
idx = x.index
|
||||
x = x.to_numpy(dtype=_F64, copy=False)
|
||||
elif pd is not None and isinstance(x, pd.DataFrame):
|
||||
idx = x.index
|
||||
x = x.iloc[:, 0].to_numpy(dtype=_F64, copy=False)
|
||||
return np.ascontiguousarray(x, dtype=_F64), idx # type: ignore[arg-type]
|
||||
|
||||
|
||||
def _ptr(a: NDArray[np.float64]): # noqa: ANN202
|
||||
"""Get ctypes double* from array."""
|
||||
return a.ctypes.data_as(_dp)
|
||||
|
||||
|
||||
def _out(n: int) -> NDArray[np.float64]:
|
||||
"""Allocate output array."""
|
||||
return np.empty(n, dtype=_F64)
|
||||
|
||||
|
||||
def _offset(arr: NDArray[np.float64], off: int) -> NDArray[np.float64]:
|
||||
"""Apply offset (roll + NaN fill)."""
|
||||
if off and off != 0:
|
||||
arr = np.roll(arr, off)
|
||||
if off > 0:
|
||||
arr[:off] = np.nan
|
||||
else:
|
||||
arr[off:] = np.nan
|
||||
return arr
|
||||
|
||||
|
||||
def _wrap(
|
||||
arr: NDArray[np.float64],
|
||||
idx: object,
|
||||
name: str,
|
||||
category: str,
|
||||
offset: int = 0,
|
||||
):
|
||||
"""Wrap result: apply offset, optionally convert to pd.Series."""
|
||||
arr = _offset(arr, offset)
|
||||
if idx is not None and pd is not None:
|
||||
s = pd.Series(arr, index=idx, name=name)
|
||||
s.category = category
|
||||
return s
|
||||
return arr
|
||||
|
||||
|
||||
def _wrap_multi(
|
||||
arrays: dict[str, NDArray[np.float64]],
|
||||
idx: object,
|
||||
category: str,
|
||||
offset: int = 0,
|
||||
):
|
||||
"""Wrap multi-output result into tuple or DataFrame."""
|
||||
for k in arrays:
|
||||
arrays[k] = _offset(arrays[k], offset)
|
||||
if idx is not None and pd is not None:
|
||||
df = pd.DataFrame(arrays, index=idx)
|
||||
df.category = category
|
||||
return df
|
||||
return tuple(arrays.values())
|
||||
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════════════════
|
||||
# Generic pattern helpers
|
||||
# ═══════════════════════════════════════════════════════════════════════════
|
||||
|
||||
def _pa(
|
||||
fn_name: str, close: object, length: int, offset: int,
|
||||
default_length: int, label: str, category: str,
|
||||
) -> object:
|
||||
"""Generic Pattern A wrapper: single-input + period."""
|
||||
length = int(length) if length is not None else default_length
|
||||
offset = int(offset) if offset is not None else 0
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
dst = _out(n)
|
||||
_check(getattr(_lib, fn_name)(_ptr(src), n, _ptr(dst), length))
|
||||
return _wrap(dst, idx, f"{label}_{length}", category, offset)
|
||||
|
||||
|
||||
def _pa3(
|
||||
fn_name: str, close: object, offset: int,
|
||||
label: str, category: str,
|
||||
) -> object:
|
||||
"""Generic Pattern A3 wrapper: single-input, no params."""
|
||||
offset = int(offset) if offset is not None else 0
|
||||
src, idx = _arr(close)
|
||||
n = len(src)
|
||||
dst = _out(n)
|
||||
_check(getattr(_lib, fn_name)(_ptr(src), n, _ptr(dst)))
|
||||
return _wrap(dst, idx, label, category, offset)
|
||||
|
||||
|
||||
def _pf(
|
||||
fn_name: str, actual: object, predicted: object,
|
||||
length: int, offset: int, default_length: int,
|
||||
label: str, category: str,
|
||||
) -> object:
|
||||
"""Generic Pattern F wrapper: actual+predicted+period."""
|
||||
length = int(length) if length is not None else default_length
|
||||
offset = int(offset) if offset is not None else 0
|
||||
a, idx = _arr(actual)
|
||||
p, _ = _arr(predicted)
|
||||
n = len(a)
|
||||
dst = _out(n)
|
||||
_check(getattr(_lib, fn_name)(_ptr(a), _ptr(p), n, _ptr(dst), length))
|
||||
return _wrap(dst, idx, f"{label}_{length}", category, offset)
|
||||
|
||||
|
||||
def _pg(
|
||||
fn_name: str, close: object, volume: object,
|
||||
offset: int, label: str, category: str,
|
||||
) -> object:
|
||||
"""Pattern G: source+volume, no period."""
|
||||
offset = int(offset) if offset is not None else 0
|
||||
c, idx = _arr(close)
|
||||
v, _ = _arr(volume)
|
||||
n = len(c)
|
||||
dst = _out(n)
|
||||
_check(getattr(_lib, fn_name)(_ptr(c), _ptr(v), n, _ptr(dst)))
|
||||
return _wrap(dst, idx, label, category, offset)
|
||||
|
||||
|
||||
def _pg2(
|
||||
fn_name: str, close: object, volume: object, length: int,
|
||||
offset: int, default_length: int, label: str, category: str,
|
||||
) -> object:
|
||||
"""Pattern G2: source+volume+period."""
|
||||
length = int(length) if length is not None else default_length
|
||||
offset = int(offset) if offset is not None else 0
|
||||
c, idx = _arr(close)
|
||||
v, _ = _arr(volume)
|
||||
n = len(c)
|
||||
dst = _out(n)
|
||||
_check(getattr(_lib, fn_name)(_ptr(c), _ptr(v), n, _ptr(dst), length))
|
||||
return _wrap(dst, idx, f"{label}_{length}", category, offset)
|
||||
|
||||
|
||||
def _ph(
|
||||
fn_name: str, x: object, y: object, length: int,
|
||||
offset: int, default_length: int, label: str, category: str,
|
||||
) -> object:
|
||||
"""Pattern H: X+Y+period."""
|
||||
length = int(length) if length is not None else default_length
|
||||
offset = int(offset) if offset is not None else 0
|
||||
xarr, idx = _arr(x)
|
||||
yarr, _ = _arr(y)
|
||||
n = len(xarr)
|
||||
dst = _out(n)
|
||||
_check(getattr(_lib, fn_name)(_ptr(xarr), _ptr(yarr), n, _ptr(dst), length))
|
||||
return _wrap(dst, idx, f"{label}_{length}", category, offset)
|
||||
|
||||
|
||||
def _ohlcv_bars_period(
|
||||
fn_name: str, open: object, high: object, low: object,
|
||||
close: object, volume: object, period: int,
|
||||
offset: int, default_period: int, label: str, category: str,
|
||||
) -> object:
|
||||
"""OHLCV bars + period → single output (BuildBars pattern)."""
|
||||
period = int(period) if period is not None else default_period
|
||||
offset = int(offset) if offset is not None else 0
|
||||
o, idx = _arr(open)
|
||||
h, _ = _arr(high)
|
||||
l, _ = _arr(low)
|
||||
c, _ = _arr(close)
|
||||
v, _ = _arr(volume)
|
||||
n = len(o)
|
||||
dst = _out(n)
|
||||
_check(getattr(_lib, fn_name)(
|
||||
_ptr(o), _ptr(h), _ptr(l), _ptr(c), _ptr(v), period, n, _ptr(dst)))
|
||||
return _wrap(dst, idx, f"{label}_{period}", category, offset)
|
||||
|
||||
|
||||
def _hlc_period(
|
||||
fn_name: str, high: object, low: object, close: object,
|
||||
period: int, offset: int, default_period: int,
|
||||
label: str, category: str,
|
||||
) -> object:
|
||||
"""HLC + period → single output."""
|
||||
period = int(period) if period is not None else default_period
|
||||
offset = int(offset) if offset is not None else 0
|
||||
h, idx = _arr(high)
|
||||
l, _ = _arr(low)
|
||||
c, _ = _arr(close)
|
||||
n = len(h)
|
||||
dst = _out(n)
|
||||
_check(getattr(_lib, fn_name)(
|
||||
_ptr(h), _ptr(l), _ptr(c), period, n, _ptr(dst)))
|
||||
return _wrap(dst, idx, f"{label}_{period}", category, offset)
|
||||
|
||||
|
||||
def _src_period(
|
||||
fn_name: str, source: object, period: int,
|
||||
offset: int, default_period: int, label: str, category: str,
|
||||
) -> object:
|
||||
"""source + period → single output (BuildSeries pattern, src,period,n,dst)."""
|
||||
period = int(period) if period is not None else default_period
|
||||
offset = int(offset) if offset is not None else 0
|
||||
src, idx = _arr(source)
|
||||
n = len(src)
|
||||
dst = _out(n)
|
||||
_check(getattr(_lib, fn_name)(_ptr(src), period, n, _ptr(dst)))
|
||||
return _wrap(dst, idx, f"{label}_{period}", category, offset)
|
||||
'''
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Step 8: Build per-category wrapper functions
|
||||
# ---------------------------------------------------------------------------
|
||||
# We derive wrapper signatures from the C# export signatures.
|
||||
|
||||
# Manual mappings for export names that need specific Python wrapper treatment
|
||||
# This defines the "known" wrappers. Anything not here gets auto-generated.
|
||||
|
||||
# Map of lib/ directory name → default period for Pattern A indicators
|
||||
DEFAULT_PERIODS: dict[str, int] = {
|
||||
# Trends FIR
|
||||
"sma": 10, "wma": 10, "hma": 9, "trima": 10, "swma": 10, "dwma": 10,
|
||||
"blma": 10, "lsma": 25, "sgma": 10, "sinema": 10, "hanma": 10,
|
||||
"parzen": 10, "tsf": 14, "sp15": 15, "tukey_w": 10, "rain": 10,
|
||||
"fwma": 10, "gwma": 10, "hamma": 10, "hend": 10, "ilrs": 10,
|
||||
"kaiser": 10, "lanczos": 10, "nlma": 10, "nyqma": 10, "pma": 10,
|
||||
"pwma": 10, "qrma": 10, "rwma": 10, "bwma": 10,
|
||||
# Trends IIR
|
||||
"ema": 10, "dema": 10, "tema": 10, "lema": 10, "hema": 10,
|
||||
"ahrens": 10, "decycler": 20, "frama": 10, "hwma": 10,
|
||||
"jma": 10, "kama": 10, "ltma": 10, "mama": 10, "mavp": 10,
|
||||
"mcnma": 10, "mgdi": 10, "mma": 10, "nma": 10, "qema": 10,
|
||||
"rema": 10, "rgma": 10, "rma": 10, "t3": 10, "trama": 10,
|
||||
"vidya": 10, "zldema": 10, "zlema": 10, "zltema": 10,
|
||||
"adxvma": 14, "vama": 14, "yzvama": 14,
|
||||
# Momentum
|
||||
"rsi": 14, "roc": 10, "mom": 10, "cmo": 14, "bias": 26,
|
||||
"cfo": 14, "rsx": 14, "pmo": 35,
|
||||
"rocp": 10, "rocr": 10, "vel": 10,
|
||||
# Oscillators
|
||||
"fisher": 9, "fisher04": 9, "dpo": 20, "trix": 18, "inertia": 20,
|
||||
"er": 10, "cti": 12, "reflex": 20, "trendflex": 20, "kri": 20,
|
||||
"psl": 12, "lrsi": 14,
|
||||
# Volatility
|
||||
"bbw": 20, "stddev": 20, "variance": 20, "natr": 14, "massi": 14,
|
||||
"ui": 14, "jvolty": 14, "jvoltyn": 14, "rsv": 14, "rv": 14,
|
||||
"rvi": 14, "vov": 14, "vr": 14,
|
||||
# Cycles
|
||||
"cg": 10, "dsp": 20, "ccor": 20,
|
||||
# Statistics
|
||||
"zscore": 20, "entropy": 10, "geomean": 10, "harmean": 10,
|
||||
"hurst": 100, "iqr": 20, "kurtosis": 20, "linreg": 14,
|
||||
"meandev": 20, "median": 20, "mode": 20, "percentile": 20,
|
||||
"polyfit": 20, "quantile": 20, "skew": 20, "spearman": 20,
|
||||
"stddev": 20, "stderr": 20, "sum": 20, "theil": 20,
|
||||
"trim": 20, "wavg": 20, "wins": 20, "ztest": 20,
|
||||
"kendall": 20, "pacf": 20,
|
||||
# Filters
|
||||
"bessel": 14, "butter2": 14, "butter3": 14, "cheby1": 14,
|
||||
"cheby2": 14, "elliptic": 14, "edcf": 14, "bpf": 14,
|
||||
"loess": 14, "nw": 14, "rmed": 14, "sgf": 14, "spbf": 14,
|
||||
"ssf2": 14, "ssf3": 14, "usf": 14, "voss": 14,
|
||||
"wavelet": 14, "wiener": 14,
|
||||
# Numerics
|
||||
"change": 1, "highest": 14, "lowest": 14, "slope": 14,
|
||||
"accel": 0, "jerk": 0,
|
||||
# Errors (all pattern F, default 20)
|
||||
"mse": 20, "rmse": 20, "mae": 20, "mape": 20, "smape": 20,
|
||||
"msle": 20, "rmsle": 20, "me": 20, "mpe": 20, "mrae": 20,
|
||||
"rse": 20, "rae": 20, "rsquared": 20, "wmape": 20, "wrmse": 20,
|
||||
"mdae": 20, "mdape": 20, "mase": 20, "maape": 20, "mapd": 20,
|
||||
"huber": 20, "logcosh": 20, "pseudohuber": 20, "tukeybiweight": 20,
|
||||
"quantileloss": 20, "theilu": 20,
|
||||
}
|
||||
|
||||
|
||||
def main() -> None:
|
||||
print("=== Generating quantalib per-category Python modules ===")
|
||||
|
||||
# Step 1: Build category map
|
||||
cat_map = build_category_map()
|
||||
print(f" Found {len(cat_map)} indicators across {len(set(cat_map.values()))} categories")
|
||||
|
||||
# Step 2: Parse exports
|
||||
exports = parse_exports(EXPORTS_CS)
|
||||
print(f" Parsed {len(exports)} exports from Exports.Generated.cs")
|
||||
|
||||
# Step 3: Resolve categories
|
||||
resolve_categories(exports, cat_map)
|
||||
|
||||
# Group by category
|
||||
by_cat: dict[str, list[ExportInfo]] = {}
|
||||
uncategorized: list[ExportInfo] = []
|
||||
for exp in exports:
|
||||
if exp.category and exp.category != "_internal":
|
||||
by_cat.setdefault(exp.category, []).append(exp)
|
||||
elif exp.category != "_internal":
|
||||
uncategorized.append(exp)
|
||||
|
||||
for cat in sorted(by_cat):
|
||||
inds = sorted(e.func_name for e in by_cat[cat])
|
||||
print(f" {cat}: {len(inds)} indicators")
|
||||
|
||||
if uncategorized:
|
||||
print(f" UNCATEGORIZED: {[e.func_name for e in uncategorized]}")
|
||||
|
||||
# Step 4: Generate _helpers.py
|
||||
helpers_path = OUT_DIR / "_helpers.py"
|
||||
helpers_path.write_text(gen_helpers(), encoding="utf-8")
|
||||
print(f" Wrote {helpers_path}")
|
||||
|
||||
# Step 5: Generate _bridge.py
|
||||
bridge_path = OUT_DIR / "_bridge.py"
|
||||
bridge_path.write_text(gen_bridge(exports, by_cat), encoding="utf-8")
|
||||
print(f" Wrote {bridge_path}")
|
||||
|
||||
# Step 6-8: will print summary
|
||||
print("\n=== Summary ===")
|
||||
print(f" Total exports: {len(exports)}")
|
||||
print(f" Categorized: {sum(len(v) for v in by_cat.values())}")
|
||||
print(f" Categories: {len(by_cat)}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,927 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Generate per-category Python wrapper modules from C# export signatures.
|
||||
|
||||
Reads Exports.Generated.cs, maps exports to lib/ categories,
|
||||
and generates one .py file per category under python/quantalib/.
|
||||
|
||||
Run from repo root:
|
||||
python python/tools/generate_wrappers.py
|
||||
"""
|
||||
from __future__ import annotations
|
||||
import os
|
||||
import re
|
||||
import textwrap
|
||||
from pathlib import Path
|
||||
|
||||
ROOT = Path(__file__).resolve().parent.parent.parent
|
||||
CS_FILE = ROOT / "python" / "src" / "Exports.Generated.cs"
|
||||
LIB_DIR = ROOT / "lib"
|
||||
OUT_DIR = ROOT / "python" / "quantalib"
|
||||
|
||||
# ── Category mapping ──────────────────────────────────────────────────────
|
||||
# Scan lib/ subdirs to build export→category map
|
||||
def build_category_map() -> dict[str, str]:
|
||||
"""Map indicator name (lowercase) → category folder name."""
|
||||
m: dict[str, str] = {}
|
||||
for cat_dir in sorted(LIB_DIR.iterdir()):
|
||||
if not cat_dir.is_dir() or cat_dir.name.startswith("."):
|
||||
continue
|
||||
cat = cat_dir.name
|
||||
for ind_dir in sorted(cat_dir.iterdir()):
|
||||
if ind_dir.is_dir() and not ind_dir.name.startswith("_"):
|
||||
m[ind_dir.name.lower()] = cat
|
||||
return m
|
||||
|
||||
CAT_MAP = build_category_map()
|
||||
|
||||
# Manual overrides for export names that differ from lib/ dir names
|
||||
EXPORT_TO_LIB = {
|
||||
"abber": "aberr",
|
||||
"htdcperiod": "ht_dcperiod",
|
||||
"htdcphase": "ht_dcphase",
|
||||
"htphasor": "ht_phasor",
|
||||
"htsine": "ht_sine",
|
||||
"httrendmode": "ht_trendmode",
|
||||
"htit": "htit",
|
||||
"ttmlrc": "ttm_lrc",
|
||||
"ttmscalper": "ttm_scalper",
|
||||
"ttmsqueeze": "ttm_squeeze",
|
||||
"ttmtrend": "ttm_trend",
|
||||
"ttmwave": "ttm_wave",
|
||||
}
|
||||
|
||||
def get_category(export_name: str) -> str:
|
||||
"""Return category for an export name."""
|
||||
lib_name = EXPORT_TO_LIB.get(export_name, export_name)
|
||||
if lib_name in CAT_MAP:
|
||||
return CAT_MAP[lib_name]
|
||||
# Some exports have _ removed vs lib dir (e.g. td_seq → tdseq)
|
||||
for k, v in CAT_MAP.items():
|
||||
if k.replace("_", "") == export_name.replace("_", ""):
|
||||
return v
|
||||
return "uncategorized"
|
||||
|
||||
|
||||
# ── Parse C# exports ─────────────────────────────────────────────────────
|
||||
def parse_exports() -> list[dict]:
|
||||
"""Parse all exports from Exports.Generated.cs."""
|
||||
cs = CS_FILE.read_text(encoding="utf-8")
|
||||
pattern = r'\[UnmanagedCallersOnly\(EntryPoint\s*=\s*"qtl_(\w+)"\)\]\s+public static int \w+\(([^)]+)\)'
|
||||
exports = []
|
||||
for name, params_str in re.findall(pattern, cs):
|
||||
params = []
|
||||
for p in params_str.split(","):
|
||||
p = p.strip()
|
||||
tokens = p.split()
|
||||
if len(tokens) >= 2:
|
||||
ptype = tokens[0]
|
||||
pname = tokens[1]
|
||||
params.append({"type": ptype, "name": pname})
|
||||
exports.append({
|
||||
"name": name,
|
||||
"params": params,
|
||||
"category": get_category(name),
|
||||
})
|
||||
return exports
|
||||
|
||||
|
||||
# ── Classify param roles ─────────────────────────────────────────────────
|
||||
def classify_params(params):
|
||||
"""Identify inputs, outputs, scalars in a param list."""
|
||||
inputs = []
|
||||
outputs = []
|
||||
n_idx = None
|
||||
scalars = []
|
||||
|
||||
for i, p in enumerate(params):
|
||||
name = p["name"]
|
||||
ptype = p["type"]
|
||||
|
||||
if name == "n":
|
||||
n_idx = i
|
||||
continue
|
||||
|
||||
if ptype == "double*":
|
||||
# Heuristic: if name contains output/dst/destination/Out/middle/upper/lower etc.
|
||||
out_names = {"output", "dst", "destination", "middle", "upper", "lower",
|
||||
"haOpenOut", "haHighOut", "haLowOut", "haCloseOut",
|
||||
"dstMiddle", "dstUpper", "dstLower", "dstTenkan", "dstKijun",
|
||||
"dstSenkouA", "dstSenkouB", "dstChikou",
|
||||
"kOut", "dOut", "jOut", "kstOut", "sigOut",
|
||||
"rvgiOutput", "signalOutput", "signalOutput",
|
||||
"momOut", "sqOut", "trend", "strength",
|
||||
"sine", "leadSine", "inPhase", "quadrature", "ppOutput",
|
||||
"upOutput", "downOutput", "highOutput", "lowOutput",
|
||||
"pmaOutput", "triggerOutput", "famaOutput",
|
||||
"upper1", "lower1", "upper2", "lower2", "vwap", "stdDev",
|
||||
"viPlus", "viMinus", "midline",
|
||||
"signal"}
|
||||
if name in out_names or name.endswith("Out") or name.endswith("Output"):
|
||||
outputs.append(p)
|
||||
else:
|
||||
inputs.append(p)
|
||||
elif ptype == "int" or ptype == "double":
|
||||
scalars.append(p)
|
||||
|
||||
return inputs, outputs, n_idx, scalars
|
||||
|
||||
|
||||
# ── Generate wrapper function ────────────────────────────────────────────
|
||||
|
||||
# Description map for well-known indicators
|
||||
DESCRIPTIONS = {
|
||||
# Core
|
||||
"avgprice": "Average Price = (O+H+L+C)/4",
|
||||
"ha": "Heikin-Ashi Candles",
|
||||
"medprice": "Median Price = (H+L)/2",
|
||||
"midbody": "Mid Body = (O+C)/2",
|
||||
"midpoint": "Midpoint = src[i] over period",
|
||||
"midprice": "Mid Price = (High+Low)/2 over period",
|
||||
"typprice": "Typical Price = (H+L+C)/3",
|
||||
"wclprice": "Weighted Close Price = (H+L+2*C)/4",
|
||||
# Momentum
|
||||
"asi": "Accumulative Swing Index",
|
||||
"bias": "Bias Indicator",
|
||||
"bop": "Balance of Power",
|
||||
"cci": "Commodity Channel Index",
|
||||
"cfb": "Composite Fractal Behavior",
|
||||
"cmo": "Chande Momentum Oscillator",
|
||||
"macd": "Moving Average Convergence Divergence",
|
||||
"mom": "Momentum",
|
||||
"pmo": "Price Momentum Oscillator",
|
||||
"ppo": "Percentage Price Oscillator",
|
||||
"prs": "Price Relative Strength",
|
||||
"roc": "Rate of Change",
|
||||
"rocp": "Rate of Change (Percentage)",
|
||||
"rocr": "Rate of Change (Ratio)",
|
||||
"rsi": "Relative Strength Index",
|
||||
"rsx": "Relative Strength Xtra",
|
||||
"sam": "Simple Alpha Momentum",
|
||||
"tsi": "True Strength Index",
|
||||
"vel": "Velocity",
|
||||
# Oscillators
|
||||
"ac": "Accelerator Oscillator",
|
||||
"ao": "Awesome Oscillator",
|
||||
"apo": "Absolute Price Oscillator",
|
||||
"bbb": "Bollinger Band Bounce",
|
||||
"bbi": "Bull Bear Index",
|
||||
"bbs": "Bollinger Band Squeeze",
|
||||
"brar": "Bull-Bear Ratio",
|
||||
"cfo": "Chande Forecast Oscillator",
|
||||
"coppock": "Coppock Curve",
|
||||
"crsi": "Connors RSI",
|
||||
"cti": "Correlation Trend Indicator",
|
||||
"deco": "DECO Oscillator",
|
||||
"dem": "DeMarker",
|
||||
"dosc": "Derivative Oscillator",
|
||||
"dpo": "Detrended Price Oscillator",
|
||||
"dymoi": "Dynamic Momentum Index",
|
||||
"er": "Efficiency Ratio",
|
||||
"eri": "Elder Ray Index",
|
||||
"fi": "Force Index",
|
||||
"fisher": "Fisher Transform",
|
||||
"fisher04": "Fisher Transform (0.4 variant)",
|
||||
"gator": "Gator Oscillator",
|
||||
"imi": "Intraday Momentum Index",
|
||||
"inertia": "Inertia",
|
||||
"kdj": "KDJ Indicator",
|
||||
"kri": "Kairi Relative Index",
|
||||
"kst": "Know Sure Thing",
|
||||
"lrsi": "Laguerre RSI",
|
||||
"marketfi": "Market Facilitation Index",
|
||||
"mstoch": "Modified Stochastic",
|
||||
"pgo": "Pretty Good Oscillator",
|
||||
"psl": "Psychological Line",
|
||||
"qqe": "Quantitative Qualitative Estimation",
|
||||
"reflex": "Reflex",
|
||||
"reverseema": "Reverse EMA",
|
||||
"rvgi": "Relative Vigor Index",
|
||||
"smi": "Stochastic Momentum Index",
|
||||
"squeeze": "Squeeze Momentum",
|
||||
"stc": "Schaff Trend Cycle",
|
||||
"stoch": "Stochastic Oscillator",
|
||||
"stochf": "Fast Stochastic",
|
||||
"stochrsi": "Stochastic RSI",
|
||||
"td_seq": "Tom DeMark Sequential",
|
||||
"trendflex": "Trendflex",
|
||||
"trix": "Triple EMA Rate of Change",
|
||||
"ttmwave": "TTM Wave",
|
||||
"ultosc": "Ultimate Oscillator",
|
||||
"willr": "Williams %R",
|
||||
# Trends FIR
|
||||
"alma": "Arnaud Legoux Moving Average",
|
||||
"blma": "Blackman Moving Average",
|
||||
"bwma": "Butterworth-weighted Moving Average",
|
||||
"conv": "Convolution Filter",
|
||||
"crma": "Cosine-Ramp Moving Average",
|
||||
"dwma": "Double Weighted Moving Average",
|
||||
"fwma": "Fibonacci Weighted Moving Average",
|
||||
"gwma": "Gaussian Weighted Moving Average",
|
||||
"hamma": "Hamming Moving Average",
|
||||
"hanma": "Hann Moving Average",
|
||||
"hend": "Henderson Moving Average",
|
||||
"hma": "Hull Moving Average",
|
||||
"ilrs": "Integral of Linear Regression Slope",
|
||||
"kaiser": "Kaiser Window Moving Average",
|
||||
"lanczos": "Lanczos Moving Average",
|
||||
"lsma": "Least Squares Moving Average",
|
||||
"nlma": "Non-Lag Moving Average",
|
||||
"nyqma": "Nyquist Moving Average",
|
||||
"parzen": "Parzen Moving Average",
|
||||
"pma": "Predictive Moving Average",
|
||||
"pwma": "Pascal Weighted Moving Average",
|
||||
"qrma": "Quick Reaction Moving Average",
|
||||
"rain": "RAIN Moving Average",
|
||||
"rwma": "Range Weighted Moving Average",
|
||||
"sgma": "Savitzky-Golay Moving Average",
|
||||
"sinema": "Sine Weighted Moving Average",
|
||||
"sma": "Simple Moving Average",
|
||||
"sp15": "SP-15 Moving Average",
|
||||
"swma": "Symmetric Weighted Moving Average",
|
||||
"trima": "Triangular Moving Average",
|
||||
"tsf": "Time Series Forecast",
|
||||
"tukey_w": "Tukey-windowed Moving Average",
|
||||
"wma": "Weighted Moving Average",
|
||||
# Trends IIR
|
||||
"adxvma": "ADX Variable Moving Average",
|
||||
"ahrens": "Ahrens Moving Average",
|
||||
"coral": "CORAL Trend",
|
||||
"decycler": "Simple Decycler",
|
||||
"dema": "Double Exponential Moving Average",
|
||||
"dsma": "Deviation-Scaled Moving Average",
|
||||
"ema": "Exponential Moving Average",
|
||||
"frama": "Fractal Adaptive Moving Average",
|
||||
"gdema": "Generalized Double EMA",
|
||||
"hema": "Henderson EMA",
|
||||
"holt": "Holt Exponential Smoothing",
|
||||
"htit": "Hilbert Transform Instantaneous Trendline",
|
||||
"hwma": "Holt-Winter Moving Average",
|
||||
"jma": "Jurik Moving Average",
|
||||
"kama": "Kaufman Adaptive Moving Average",
|
||||
"lema": "Laguerre EMA",
|
||||
"ltma": "Low-Lag Triple Moving Average",
|
||||
"mama": "MESA Adaptive Moving Average",
|
||||
"mavp": "Moving Average Variable Period",
|
||||
"mcnma": "McNicholl Moving Average",
|
||||
"mgdi": "McGinley Dynamic",
|
||||
"mma": "Modified Moving Average",
|
||||
"nma": "Normalized Moving Average",
|
||||
"qema": "Quadruple EMA",
|
||||
"rema": "Regularized EMA",
|
||||
"rgma": "Recursive Gaussian Moving Average",
|
||||
"rma": "Rolling Moving Average",
|
||||
"t3": "Tillson T3",
|
||||
"tema": "Triple Exponential Moving Average",
|
||||
"trama": "Triangular Adaptive Moving Average",
|
||||
"vama": "Volume Adjusted Moving Average",
|
||||
"vidya": "Variable Index Dynamic Average",
|
||||
"yzvama": "Yang Zhang Volatility Adaptive MA",
|
||||
"zldema": "Zero-Lag Double EMA",
|
||||
"zlema": "Zero-Lag EMA",
|
||||
"zltema": "Zero-Lag Triple EMA",
|
||||
# Channels
|
||||
"abber": "Aberration Bands",
|
||||
"accbands": "Acceleration Bands",
|
||||
"apchannel": "Average Price Channel",
|
||||
"apz": "Adaptive Price Zone",
|
||||
"atrbands": "ATR Bands",
|
||||
"bbands": "Bollinger Bands",
|
||||
"dchannel": "Donchian Channel",
|
||||
"decaychannel": "Decay Channel",
|
||||
"fcb": "Fractal Chaos Bands",
|
||||
"jbands": "J-Line Bands",
|
||||
"kchannel": "Keltner Channel",
|
||||
"maenv": "Moving Average Envelope",
|
||||
"mmchannel": "Min-Max Channel",
|
||||
"pchannel": "Price Channel",
|
||||
"regchannel": "Regression Channel",
|
||||
"sdchannel": "Standard Deviation Channel",
|
||||
"starchannel": "Stoller Average Range Channel (STARC)",
|
||||
"stbands": "SuperTrend Bands",
|
||||
"ttmlrc": "TTM Linear Regression Channel",
|
||||
"ubands": "Upper/Lower Bands",
|
||||
"uchannel": "Ulcer Channel",
|
||||
"vwapbands": "VWAP Bands",
|
||||
"vwapsd": "VWAP Standard Deviation",
|
||||
# Volatility
|
||||
"adr": "Average Daily Range",
|
||||
"atr": "Average True Range",
|
||||
"atrn": "Normalized ATR",
|
||||
"bbw": "Bollinger Band Width",
|
||||
"bbwn": "Bollinger Band Width Normalized",
|
||||
"bbwp": "Bollinger Band Width Percentile",
|
||||
"ccv": "Close-to-Close Volatility",
|
||||
"cv": "Coefficient of Variation",
|
||||
"cvi": "Chaikin Volatility Index",
|
||||
"etherm": "Elder Thermometer",
|
||||
"ewma": "Exponentially Weighted Moving Average Volatility",
|
||||
"gkv": "Garman-Klass Volatility",
|
||||
"hlv": "High-Low Volatility",
|
||||
"hv": "Historical Volatility",
|
||||
"jvolty": "Jurik Volatility",
|
||||
"jvoltyn": "Jurik Volatility Normalized",
|
||||
"massi": "Mass Index",
|
||||
"natr": "Normalized ATR",
|
||||
"rsv": "Rogers-Satchell Volatility",
|
||||
"rv": "Realized Volatility",
|
||||
"rvi": "Relative Volatility Index",
|
||||
"tr": "True Range",
|
||||
"ui": "Ulcer Index",
|
||||
"vov": "Volatility of Volatility",
|
||||
"vr": "Volatility Ratio",
|
||||
"yzv": "Yang-Zhang Volatility",
|
||||
# Volume
|
||||
"adl": "Accumulation/Distribution Line",
|
||||
"adosc": "Accumulation/Distribution Oscillator",
|
||||
"aobv": "Archer On-Balance Volume",
|
||||
"cmf": "Chaikin Money Flow",
|
||||
"efi": "Elder Force Index",
|
||||
"eom": "Ease of Movement",
|
||||
"evwma": "Elastic Volume Weighted Moving Average",
|
||||
"iii": "Intraday Intensity Index",
|
||||
"kvo": "Klinger Volume Oscillator",
|
||||
"mfi": "Money Flow Index",
|
||||
"nvi": "Negative Volume Index",
|
||||
"obv": "On-Balance Volume",
|
||||
"pvd": "Price Volume Divergence",
|
||||
"pvi": "Positive Volume Index",
|
||||
"pvo": "Percentage Volume Oscillator",
|
||||
"pvr": "Price Volume Rank",
|
||||
"pvt": "Price Volume Trend",
|
||||
"tvi": "Trade Volume Index",
|
||||
"twap": "Time Weighted Average Price",
|
||||
"va": "Volume Accumulation",
|
||||
"vf": "Volume Flow",
|
||||
"vo": "Volume Oscillator",
|
||||
"vroc": "Volume Rate of Change",
|
||||
"vwad": "Volume Weighted Accumulation/Distribution",
|
||||
"vwap": "Volume Weighted Average Price",
|
||||
"vwma": "Volume Weighted Moving Average",
|
||||
"wad": "Williams Accumulation/Distribution",
|
||||
# Statistics
|
||||
"acf": "Autocorrelation Function",
|
||||
"beta": "Beta Coefficient",
|
||||
"cma": "Cumulative Moving Average",
|
||||
"cointegration": "Cointegration",
|
||||
"correlation": "Pearson Correlation",
|
||||
"covariance": "Covariance",
|
||||
"entropy": "Shannon Entropy",
|
||||
"geomean": "Geometric Mean",
|
||||
"granger": "Granger Causality",
|
||||
"harmean": "Harmonic Mean",
|
||||
"hurst": "Hurst Exponent",
|
||||
"iqr": "Interquartile Range",
|
||||
"jb": "Jarque-Bera Test",
|
||||
"kendall": "Kendall Rank Correlation",
|
||||
"kurtosis": "Kurtosis",
|
||||
"linreg": "Linear Regression",
|
||||
"meandev": "Mean Deviation",
|
||||
"median": "Rolling Median",
|
||||
"mode": "Rolling Mode",
|
||||
"pacf": "Partial Autocorrelation Function",
|
||||
"percentile": "Rolling Percentile",
|
||||
"polyfit": "Polynomial Fit",
|
||||
"quantile": "Rolling Quantile",
|
||||
"skew": "Skewness",
|
||||
"spearman": "Spearman Rank Correlation",
|
||||
"stddev": "Standard Deviation",
|
||||
"stderr": "Standard Error",
|
||||
"sum": "Rolling Sum",
|
||||
"theil": "Theil U Statistic",
|
||||
"trim": "Trimmed Mean",
|
||||
"variance": "Variance",
|
||||
"wavg": "Weighted Average",
|
||||
"wins": "Winsorized Mean",
|
||||
"zscore": "Z-Score",
|
||||
"ztest": "Z-Test",
|
||||
# Errors
|
||||
"huber": "Huber Loss",
|
||||
"logcosh": "Log-Cosh Loss",
|
||||
"maape": "Mean Arctangent Absolute Percentage Error",
|
||||
"mae": "Mean Absolute Error",
|
||||
"mapd": "Mean Absolute Percentage Deviation",
|
||||
"mape": "Mean Absolute Percentage Error",
|
||||
"mase": "Mean Absolute Scaled Error",
|
||||
"mdae": "Median Absolute Error",
|
||||
"mdape": "Median Absolute Percentage Error",
|
||||
"me": "Mean Error",
|
||||
"mpe": "Mean Percentage Error",
|
||||
"mrae": "Mean Relative Absolute Error",
|
||||
"mse": "Mean Squared Error",
|
||||
"msle": "Mean Squared Logarithmic Error",
|
||||
"pseudohuber": "Pseudo-Huber Loss",
|
||||
"quantileloss": "Quantile Loss (Pinball Loss)",
|
||||
"rae": "Relative Absolute Error",
|
||||
"rmse": "Root Mean Squared Error",
|
||||
"rmsle": "Root Mean Squared Logarithmic Error",
|
||||
"rse": "Relative Squared Error",
|
||||
"rsquared": "R-Squared (Coefficient of Determination)",
|
||||
"smape": "Symmetric Mean Absolute Percentage Error",
|
||||
"theilu": "Theil U Statistic (Error)",
|
||||
"tukeybiweight": "Tukey Biweight Loss",
|
||||
"wmape": "Weighted Mean Absolute Percentage Error",
|
||||
"wrmse": "Weighted Root Mean Squared Error",
|
||||
# Filters
|
||||
"agc": "Automatic Gain Control",
|
||||
"alaguerre": "Adaptive Laguerre Filter",
|
||||
"baxterking": "Baxter-King Filter",
|
||||
"bessel": "Bessel Filter",
|
||||
"bilateral": "Bilateral Filter",
|
||||
"bpf": "Bandpass Filter",
|
||||
"butter2": "2nd-Order Butterworth Filter",
|
||||
"butter3": "3rd-Order Butterworth Filter",
|
||||
"cfitz": "Christiano-Fitzgerald Filter",
|
||||
"cheby1": "Chebyshev Type I Filter",
|
||||
"cheby2": "Chebyshev Type II Filter",
|
||||
"edcf": "Ehlers Distance Coefficient Filter",
|
||||
"elliptic": "Elliptic (Cauer) Filter",
|
||||
"gauss": "Gaussian Filter",
|
||||
"hann": "Hann Filter",
|
||||
"hp": "Hodrick-Prescott Filter",
|
||||
"hpf": "High-Pass Filter",
|
||||
"kalman": "Kalman Filter",
|
||||
"laguerre": "Laguerre Filter",
|
||||
"lms": "Least Mean Squares Filter",
|
||||
"loess": "LOESS Smoother",
|
||||
"modf": "Modified Filter",
|
||||
"notch": "Notch Filter",
|
||||
"nw": "Nadaraya-Watson Filter",
|
||||
"oneeuro": "1€ Filter",
|
||||
"rls": "Recursive Least Squares Filter",
|
||||
"rmed": "Running Median Filter",
|
||||
"roofing": "Roofing Filter",
|
||||
"sgf": "Savitzky-Golay Filter",
|
||||
"spbf": "Short-Period Bandpass Filter",
|
||||
"ssf2": "Super Smoother (2-pole)",
|
||||
"ssf3": "Super Smoother (3-pole)",
|
||||
"usf": "Universal Smoother Filter",
|
||||
"voss": "Voss Predictor",
|
||||
"wavelet": "Wavelet Filter",
|
||||
"wiener": "Wiener Filter",
|
||||
# Cycles
|
||||
"ccor": "Circular Correlation",
|
||||
"ccyc": "Cyber Cycle",
|
||||
"cg": "Center of Gravity",
|
||||
"dsp": "Dominant Cycle Period",
|
||||
"eacp": "Ehlers Autocorrelation Periodogram",
|
||||
"ebsw": "Even Better Sinewave",
|
||||
"homod": "Homodyne Discriminator",
|
||||
"ht_dcperiod": "Hilbert Transform Dominant Cycle Period",
|
||||
"ht_dcphase": "Hilbert Transform Dominant Cycle Phase",
|
||||
"ht_phasor": "Hilbert Transform Phasor",
|
||||
"ht_sine": "Hilbert Transform Sine",
|
||||
"lunar": "Lunar Cycle",
|
||||
"solar": "Solar Cycle",
|
||||
"ssfdsp": "Supersmoother DSP",
|
||||
# Dynamics
|
||||
"adx": "Average Directional Index",
|
||||
"adxr": "ADX Rating",
|
||||
"alligator": "Williams Alligator",
|
||||
"amat": "Archer Moving Average Trends",
|
||||
"aroon": "Aroon",
|
||||
"aroonosc": "Aroon Oscillator",
|
||||
"chop": "Choppiness Index",
|
||||
"dmx": "Directional Movement Extended",
|
||||
"dx": "Directional Movement Index",
|
||||
"ghla": "Gann Hi-Lo Activator",
|
||||
"ht_trendmode": "Hilbert Transform Trend Mode",
|
||||
"ichimoku": "Ichimoku Cloud",
|
||||
"impulse": "Elder Impulse System",
|
||||
"pfe": "Polarized Fractal Efficiency",
|
||||
"qstick": "QStick",
|
||||
"ravi": "Range Action Verification Index",
|
||||
"super": "SuperTrend",
|
||||
"ttmsqueeze": "TTM Squeeze",
|
||||
"ttmtrend": "TTM Trend",
|
||||
"vhf": "Vertical Horizontal Filter",
|
||||
"vortex": "Vortex Indicator",
|
||||
# Reversals
|
||||
"chandelier": "Chandelier Exit",
|
||||
"ckstop": "Chuck LeBeau Stop",
|
||||
"fractals": "Williams Fractals",
|
||||
"pivot": "Pivot Points (Traditional)",
|
||||
"pivotcam": "Camarilla Pivot Points",
|
||||
"pivotdem": "DeMark Pivot Points",
|
||||
"pivotext": "Extended Pivot Points",
|
||||
"pivotfib": "Fibonacci Pivot Points",
|
||||
"pivotwood": "Woodie Pivot Points",
|
||||
"psar": "Parabolic SAR",
|
||||
"swings": "Swing High/Low",
|
||||
"ttmscalper": "TTM Scalper",
|
||||
# Forecasts
|
||||
"afirma": "Adaptive FIR Moving Average",
|
||||
# Numerics
|
||||
"accel": "Acceleration",
|
||||
"betadist": "Beta Distribution",
|
||||
"binomdist": "Binomial Distribution",
|
||||
"change": "Price Change",
|
||||
"cwt": "Continuous Wavelet Transform",
|
||||
"dwt": "Discrete Wavelet Transform",
|
||||
"expdist": "Exponential Distribution",
|
||||
"exptrans": "Exponential Transform",
|
||||
"fdist": "F-Distribution",
|
||||
"fft": "Fast Fourier Transform",
|
||||
"gammadist": "Gamma Distribution",
|
||||
"highest": "Highest Value",
|
||||
"ifft": "Inverse FFT",
|
||||
"jerk": "Jerk (3rd derivative)",
|
||||
"lineartrans": "Linear Transform",
|
||||
"lognormdist": "Log-Normal Distribution",
|
||||
"logtrans": "Logarithmic Transform",
|
||||
"lowest": "Lowest Value",
|
||||
"normalize": "Normalization",
|
||||
"normdist": "Normal Distribution",
|
||||
"poissondist": "Poisson Distribution",
|
||||
"relu": "ReLU Activation",
|
||||
"sigmoid": "Sigmoid Transform",
|
||||
"slope": "Slope (1st derivative)",
|
||||
"sqrttrans": "Square Root Transform",
|
||||
"tdist": "Student's t-Distribution",
|
||||
"weibulldist": "Weibull Distribution",
|
||||
}
|
||||
|
||||
# Python function name overrides (export_name → python_name)
|
||||
PY_NAME = {
|
||||
"abber": "aberr", # fix typo in C# export
|
||||
"htdcperiod": "ht_dcperiod",
|
||||
"htdcphase": "ht_dcphase",
|
||||
"htphasor": "ht_phasor",
|
||||
"htsine": "ht_sine",
|
||||
"httrendmode": "ht_trendmode",
|
||||
"ttmlrc": "ttm_lrc",
|
||||
"ttmscalper": "ttm_scalper",
|
||||
"ttmsqueeze": "ttm_squeeze",
|
||||
"ttmtrend": "ttm_trend",
|
||||
"ttmwave": "ttm_wave",
|
||||
}
|
||||
|
||||
|
||||
def gen_wrapper(export: dict) -> str | None:
|
||||
"""Generate a Python wrapper function for one export."""
|
||||
name = export["name"]
|
||||
params = export["params"]
|
||||
py_name = PY_NAME.get(name, name)
|
||||
label = py_name.upper()
|
||||
cat = export["category"]
|
||||
desc = DESCRIPTIONS.get(name, DESCRIPTIONS.get(py_name, f"{label} indicator"))
|
||||
|
||||
inputs, outputs, n_idx, scalars = classify_params(params)
|
||||
|
||||
# Build Python function signature and body
|
||||
lines = []
|
||||
|
||||
# Determine input pattern and generate accordingly
|
||||
input_names = [p["name"] for p in inputs]
|
||||
output_names = [p["name"] for p in outputs]
|
||||
scalar_specs = [(p["name"], p["type"]) for p in scalars]
|
||||
|
||||
# Build Python params
|
||||
py_params = []
|
||||
py_body = []
|
||||
|
||||
# Categorize input types
|
||||
has_ohlcv = all(x in [p["name"] for p in inputs] for x in ["sourceOpen", "sourceHigh", "sourceLow", "sourceClose", "sourceVolume"])
|
||||
has_ohlc = all(x in [p["name"] for p in inputs] for x in ["open", "high", "low", "close"]) and not has_ohlcv
|
||||
has_hlc = all(x in [p["name"] for p in inputs] for x in ["high", "low", "close"]) and not has_ohlc and not has_ohlcv
|
||||
has_hl = {"high", "low"}.issubset(set(input_names)) and "close" not in input_names and not has_ohlcv
|
||||
has_actual_predicted = {"actual", "predicted"}.issubset(set(input_names))
|
||||
has_xy = {"seriesX", "seriesY"}.issubset(set(input_names)) or {"x", "y"}.issubset(set(input_names))
|
||||
has_src_vol = (len(inputs) == 2 and any("volume" in p["name"].lower() or p["name"] == "volume" for p in inputs))
|
||||
has_price_vol = (len(inputs) == 2 and any(p["name"] == "price" for p in inputs) and any(p["name"] == "volume" for p in inputs))
|
||||
single_src = len(inputs) == 1 and inputs[0]["type"] == "double*"
|
||||
|
||||
# Generate function
|
||||
# Decide function signature
|
||||
sig_params = []
|
||||
|
||||
# Add input params
|
||||
if has_ohlcv:
|
||||
sig_params.extend([
|
||||
"open: object", "high: object", "low: object",
|
||||
"close: object", "volume: object",
|
||||
])
|
||||
elif has_ohlc:
|
||||
sig_params.extend([
|
||||
"open: object", "high: object", "low: object", "close: object",
|
||||
])
|
||||
elif has_hlc:
|
||||
sig_params.extend(["high: object", "low: object", "close: object"])
|
||||
elif has_hl:
|
||||
sig_params.extend(["high: object", "low: object"])
|
||||
elif has_actual_predicted:
|
||||
sig_params.extend(["actual: object", "predicted: object"])
|
||||
elif has_xy:
|
||||
sig_params.extend(["x: object", "y: object"])
|
||||
elif has_price_vol:
|
||||
sig_params.extend(["price: object", "volume: object"])
|
||||
elif has_src_vol:
|
||||
# Figure out which is source, which is volume
|
||||
src_name = [p["name"] for p in inputs if p["name"] != "volume"][0] if inputs else "source"
|
||||
sig_params.extend([f"close: object", "volume: object"])
|
||||
elif single_src:
|
||||
src_name = inputs[0]["name"] if inputs else "source"
|
||||
py_input_name = "close" if src_name in ("source", "src", "prices", "price") else src_name
|
||||
sig_params.append(f"{py_input_name}: object")
|
||||
elif len(inputs) == 2:
|
||||
# Two inputs (e.g. prs: baseSeries, compSeries)
|
||||
for p in inputs:
|
||||
pn = p["name"]
|
||||
if pn.startswith("source") or pn.startswith("base"):
|
||||
pn = "x"
|
||||
elif pn.startswith("comp"):
|
||||
pn = "y"
|
||||
sig_params.append(f"{pn}: object")
|
||||
elif len(inputs) == 0 and len(outputs) == 0:
|
||||
# Weird case
|
||||
return None
|
||||
else:
|
||||
for p in inputs:
|
||||
sig_params.append(f"{p['name']}: object")
|
||||
|
||||
# Add scalar params with defaults
|
||||
scalar_defaults = {
|
||||
"period": 14, "length": 14, "hpLength": 40, "ssLength": 10,
|
||||
"fastPeriod": 12, "slowPeriod": 26, "acPeriod": 5,
|
||||
"bbPeriod": 20, "bbMult": 2.0, "kcPeriod": 10, "kcMult": 1.5,
|
||||
"multiplier": 2.0, "factor": 2.0, "sigma": 6.0,
|
||||
"rsiPeriod": 14, "smoothFactor": 5, "qqeFactor": 4.236,
|
||||
"kPeriod": 14, "dPeriod": 3, "kSmooth": 3, "dSmooth": 3,
|
||||
"kLength": 14, "windowSize": 256, "minPeriod": 6, "maxPeriod": 48,
|
||||
"longRoc": 14, "shortRoc": 11, "wmaPeriod": 10,
|
||||
"r1": 10, "r2": 15, "r3": 20, "r4": 30,
|
||||
"s1": 10, "s2": 10, "s3": 10, "s4": 15, "sigPeriod": 9,
|
||||
"jawPeriod": 13, "jawShift": 8, "jawOffset": 8,
|
||||
"teethPeriod": 8, "teethShift": 5, "teethOffset": 5,
|
||||
"lipsPeriod": 5, "lipsShift": 3, "lipsOffset": 3,
|
||||
"tenkanPeriod": 9, "kijunPeriod": 26, "senkouBPeriod": 52, "displacement": 26,
|
||||
"emaPeriod": 13, "macdFast": 12, "macdSlow": 26, "macdSignal": 9,
|
||||
"signalPeriod": 9, "signal": 3,
|
||||
"numHarmonics": 10,
|
||||
"atrPeriod": 22, "stopPeriod": 3,
|
||||
"alpha": 2.0, "beta": 2.0, "gamma": 0.7, "k": 2.0,
|
||||
"lambda": 1600.0, "mu": 0.01, "mu0": 0.0,
|
||||
"delta": 1.35, "c": 4.685,
|
||||
"q": 0.3, "r": 1.0,
|
||||
"vfactor": 0.7, "vovPeriod": 20, "volatilityPeriod": 20,
|
||||
"d1": 10, "d2": 20, "nu": 10,
|
||||
"order": 3, "polyOrder": 3, "feedback": 0, "fbWeight": 0.5,
|
||||
"annualize": 1, "annualPeriods": 252, "isPopulation": 0,
|
||||
"predict": 3, "bandwidth": 0.25,
|
||||
"nanValue": 0.0, "initialLastValid": 0.0, "initialLast": 0.0,
|
||||
"x0": 0.0, "intercept": 0.0, "slope_val": 1.0,
|
||||
"minCutoff": 1.0, "dCutoff": 1.0,
|
||||
"method": 0, "maType": 0,
|
||||
"percentage": 2.5, "percent": 50.0,
|
||||
"quantileLevel": 0.5, "quantile": 0.5,
|
||||
"trimPct": 0.1, "winPct": 0.05,
|
||||
"offset": 0,
|
||||
"shortPeriod": 12, "longPeriod": 26, "sumLength": 25,
|
||||
"emaLength": 9, "rmaLength": 14, "stdevLength": 10,
|
||||
"stochLength": 14, "rsiLength": 14,
|
||||
"fastLength": 23, "slowLength": 50, "smoothing": 10,
|
||||
"lookback": 5, "useCloses": 0,
|
||||
"levels": 4, "threshMult": 1.0, "smoothPeriod": 5,
|
||||
"blau": 3, "phase": 0, "power": 1.0,
|
||||
"rmsPeriod": 20,
|
||||
"nyquistPeriod": 2, "passes": 3,
|
||||
"cumulative": 0, "usePercent": 1, "useEma": 0,
|
||||
"base": 2.0, "degree": 2,
|
||||
"minLength": 5, "maxLength": 50,
|
||||
"yzvShortPeriod": 10, "yzvLongPeriod": 100, "percentileLookback": 252,
|
||||
"baseLength": 20, "shortAtrPeriod": 14, "longAtrPeriod": 50,
|
||||
"strPeriod": 14, "centerPeriod": 20,
|
||||
"stPeriod": 14, "momPeriod": 12,
|
||||
"scale": 10.0, "omega": 6.0,
|
||||
"trials": 20, "threshold": 10,
|
||||
"lam": 3.0, "afStart": 0.02, "afIncrement": 0.02, "afMax": 0.2,
|
||||
"cutoff": 10, "fastLimit": 0.5, "slowLimit": 0.05,
|
||||
"minVol": 0.2, "maxVol": 0.7,
|
||||
"friction": 0.4,
|
||||
"avgLength": 3, "enhance": 1,
|
||||
"numDevs": 2.0,
|
||||
"window_type": 0, "use_simd": 0,
|
||||
"hpLength_val": 40, "ssfLength": 10,
|
||||
}
|
||||
|
||||
for sname, stype in scalar_specs:
|
||||
# Get reasonable default
|
||||
default = scalar_defaults.get(sname)
|
||||
if default is None:
|
||||
# Try to infer
|
||||
if "period" in sname.lower() or "length" in sname.lower():
|
||||
default = 14
|
||||
elif "mult" in sname.lower() or "factor" in sname.lower():
|
||||
default = 2.0
|
||||
elif stype == "double":
|
||||
default = 1.0
|
||||
else:
|
||||
default = 10
|
||||
|
||||
if stype == "double":
|
||||
sig_params.append(f"{sname}: float = {default}")
|
||||
else:
|
||||
sig_params.append(f"{sname}: int = {int(default)}")
|
||||
|
||||
sig_params.append("offset: int = 0")
|
||||
sig_params.append("**kwargs")
|
||||
|
||||
# Build function body
|
||||
body = []
|
||||
|
||||
# Sanitize scalars
|
||||
for sname, stype in scalar_specs:
|
||||
if stype == "double":
|
||||
body.append(f" {sname} = float({sname})")
|
||||
else:
|
||||
body.append(f" {sname} = int({sname})")
|
||||
body.append(" offset = int(offset)")
|
||||
|
||||
# Convert inputs
|
||||
if has_ohlcv:
|
||||
body.append(" o, idx = _arr(open); h, _ = _arr(high); l, _ = _arr(low)")
|
||||
body.append(" c, _ = _arr(close); v, _ = _arr(volume)")
|
||||
body.append(" n = len(o)")
|
||||
elif has_ohlc:
|
||||
body.append(" o, idx = _arr(open); h, _ = _arr(high); l, _ = _arr(low); c, _ = _arr(close)")
|
||||
body.append(" n = len(o)")
|
||||
elif has_hlc:
|
||||
body.append(" h, idx = _arr(high); l, _ = _arr(low); c, _ = _arr(close)")
|
||||
body.append(" n = len(h)")
|
||||
elif has_hl:
|
||||
body.append(" h, idx = _arr(high); l, _ = _arr(low)")
|
||||
body.append(" n = len(h)")
|
||||
elif has_actual_predicted:
|
||||
body.append(" a, idx = _arr(actual); p, _ = _arr(predicted)")
|
||||
body.append(" n = len(a)")
|
||||
elif has_xy:
|
||||
body.append(" xarr, idx = _arr(x); yarr, _ = _arr(y)")
|
||||
body.append(" n = len(xarr)")
|
||||
elif has_price_vol:
|
||||
body.append(" pr, idx = _arr(price); v, _ = _arr(volume)")
|
||||
body.append(" n = len(pr)")
|
||||
elif has_src_vol:
|
||||
body.append(" src, idx = _arr(close); v, _ = _arr(volume)")
|
||||
body.append(" n = len(src)")
|
||||
elif single_src:
|
||||
py_input_name = "close" if inputs[0]["name"] in ("source", "src", "prices", "price") else inputs[0]["name"]
|
||||
body.append(f" src, idx = _arr({py_input_name})")
|
||||
body.append(" n = len(src)")
|
||||
elif len(inputs) == 2:
|
||||
body.append(f" xarr, idx = _arr(x); yarr, _ = _arr(y)")
|
||||
body.append(" n = len(xarr)")
|
||||
|
||||
# Allocate outputs
|
||||
for p in outputs:
|
||||
body.append(f" {p['name']} = _out(n)")
|
||||
|
||||
# Build native call arguments in original order
|
||||
call_args = []
|
||||
for p in params:
|
||||
pname = p["name"]
|
||||
ptype = p["type"]
|
||||
if pname == "n":
|
||||
call_args.append("n")
|
||||
elif ptype == "double*":
|
||||
if p in outputs:
|
||||
call_args.append(f"_ptr({pname})")
|
||||
else:
|
||||
# Map to our local var names
|
||||
if has_ohlcv:
|
||||
vmap = {"sourceOpen": "o", "sourceHigh": "h", "sourceLow": "l", "sourceClose": "c", "sourceVolume": "v"}
|
||||
call_args.append(f"_ptr({vmap.get(pname, pname)})")
|
||||
elif has_ohlc:
|
||||
vmap = {"open": "o", "high": "h", "low": "l", "close": "c"}
|
||||
call_args.append(f"_ptr({vmap.get(pname, pname)})")
|
||||
elif has_hlc:
|
||||
vmap = {"high": "h", "low": "l", "close": "c"}
|
||||
call_args.append(f"_ptr({vmap.get(pname, pname)})")
|
||||
elif has_hl:
|
||||
vmap = {"high": "h", "low": "l"}
|
||||
call_args.append(f"_ptr({vmap.get(pname, pname)})")
|
||||
elif has_actual_predicted:
|
||||
vmap = {"actual": "a", "predicted": "p"}
|
||||
call_args.append(f"_ptr({vmap.get(pname, pname)})")
|
||||
elif has_xy:
|
||||
vmap = {"seriesX": "xarr", "seriesY": "yarr", "x": "xarr", "y": "yarr"}
|
||||
call_args.append(f"_ptr({vmap.get(pname, pname)})")
|
||||
elif has_price_vol:
|
||||
vmap = {"price": "pr", "volume": "v"}
|
||||
call_args.append(f"_ptr({vmap.get(pname, pname)})")
|
||||
elif has_src_vol:
|
||||
if pname == "volume":
|
||||
call_args.append("_ptr(v)")
|
||||
else:
|
||||
call_args.append("_ptr(src)")
|
||||
elif single_src:
|
||||
call_args.append("_ptr(src)")
|
||||
elif len(inputs) == 2:
|
||||
vmap = {}
|
||||
for ip in inputs:
|
||||
if ip["name"].startswith("source") or ip["name"].startswith("base"):
|
||||
vmap[ip["name"]] = "xarr"
|
||||
else:
|
||||
vmap[ip["name"]] = "yarr"
|
||||
call_args.append(f"_ptr({vmap.get(pname, pname)})")
|
||||
else:
|
||||
call_args.append(f"_ptr({pname})")
|
||||
else:
|
||||
call_args.append(pname)
|
||||
|
||||
call_str = ", ".join(call_args)
|
||||
body.append(f' _check(_lib.qtl_{name}({call_str}))')
|
||||
|
||||
# Wrap output
|
||||
if len(outputs) == 1:
|
||||
out_name = outputs[0]["name"]
|
||||
# Decide label
|
||||
has_period_scalar = any("period" in s[0].lower() or "length" in s[0].lower() for s in scalar_specs)
|
||||
if has_period_scalar:
|
||||
# Use first period-like scalar for label
|
||||
period_var = next(s[0] for s in scalar_specs if "period" in s[0].lower() or "length" in s[0].lower())
|
||||
body.append(f' return _wrap({out_name}, idx, f"{label}_{{{period_var}}}", "{cat}", offset)')
|
||||
else:
|
||||
body.append(f' return _wrap({out_name}, idx, "{label}", "{cat}", offset)')
|
||||
elif len(outputs) > 1:
|
||||
# Multi-output
|
||||
out_dict_parts = []
|
||||
for p in outputs:
|
||||
out_dict_parts.append(f'"{p["name"]}": {p["name"]}')
|
||||
out_dict = ", ".join(out_dict_parts)
|
||||
body.append(f' return _wrap_multi({{{out_dict}}}, idx, "{cat}", offset)')
|
||||
else:
|
||||
body.append(" return None # no output detected")
|
||||
|
||||
# Assemble
|
||||
sig = ", ".join(sig_params)
|
||||
|
||||
func = f'def {py_name}({sig}) -> object:\n'
|
||||
func += f' """{desc}."""\n'
|
||||
func += "\n".join(body) + "\n"
|
||||
|
||||
return func
|
||||
|
||||
|
||||
def generate_category_file(category: str, exports: list[dict]) -> str:
|
||||
"""Generate a full category module."""
|
||||
# Map category to Python module name
|
||||
mod_name = category.replace("-", "_")
|
||||
|
||||
header = f'"""quantalib {category} indicators.\n\nAuto-generated — DO NOT EDIT.\n"""\n'
|
||||
header += "from __future__ import annotations\n\n"
|
||||
header += "from ._helpers import _arr, _ptr, _out, _wrap, _wrap_multi, _check, _lib\n\n\n"
|
||||
|
||||
functions = []
|
||||
all_names = []
|
||||
|
||||
for exp in sorted(exports, key=lambda e: e["name"]):
|
||||
func = gen_wrapper(exp)
|
||||
if func:
|
||||
py_name = PY_NAME.get(exp["name"], exp["name"])
|
||||
all_names.append(py_name)
|
||||
functions.append(func)
|
||||
|
||||
# __all__
|
||||
all_str = "__all__ = [\n"
|
||||
for n in all_names:
|
||||
all_str += f' "{n}",\n'
|
||||
all_str += "]\n"
|
||||
|
||||
return header + all_str + "\n\n" + "\n\n".join(functions)
|
||||
|
||||
|
||||
def main():
|
||||
exports = parse_exports()
|
||||
|
||||
# Group by category
|
||||
by_cat: dict[str, list[dict]] = {}
|
||||
for exp in exports:
|
||||
cat = exp["category"]
|
||||
by_cat.setdefault(cat, []).append(exp)
|
||||
|
||||
print(f"Parsed {len(exports)} exports in {len(by_cat)} categories:")
|
||||
for cat, exps in sorted(by_cat.items()):
|
||||
print(f" {cat}: {len(exps)} indicators")
|
||||
|
||||
# Generate files
|
||||
for cat, exps in sorted(by_cat.items()):
|
||||
if cat == "uncategorized":
|
||||
continue
|
||||
mod_name = cat.replace("-", "_")
|
||||
# Map category dirs to Python module names
|
||||
py_mod = {
|
||||
"trends_FIR": "trends_fir",
|
||||
"trends_IIR": "trends_iir",
|
||||
}.get(mod_name, mod_name)
|
||||
|
||||
outpath = OUT_DIR / f"{py_mod}.py"
|
||||
content = generate_category_file(cat, exps)
|
||||
outpath.write_text(content, encoding="utf-8")
|
||||
print(f" Generated {outpath.name} ({len(exps)} indicators)")
|
||||
|
||||
# List uncategorized
|
||||
if "uncategorized" in by_cat:
|
||||
print(f"\n UNCATEGORIZED: {[e['name'] for e in by_cat['uncategorized']]}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user