YOUSEFUL / DELPHI / COMPONENTS

TAtlasIndicators

Technical indicators over an array of values: SMA, EMA, Bollinger bands, RSI and MACD.

Class Unit Atlas.FinIndicators · Inherits TObject · Product Atlas Fin

Description

Static class functions; never create an instance. Each result is as long as the input and holds NaN wherever the indicator is not yet defined, so index I of a result belongs to bar I. Pass TAtlasBarSeries.Closes, or any other array. The chart's studies call these same functions.

Every period must be 1..100000; otherwise EAtlasFinError is raised. A period longer than the input gives an all-NaN result, and an empty input an empty one. A NaN inside the input makes the windows that contain it NaN (and every later EMA value). The functions share no state, so they can run on any thread.

Only these five indicators exist. Stochastics, ATR, ADX, Ichimoku, VWAP and user-defined studies are not implemented.

Members

MemberKindWhat it does
SMAmethodThe simple moving average: the mean of the last Period values, defined from index Period - 1.
EMAmethodThe exponential moving average with factor 2/(Period+1).
BollingermethodBollinger bands: Middle is the SMA, Upper and Lower add and subtract Deviations population standard deviations (divided by Period, not Period - 1) of the same window.
RSImethodWilder's relative strength index, 0..100.
MACDmethodMoving average convergence/divergence.

Methods

SMA method

class function SMA(const Values: TArray<Double>; Period: Integer): TArray<Double>; static;

The simple moving average: the mean of the last Period values, defined from index Period - 1. Each window is summed afresh, so long series do not drift.

pascal
var V: TArray<Double>;
V := TAtlasIndicators.SMA([1, 2, 3, 4, 5], 3);   // NaN, NaN, 2, 3, 4

EMA method

class function EMA(const Values: TArray<Double>; Period: Integer): TArray<Double>; static;

The exponential moving average with factor 2/(Period+1). It starts at index Period - 1 with the SMA of the first Period values; leading NaN values in the input are skipped before counting.

pascal
var V: TArray<Double>;
V := TAtlasIndicators.EMA([10, 10, 10, 20], 3);   // NaN, NaN, 10, 15

Bollinger method

class function Bollinger(const Values: TArray<Double>; Period: Integer; const Deviations: Double): TAtlasBands; static;

Bollinger bands: Middle is the SMA, Upper and Lower add and subtract Deviations population standard deviations (divided by Period, not Period - 1) of the same window. Defined from index Period - 1. Deviations must be 0..100; NaN or a value outside raises EAtlasFinError.

pascal
var Bands: TAtlasBands;
Bands := TAtlasIndicators.Bollinger([2, 4, 4, 4, 5, 5, 7, 9], 8, 2);   // Middle[7] = 5, Upper[7] = 9, Lower[7] = 1

RSI method

class function RSI(const Values: TArray<Double>; Period: Integer): TArray<Double>; static;

Wilder's relative strength index, 0..100. The average gain and loss start as plain means of the first Period changes and are then smoothed by Wilder's rule. The first value is at index Period; an input no longer than Period gives no value. Without losses the index is 100, and without any movement 50.

pascal
var V: TArray<Double>;
V := TAtlasIndicators.RSI([10, 11, 10, 11], 2);   // NaN, NaN, 50, 75

MACD method

class function MACD(const Values: TArray<Double>; Fast, Slow, Signal: Integer): TAtlasMacd; static;

Moving average convergence/divergence. Line is EMA(Fast) minus EMA(Slow), defined from index Slow - 1; Signal is the EMA(Signal) of the defined part of the line, from index Slow + Signal - 2; Histogram is the line minus the signal. Raises EAtlasFinError when Fast is not below Slow.

pascal
var M: TAtlasMacd;
M := TAtlasIndicators.MACD(Data.Closes, 12, 26, 9);   // M.Signal[33] is the first signal value

Examples

Signals without a chart

Reports the bars where the MACD histogram turns positive, with the RSI at that bar. The functions need no chart and no window.

pascal
uses System.SysUtils, System.Math, Atlas.FinData, Atlas.FinIndicators;

procedure PrintMacdCrossings(Bars: TAtlasBarSeries);
var
  Closes, Rsi: TArray<Double>;
  Macd: TAtlasMacd;
  I: Integer;
begin
  Closes := Bars.Closes;
  Rsi := TAtlasIndicators.RSI(Closes, 14);
  Macd := TAtlasIndicators.MACD(Closes, 12, 26, 9);
  for I := 1 to High(Closes) do
    if not IsNan(Macd.Histogram[I - 1]) and (Macd.Histogram[I - 1] < 0) and (Macd.Histogram[I] >= 0) then
      Writeln(DateToStr(Bars[I].Time), ': MACD above its signal, RSI ', FormatFloat('0.0', Rsi[I]));
end;

TAtlasBands · TAtlasMacd · TAtlasFinStudy · TAtlasBarSeries

Also in Atlas Fin

TAtlasFinChart