@extasyio/indicators
Version:
Streaming technical indicators for extasy-trading-core-libs
138 lines (128 loc) • 3.77 kB
TypeScript
import { MarketTick } from '@extasyio/market-models';
/** Return type of `update`: either a new indicator value or `null` if not enough data yet. */
type Maybe<T> = T | null;
/**
* Streaming indicator interface.
*
* @template TIn Type of the input value (e.g. `number` or `Candle`)
* @template TOut Type of the calculated result (usually `number`)
*/
interface Indicator<TIn, TOut> {
/**
* Feed a new data point and get the current indicator value.
* Returns `null` until the indicator is ready.
*/
update(value: TIn): Maybe<TOut>;
/** Fully reset the internal state. */
reset(): void;
}
/**
* Fixed-size ring buffer — minimal implementation
* used by moving-average indicators. No dynamic array resizing.
*/
declare class RingBuffer {
readonly size: number;
private readonly data;
private index;
private filled;
constructor(size: number);
/**
* Push a value into the buffer.
* @returns overwritten element once the buffer is full, otherwise `null`
*/
push(value: number): number | null;
/** Iterate over currently stored elements. */
forEach(cb: (v: number) => void): void;
/** Current number of elements in the buffer. */
length(): number;
/** Clear buffer contents. */
reset(): void;
}
/**
* Simple Moving Average.
* Keeps a running sum to avoid O(n) recalculation.
*/
declare class SMA implements Indicator<number, number> {
private readonly period;
private readonly buf;
private sum;
constructor(period: number);
update(value: number): Maybe<number>;
reset(): void;
}
/**
* Exponential Moving Average with SMA bootstrap.
* First `period` input values form a simple average; afterwards the
* classic EMA recursion is applied.
*/
declare class EMA implements Indicator<number, number> {
private readonly period;
private readonly alpha;
private ema;
private sum;
private counter;
constructor(period: number);
update(value: number): Maybe<number>;
reset(): void;
}
/**
* Weighted Moving Average (linear weights 1..period).
* The most recent value receives the highest weight.
*/
declare class WMA implements Indicator<number, number> {
private readonly period;
private readonly buf;
private readonly weightSum;
constructor(period: number);
update(value: number): Maybe<number>;
reset(): void;
}
/**
* Relative Strength Index (Wilder, default period = 14).
* Returns value 0..100. Flat market → 50.
*/
declare class RSI implements Indicator<number, number> {
private readonly period;
private avgGain;
private avgLoss;
private prev;
private counter;
constructor(period?: number);
update(value: number): Maybe<number>;
reset(): void;
}
interface BollingerBands {
middle: number;
upper: number;
lower: number;
}
/**
* Bollinger Bands: middle SMA ± k × σ.
* Uses Welford's online algorithm for variance.
*/
declare class Bollinger implements Indicator<number, BollingerBands> {
private readonly period;
private readonly k;
private readonly buf;
private mean;
private m2;
private counter;
constructor(period?: number, k?: number);
update(value: number): Maybe<BollingerBands>;
reset(): void;
}
/**
* Average True Range (volatility indicator).
* Input: MarketTick (OHLCV). Period default = 14.
*/
declare class ATR implements Indicator<MarketTick, number> {
private readonly period;
private prevClose;
private atr;
private sumTR;
private counter;
constructor(period?: number);
update(c: MarketTick): Maybe<number>;
reset(): void;
}
export { ATR, Bollinger, type BollingerBands, EMA, type Indicator, type Maybe, RSI, RingBuffer, SMA, WMA };