From 4ab3a7fb53d6c0a36d2dbfdcf96cfc1741ab93c2 Mon Sep 17 00:00:00 2001 From: Miha Kralj Date: Fri, 27 Feb 2026 07:48:12 -0800 Subject: [PATCH] doc headers --- lib/channels/abber/abber.md | 17 +++++ lib/channels/accbands/accbands.md | 17 +++++ lib/channels/apchannel/apchannel.md | 17 +++++ lib/channels/apz/apz.md | 17 +++++ lib/channels/atrbands/atrbands.md | 17 +++++ lib/channels/bbands/bbands.md | 17 +++++ lib/channels/dchannel/dchannel.md | 17 +++++ lib/channels/decaychannel/decaychannel.md | 17 +++++ lib/channels/fcb/fcb.md | 17 +++++ lib/channels/jbands/jbands.md | 17 +++++ lib/channels/kchannel/kchannel.md | 17 +++++ lib/channels/maenv/maenv.md | 17 +++++ lib/channels/mmchannel/mmchannel.md | 17 +++++ lib/channels/pchannel/pchannel.md | 17 +++++ lib/channels/regchannel/regchannel.md | 17 +++++ lib/channels/sdchannel/sdchannel.md | 17 +++++ lib/channels/starchannel/starchannel.md | 17 +++++ lib/channels/stbands/stbands.md | 17 +++++ lib/channels/ttm_lrc/TtmLrc.md | 17 +++++ lib/channels/ubands/ubands.md | 17 +++++ lib/channels/uchannel/uchannel.md | 17 +++++ lib/channels/vwapbands/vwapbands.md | 17 +++++ lib/channels/vwapsd/vwapsd.md | 17 +++++ lib/core/avgprice/Avgprice.md | 17 +++++ lib/core/ha/Ha.md | 17 +++++ lib/core/medprice/Medprice.md | 17 +++++ lib/core/midpoint/Midpoint.md | 17 +++++ lib/core/midprice/Midprice.md | 17 +++++ lib/core/simd/SimdExtensions.md | 17 +++++ lib/core/tbar/TBar.md | 17 +++++ lib/core/tbarseries/TBarSeries.md | 17 +++++ lib/core/tseries/TSeries.md | 17 +++++ lib/core/tvalue/TValue.md | 17 +++++ lib/core/typprice/Typprice.md | 17 +++++ lib/core/wclprice/Wclprice.md | 17 +++++ lib/cycles/ccor/Ccor.md | 17 +++++ lib/cycles/ccyc/Ccyc.Validation.Tests.cs | 4 +- lib/cycles/ccyc/Ccyc.md | 17 +++++ lib/cycles/cg/cg.md | 17 +++++ lib/cycles/dsp/dsp.md | 17 +++++ lib/cycles/eacp/eacp.md | 17 +++++ lib/cycles/ebsw/ebsw.md | 17 +++++ lib/cycles/homod/homod.md | 17 +++++ lib/cycles/ht_dcperiod/HtDcperiod.md | 17 +++++ lib/cycles/ht_dcphase/HtDcphase.md | 17 +++++ lib/cycles/ht_phasor/HtPhasor.md | 17 +++++ lib/cycles/ht_sine/HtSine.md | 17 +++++ lib/cycles/lunar/Lunar.md | 17 +++++ lib/cycles/solar/Solar.md | 17 +++++ lib/cycles/ssfdsp/Ssfdsp.md | 17 +++++ lib/dynamics/adx/Adx.md | 19 ++++- lib/dynamics/adxr/Adxr.md | 19 ++++- lib/dynamics/alligator/Alligator.md | 19 ++++- lib/dynamics/amat/Amat.md | 19 ++++- lib/dynamics/aroon/Aroon.md | 19 ++++- lib/dynamics/aroonosc/AroonOsc.md | 19 ++++- lib/dynamics/chop/Chop.md | 19 ++++- lib/dynamics/dmx/Dmx.md | 19 ++++- lib/dynamics/dx/Dx.md | 19 ++++- lib/dynamics/ghla/Ghla.md | 17 +++++ lib/dynamics/ht_trendmode/HtTrendmode.md | 19 ++++- lib/dynamics/ichimoku/Ichimoku.md | 19 ++++- lib/dynamics/impulse/Impulse.md | 19 ++++- lib/dynamics/pfe/Pfe.md | 17 +++++ lib/dynamics/qstick/Qstick.md | 19 ++++- lib/dynamics/ravi/Ravi.md | 17 +++++ lib/dynamics/super/Super.md | 19 ++++- lib/dynamics/ttm_squeeze/TtmSqueeze.md | 19 ++++- lib/dynamics/ttm_trend/TtmTrend.md | 19 ++++- lib/dynamics/vhf/Vhf.md | 17 +++++ lib/dynamics/vortex/Vortex.md | 19 ++++- lib/errors/huber/Huber.md | 19 ++++- lib/errors/logcosh/LogCosh.md | 19 ++++- lib/errors/maape/Maape.md | 19 ++++- lib/errors/mae/Mae.md | 19 ++++- lib/errors/mapd/Mapd.md | 19 ++++- lib/errors/mape/Mape.md | 19 ++++- lib/errors/mase/Mase.md | 19 ++++- lib/errors/mdae/Mdae.md | 19 ++++- lib/errors/mdape/Mdape.md | 19 ++++- lib/errors/me/Me.md | 19 ++++- lib/errors/mpe/Mpe.md | 19 ++++- lib/errors/mrae/Mrae.md | 19 ++++- lib/errors/mse/Mse.md | 19 ++++- lib/errors/msle/Msle.md | 19 ++++- lib/errors/pseudohuber/PseudoHuber.md | 19 ++++- lib/errors/quantileloss/QuantileLoss.md | 19 ++++- lib/errors/rae/Rae.md | 19 ++++- lib/errors/rmse/Rmse.md | 19 ++++- lib/errors/rmsle/Rmsle.md | 19 ++++- lib/errors/rse/Rse.md | 19 ++++- lib/errors/rsquared/Rsquared.md | 19 ++++- lib/errors/smape/Smape.md | 19 ++++- lib/errors/theilu/TheilU.md | 19 ++++- lib/errors/tukeybiweight/TukeyBiweight.md | 19 ++++- lib/errors/wmape/Wmape.md | 19 ++++- lib/errors/wrmse/Wrmse.md | 19 ++++- lib/feeds/IFeed.md | 17 +++++ lib/feeds/csvfeed/CsvFeed.md | 17 +++++ lib/feeds/gbm/GBM.md | 17 +++++ lib/filters/agc/Agc.md | 19 ++++- lib/filters/alaguerre/ALaguerre.md | 21 +++++- lib/filters/baxterking/BaxterKing.md | 19 ++++- lib/filters/bessel/Bessel.md | 19 ++++- lib/filters/bilateral/Bilateral.md | 19 ++++- lib/filters/bpf/Bpf.md | 19 ++++- lib/filters/butter2/Butter2.md | 19 ++++- lib/filters/butter3/Butter3.md | 19 ++++- lib/filters/cfitz/Cfitz.md | 19 ++++- lib/filters/cheby1/Cheby1.md | 19 ++++- lib/filters/cheby2/Cheby2.md | 19 ++++- lib/filters/edcf/Edcf.md | 19 ++++- lib/filters/elliptic/Elliptic.md | 19 ++++- lib/filters/gauss/Gauss.md | 19 ++++- lib/filters/hann/Hann.md | 19 ++++- lib/filters/hp/Hp.md | 21 +++++- lib/filters/hpf/Hpf.md | 19 ++++- lib/filters/kalman/Kalman.md | 21 +++++- lib/filters/laguerre/Laguerre.md | 17 +++++ lib/filters/lms/Lms.md | 19 ++++- lib/filters/loess/Loess.md | 19 ++++- lib/filters/modf/Modf.md | 19 ++++- lib/filters/notch/Notch.md | 19 ++++- lib/filters/nw/Nw.md | 19 ++++- lib/filters/oneeuro/OneEuro.md | 19 ++++- lib/filters/rls/Rls.md | 17 +++++ lib/filters/rmed/Rmed.md | 19 ++++- lib/filters/roofing/Roofing.md | 19 ++++- lib/filters/sgf/Sgf.md | 19 ++++- lib/filters/spbf/Spbf.md | 19 ++++- lib/filters/ssf2/Ssf2.md | 19 ++++- lib/filters/ssf3/Ssf3.md | 19 ++++- lib/filters/usf/Usf.md | 19 ++++- lib/filters/voss/Voss.md | 19 ++++- lib/filters/wavelet/Wavelet.md | 17 +++++ lib/filters/wiener/Wiener.md | 19 ++++- lib/forecasts/afirma/Afirma.md | 19 ++++- lib/momentum/asi/Asi.md | 19 ++++- lib/momentum/bias/Bias.md | 17 +++++ lib/momentum/bop/Bop.md | 19 ++++- lib/momentum/cci/Cci.md | 19 ++++- lib/momentum/cfb/Cfb.md | 19 ++++- lib/momentum/cmo/Cmo.md | 19 ++++- lib/momentum/macd/Macd.md | 19 ++++- lib/momentum/mom/Mom.md | 17 +++++ lib/momentum/pmo/Pmo.md | 17 +++++ lib/momentum/ppo/Ppo.md | 17 +++++ lib/momentum/prs/Prs.md | 19 ++++- lib/momentum/roc/Roc.md | 17 +++++ lib/momentum/rocp/Rocp.md | 17 +++++ lib/momentum/rocr/Rocr.md | 17 +++++ lib/momentum/rsi/Rsi.md | 19 ++++- lib/momentum/rsx/Rsx.md | 19 ++++- lib/momentum/sam/Sam.md | 19 ++++- lib/momentum/tsi/Tsi.md | 19 ++++- lib/momentum/vel/Vel.md | 19 ++++- lib/numerics/accel/Accel.md | 17 +++++ lib/numerics/betadist/Betadist.md | 17 +++++ lib/numerics/binomdist/Binomdist.md | 17 +++++ lib/numerics/change/Change.md | 17 +++++ lib/numerics/cwt/Cwt.md | 17 +++++ lib/numerics/dwt/Dwt.md | 17 +++++ lib/numerics/expdist/Expdist.md | 17 +++++ lib/numerics/exptrans/Exptrans.md | 17 +++++ lib/numerics/fdist/Fdist.md | 17 +++++ lib/numerics/fft/Fft.md | 17 +++++ lib/numerics/gammadist/Gammadist.md | 17 +++++ lib/numerics/highest/Highest.md | 17 +++++ lib/numerics/ifft/Ifft.md | 17 +++++ lib/numerics/jerk/Jerk.md | 17 +++++ lib/numerics/lineartrans/Lineartrans.md | 17 +++++ lib/numerics/lognormdist/Lognormdist.md | 17 +++++ lib/numerics/logtrans/Logtrans.md | 17 +++++ lib/numerics/lowest/Lowest.md | 17 +++++ lib/numerics/normalize/Normalize.md | 17 +++++ lib/numerics/normdist/Normdist.md | 17 +++++ lib/numerics/poissondist/Poissondist.md | 17 +++++ lib/numerics/relu/Relu.md | 17 +++++ lib/numerics/sigmoid/Sigmoid.md | 17 +++++ lib/numerics/slope/Slope.md | 17 +++++ lib/numerics/sqrttrans/Sqrttrans.md | 19 ++++- lib/numerics/tdist/Tdist.md | 17 +++++ lib/numerics/weibulldist/Weibulldist.md | 17 +++++ lib/oscillators/bbi/Bbi.md | 19 ++++- lib/oscillators/brar/Brar.md | 17 +++++ lib/oscillators/coppock/Coppock.md | 19 ++++- lib/oscillators/crsi/Crsi.md | 19 ++++- lib/oscillators/cti/Cti.md | 19 ++++- lib/oscillators/deco/Deco.md | 19 ++++- lib/oscillators/dem/Dem.md | 19 ++++- lib/oscillators/dosc/Dosc.md | 19 ++++- lib/oscillators/dymoi/Dymoi.md | 19 ++++- lib/oscillators/er/Er.md | 2 + lib/oscillators/gator/Gator.md | 17 +++++ lib/oscillators/imi/Imi.md | 19 ++++- lib/oscillators/kst/Kst.md | 23 +++++- lib/oscillators/lrsi/Lrsi.md | 19 ++++- lib/oscillators/marketfi/Marketfi.md | 17 +++++ lib/oscillators/mstoch/Mstoch.md | 19 ++++- lib/oscillators/qqe/Qqe.md | 19 ++++- lib/oscillators/reflex/Reflex.md | 19 ++++- lib/oscillators/reverseema/ReverseEma.md | 17 +++++ lib/oscillators/rvgi/Rvgi.md | 19 ++++- lib/oscillators/squeeze/Squeeze.md | 19 ++++- lib/oscillators/stc/stc.md | 17 +++++ lib/oscillators/td_seq/Td_seq.md | 19 ++++- lib/oscillators/trendflex/Trendflex.md | 17 +++++ lib/reversals/chandelier/Chandelier.md | 17 +++++ lib/reversals/ckstop/Ckstop.md | 17 +++++ lib/reversals/fractals/Fractals.md | 17 +++++ lib/reversals/pivot/Pivot.Validation.Tests.cs | 21 ------ lib/reversals/pivot/Pivot.md | 17 +++++ .../pivotcam/Pivotcam.Validation.Tests.cs | 21 ------ lib/reversals/pivotcam/Pivotcam.md | 17 +++++ .../pivotdem/Pivotdem.Validation.Tests.cs | 21 ------ lib/reversals/pivotdem/Pivotdem.md | 17 +++++ lib/reversals/pivotext/Pivotext.md | 17 +++++ .../pivotfib/Pivotfib.Validation.Tests.cs | 22 ------ lib/reversals/pivotfib/Pivotfib.md | 17 +++++ .../pivotwood/Pivotwood.Validation.Tests.cs | 22 ------ lib/reversals/pivotwood/Pivotwood.md | 17 +++++ lib/reversals/psar/Psar.md | 17 +++++ lib/reversals/swings/Swings.md | 17 +++++ lib/reversals/ttm_scalper/TtmScalper.md | 19 ++++- lib/statistics/acf/Acf.Validation.Tests.cs | 10 +-- lib/statistics/acf/Acf.md | 19 ++++- lib/statistics/beta/Beta.md | 17 +++++ lib/statistics/cma/Cma.md | 17 +++++ .../cointegration/Cointegration.Tests.cs | 13 ++-- .../Cointegration.Validation.Tests.cs | 29 ++++---- lib/statistics/cointegration/Cointegration.md | 19 ++++- .../Correlation.Validation.Tests.cs | 12 ++-- lib/statistics/correlation/Correlation.md | 19 ++++- lib/statistics/covariance/Covariance.md | 17 +++++ lib/statistics/entropy/Entropy.md | 17 +++++ lib/statistics/geomean/Geomean.md | 17 +++++ .../granger/Granger.Validation.Tests.cs | 24 ++++--- lib/statistics/granger/Granger.md | 17 +++++ lib/statistics/harmean/Harmean.md | 17 +++++ .../hurst/Hurst.Validation.Tests.cs | 21 ------ lib/statistics/hurst/Hurst.md | 17 +++++ lib/statistics/iqr/Iqr.md | 17 +++++ lib/statistics/jb/Jb.md | 17 +++++ lib/statistics/kurtosis/Kurtosis.md | 17 +++++ lib/statistics/linreg/LinReg.md | 17 +++++ lib/statistics/meandev/MeanDev.md | 18 ++++- lib/statistics/median/Median.md | 17 +++++ lib/statistics/mode/Mode.md | 17 +++++ lib/statistics/pacf/Pacf.Validation.Tests.cs | 4 +- lib/statistics/pacf/Pacf.md | 19 ++++- lib/statistics/percentile/Percentile.md | 18 +++++ lib/statistics/polyfit/Polyfit.md | 17 +++++ lib/statistics/quantile/Quantile.md | 17 +++++ lib/statistics/skew/Skew.md | 17 +++++ lib/statistics/spearman/Spearman.md | 17 +++++ lib/statistics/stddev/StdDev.md | 17 +++++ .../stderr/Stderr.Validation.Tests.cs | 11 +-- lib/statistics/stderr/Stderr.md | 18 ++++- lib/statistics/sum/Sum.md | 17 +++++ lib/statistics/theil/Theil.md | 17 +++++ lib/statistics/trim/Trim.md | 17 +++++ lib/statistics/variance/Variance.md | 17 +++++ lib/statistics/wavg/Wavg.md | 17 +++++ lib/statistics/wins/Wins.md | 17 +++++ lib/statistics/zscore/Zscore.md | 17 +++++ lib/statistics/ztest/Ztest.md | 17 +++++ lib/trends_FIR/alma/Alma.md | 19 ++++- lib/trends_FIR/blma/Blma.md | 19 ++++- lib/trends_FIR/bwma/Bwma.md | 19 ++++- lib/trends_FIR/conv/Conv.md | 19 ++++- lib/trends_FIR/crma/Crma.md | 19 ++++- lib/trends_FIR/dwma/Dwma.md | 19 ++++- lib/trends_FIR/fwma/Fwma.md | 17 +++++ lib/trends_FIR/gwma/Gwma.md | 19 ++++- lib/trends_FIR/hamma/Hamma.md | 19 ++++- lib/trends_FIR/hanma/Hanma.md | 19 ++++- lib/trends_FIR/hend/Hend.md | 19 ++++- lib/trends_FIR/hma/Hma.md | 19 ++++- lib/trends_FIR/ilrs/Ilrs.md | 19 ++++- lib/trends_FIR/kaiser/Kaiser.md | 19 ++++- lib/trends_FIR/lanczos/Lanczos.md | 19 ++++- lib/trends_FIR/lsma/Lsma.md | 19 ++++- lib/trends_FIR/nlma/Nlma.md | 19 ++++- lib/trends_FIR/nyqma/Nyqma.md | 17 +++++ lib/trends_FIR/parzen/Parzen.md | 19 ++++- lib/trends_FIR/pma/Pma.md | 19 ++++- lib/trends_FIR/pwma/Pwma.md | 19 ++++- lib/trends_FIR/qrma/Qrma.md | 19 ++++- lib/trends_FIR/rain/Rain.md | 19 ++++- lib/trends_FIR/rwma/Rwma.md | 19 ++++- lib/trends_FIR/sgma/Sgma.md | 19 ++++- lib/trends_FIR/sinema/Sinema.md | 19 ++++- lib/trends_FIR/sma/Sma.md | 19 ++++- lib/trends_FIR/sp15/Sp15.md | 19 ++++- lib/trends_FIR/swma/Swma.md | 19 ++++- lib/trends_FIR/trima/Trima.md | 19 ++++- lib/trends_FIR/tsf/Tsf.md | 17 +++++ lib/trends_FIR/tukey_w/Tukey_w.md | 19 ++++- lib/trends_FIR/wma/Wma.md | 19 ++++- lib/trends_IIR/adxvma/Adxvma.md | 19 ++++- lib/trends_IIR/ahrens/Ahrens.md | 19 ++++- lib/trends_IIR/coral/Coral.md | 19 ++++- lib/trends_IIR/decycler/Decycler.md | 17 +++++ lib/trends_IIR/dema/Dema.md | 19 ++++- lib/trends_IIR/dsma/Dsma.md | 19 ++++- lib/trends_IIR/ema/Ema.md | 19 ++++- lib/trends_IIR/frama/Frama.md | 19 ++++- lib/trends_IIR/gdema/Gdema.md | 19 ++++- lib/trends_IIR/hema/Hema.md | 20 +++++- lib/trends_IIR/holt/Holt.md | 19 ++++- lib/trends_IIR/htit/Htit.md | 19 ++++- lib/trends_IIR/hwma/Hwma.md | 19 ++++- lib/trends_IIR/jma/Jma.md | 19 ++++- lib/trends_IIR/kama/Kama.md | 19 ++++- lib/trends_IIR/lema/Lema.md | 19 ++++- lib/trends_IIR/mama/Mama.md | 19 ++++- lib/trends_IIR/mavp/Mavp.md | 17 +++++ lib/trends_IIR/mcnma/Mcnma.md | 19 ++++- lib/trends_IIR/mgdi/Mgdi.md | 19 ++++- lib/trends_IIR/mma/Mma.md | 19 ++++- lib/trends_IIR/nma/Nma.md | 17 +++++ lib/trends_IIR/qema/Qema.md | 19 ++++- lib/trends_IIR/rema/Rema.md | 19 ++++- lib/trends_IIR/rgma/Rgma.md | 19 ++++- lib/trends_IIR/rma/Rma.md | 19 ++++- lib/trends_IIR/t3/T3.md | 19 ++++- lib/trends_IIR/tema/Tema.md | 19 ++++- lib/trends_IIR/trama/Trama.md | 17 +++++ lib/trends_IIR/vama/Vama.md | 19 ++++- lib/trends_IIR/vidya/Vidya.md | 19 ++++- lib/trends_IIR/yzvama/Yzvama.md | 19 ++++- lib/trends_IIR/zldema/Zldema.md | 22 +++++- lib/trends_IIR/zlema/Zlema.md | 22 +++++- lib/trends_IIR/zltema/Zltema.md | 22 +++++- lib/volatility/adr/Adr.md | 19 ++++- lib/volatility/atr/Atr.md | 19 ++++- lib/volatility/atrn/Atrn.md | 19 ++++- lib/volatility/bbw/Bbw.md | 19 ++++- lib/volatility/bbwn/Bbwn.md | 17 +++++ lib/volatility/bbwp/Bbwp.md | 19 ++++- lib/volatility/ccv/Ccv.md | 19 ++++- lib/volatility/cv/Cv.md | 19 ++++- lib/volatility/cvi/Cvi.md | 19 ++++- lib/volatility/etherm/Etherm.md | 17 +++++ lib/volatility/ewma/Ewma.md | 19 ++++- lib/volatility/gkv/Gkv.md | 19 ++++- lib/volatility/hlv/Hlv.md | 22 +++++- lib/volatility/hv/Hv.md | 19 ++++- lib/volatility/jvolty/Jvolty.md | 19 ++++- lib/volatility/jvoltyn/Jvoltyn.md | 19 ++++- lib/volatility/massi/Massi.md | 19 ++++- lib/volatility/natr/Natr.md | 19 ++++- lib/volatility/rsv/Rsv.md | 19 ++++- lib/volatility/rv/Rv.md | 19 ++++- lib/volatility/rvi/Rvi.md | 19 ++++- lib/volatility/tr/Tr.md | 19 ++++- lib/volatility/ui/Ui.md | 19 ++++- lib/volatility/vov/Vov.md | 19 ++++- lib/volatility/vr/Vr.md | 19 ++++- lib/volatility/yzv/Yzv.md | 19 ++++- lib/volume/adl/Adl.md | 17 +++++ lib/volume/adosc/Adosc.md | 17 +++++ lib/volume/aobv/Aobv.md | 17 +++++ lib/volume/cmf/Cmf.md | 17 +++++ lib/volume/efi/Efi.md | 19 ++++- lib/volume/eom/Eom.md | 19 ++++- lib/volume/evwma/Evwma.md | 17 +++++ lib/volume/iii/Iii.md | 19 ++++- lib/volume/kvo/Kvo.md | 19 ++++- lib/volume/mfi/Mfi.md | 19 ++++- lib/volume/nvi/Nvi.md | 19 ++++- lib/volume/obv/Obv.md | 19 ++++- lib/volume/pvd/Pvd.md | 19 ++++- lib/volume/pvi/Pvi.md | 19 ++++- lib/volume/pvo/Pvo.md | 19 ++++- lib/volume/pvr/Pvr.md | 19 ++++- lib/volume/pvt/Pvt.md | 19 ++++- lib/volume/tvi/Tvi.md | 19 ++++- lib/volume/twap/Twap.md | 19 ++++- lib/volume/va/Va.md | 19 ++++- lib/volume/vf/Vf.md | 19 ++++- lib/volume/vo/Vo.md | 19 ++++- lib/volume/vroc/Vroc.md | 19 ++++- lib/volume/vwad/Vwad.md | 19 ++++- lib/volume/vwap/Vwap.md | 19 ++++- lib/volume/vwma/Vwma.md | 19 ++++- lib/volume/wad/Wad.md | 19 ++++- ndepend/generate-badges.ps1 | 53 +++++++------- ndepend/ndepend.ps1 | 72 +++++++++++-------- 389 files changed, 6682 insertions(+), 468 deletions(-) diff --git a/lib/channels/abber/abber.md b/lib/channels/abber/abber.md index a83e7262..bfe75950 100644 --- a/lib/channels/abber/abber.md +++ b/lib/channels/abber/abber.md @@ -1,5 +1,22 @@ # ABBER: Aberration Bands +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Channel | +| **Inputs** | Source (close) | +| **Parameters** | `period`, `multiplier` (default 2.0) | +| **Outputs** | Multiple series (Upper, Lower) | +| **Output range** | Tracks input | +| **Warmup** | `period` bars | + +### TL;DR + +- ABBER measures price deviation from a central moving average using mean absolute deviation rather than standard deviation, producing dynamic bands ... +- Parameterized by `period`, `multiplier` (default 2.0). +- Output range: Tracks input. +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + ABBER measures price deviation from a central moving average using mean absolute deviation rather than standard deviation, producing dynamic bands that adapt to volatility while remaining robust against extreme outliers. Where Bollinger Bands amplify outliers through squaring (the $L^2$ norm), ABBER uses raw absolute differences (the $L^1$ norm), so bands respond to typical price behavior rather than the occasional spike that yanks everything sideways. For a 20-period window with a 2.0 multiplier, ABBER contains approximately 89% of normally-distributed price action, but its real advantage emerges with fat-tailed distributions where standard deviation overreacts to single-bar anomalies. ## Historical Context diff --git a/lib/channels/accbands/accbands.md b/lib/channels/accbands/accbands.md index dabd7e78..164fad74 100644 --- a/lib/channels/accbands/accbands.md +++ b/lib/channels/accbands/accbands.md @@ -1,5 +1,22 @@ # ACCBANDS: Acceleration Bands +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Channel | +| **Inputs** | OHLCV bar (TBar) | +| **Parameters** | `period`, `factor` (default 4.0) | +| **Outputs** | Multiple series (Upper, Lower) | +| **Output range** | Tracks input | +| **Warmup** | `period` bars | + +### TL;DR + +- Acceleration Bands construct a volatility envelope using the intra-bar high-low range rather than close-to-close standard deviation, creating chann... +- Parameterized by `period`, `factor` (default 4.0). +- Output range: Tracks input. +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + Acceleration Bands construct a volatility envelope using the intra-bar high-low range rather than close-to-close standard deviation, creating channels that accommodate the full price excursion of the underlying asset. Each bar's contribution to band width is normalized by price level ($w = (H-L)/(H+L)$), making the bands scale-invariant across instruments. Three independent Simple Moving Averages of the adjusted high, adjusted low, and close prices form the upper, lower, and middle bands respectively. Headley's original breakout rule declares a trend when price closes outside the bands for two consecutive bars. ## Historical Context diff --git a/lib/channels/apchannel/apchannel.md b/lib/channels/apchannel/apchannel.md index 9ca9e542..4886da06 100644 --- a/lib/channels/apchannel/apchannel.md +++ b/lib/channels/apchannel/apchannel.md @@ -1,5 +1,22 @@ # APCHANNEL: Adaptive Price Channel +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Channel | +| **Inputs** | OHLCV bar (TBar) | +| **Parameters** | None | +| **Outputs** | Single series (Apchannel) | +| **Output range** | Tracks input | +| **Warmup** | 1 bar | + +### TL;DR + +- APCHANNEL applies exponential smoothing independently to price highs and lows, creating a dynamic envelope that "remembers" significant extremes wh... +- No configurable parameters; computation is stateless per bar. +- Output range: Tracks input. +- Requires 1 bar of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + APCHANNEL applies exponential smoothing independently to price highs and lows, creating a dynamic envelope that "remembers" significant extremes while gradually fading their influence over time. Unlike rigid Donchian channels that drop price extremes abruptly when they exit the lookback window (the "cliff effect"), APCHANNEL decays them smoothly through leaky integration. The result is a channel with continuously sloping boundaries that responds to volatility without the discontinuous jumps that plague fixed-window approaches. The algorithm is $O(1)$ per bar with only two state variables and no buffers. ## Historical Context diff --git a/lib/channels/apz/apz.md b/lib/channels/apz/apz.md index 8948c39b..b1b5505d 100644 --- a/lib/channels/apz/apz.md +++ b/lib/channels/apz/apz.md @@ -1,5 +1,22 @@ # APZ: Adaptive Price Zone +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Channel | +| **Inputs** | OHLCV bar (TBar) | +| **Parameters** | `period`, `multiplier` (default 2.0) | +| **Outputs** | Multiple series (Upper, Lower) | +| **Output range** | Tracks input | +| **Warmup** | `period` bars | + +### TL;DR + +- APZ constructs a volatility-adaptive envelope using double-smoothed exponential moving averages with an aggressive smoothing factor derived from $\... +- Parameterized by `period`, `multiplier` (default 2.0). +- Output range: Tracks input. +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + APZ constructs a volatility-adaptive envelope using double-smoothed exponential moving averages with an aggressive smoothing factor derived from $\sqrt{\text{period}}$, making it significantly faster than standard EMA-based channels. The center line is a double-EMA of price; the band width is a double-EMA of the high-low range, scaled by a multiplier. Designed specifically for mean-reversion trading in non-trending markets, APZ identifies overbought/oversold extremes where price is likely to reverse rather than continue. A closing price outside the zone signals an immediate overshoot, not a breakout. ## Historical Context diff --git a/lib/channels/atrbands/atrbands.md b/lib/channels/atrbands/atrbands.md index fb0559c0..15337a0c 100644 --- a/lib/channels/atrbands/atrbands.md +++ b/lib/channels/atrbands/atrbands.md @@ -1,5 +1,22 @@ # ATRBANDS: Average True Range Bands +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Channel | +| **Inputs** | OHLCV bar (TBar) | +| **Parameters** | `period`, `multiplier` (default 2.0) | +| **Outputs** | Multiple series (Upper, Lower) | +| **Output range** | Tracks input | +| **Warmup** | `period` bars | + +### TL;DR + +- ATR Bands create a volatility-adaptive envelope by projecting Wilder's Average True Range above and below a central Simple Moving Average. +- Parameterized by `period`, `multiplier` (default 2.0). +- Output range: Tracks input. +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + ATR Bands create a volatility-adaptive envelope by projecting Wilder's Average True Range above and below a central Simple Moving Average. Unlike fixed-percentage envelopes or standard-deviation bands, ATR Bands use True Range to measure volatility, making them robust for assets with gaps, pre-market moves, and 24/7 trading where the "hidden" volatility between bars is significant. The True Range captures the maximum of intra-bar range, gap-up distance, and gap-down distance, ensuring that overnight gaps contribute fully to band width even when the current bar's open-to-close range is narrow. ## Historical Context diff --git a/lib/channels/bbands/bbands.md b/lib/channels/bbands/bbands.md index a990e06d..04ea8b96 100644 --- a/lib/channels/bbands/bbands.md +++ b/lib/channels/bbands/bbands.md @@ -1,5 +1,22 @@ # BBANDS: Bollinger Bands +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Channel | +| **Inputs** | Source (close) | +| **Parameters** | `period` (default DefaultPeriod), `multiplier` (default DefaultMultiplier) | +| **Outputs** | Multiple series (Middle, Upper, Lower, Width, PercentB) | +| **Output range** | Tracks input | +| **Warmup** | `period` bars | + +### TL;DR + +- Bollinger Bands construct a volatility-adaptive envelope around a Simple Moving Average using population standard deviation as the width measure. +- Parameterized by `period` (default defaultperiod), `multiplier` (default defaultmultiplier). +- Output range: Tracks input. +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + Bollinger Bands construct a volatility-adaptive envelope around a Simple Moving Average using population standard deviation as the width measure. The bands expand during high-volatility periods and contract during consolidation, dynamically adapting to changing market conditions. Under Gaussian assumptions, $\pm 2\sigma$ contains approximately 95.4% of price action, but financial returns exhibit fat tails and volatility clustering, so the bands function more as a volatility-normalized reference frame than a strict probability envelope. The derived metrics %B (price position as a fraction of band width) and BandWidth (normalized band spread) extend the raw bands into a complete analytical toolkit. ## Historical Context diff --git a/lib/channels/dchannel/dchannel.md b/lib/channels/dchannel/dchannel.md index 02806fe7..b6a57f43 100644 --- a/lib/channels/dchannel/dchannel.md +++ b/lib/channels/dchannel/dchannel.md @@ -1,5 +1,22 @@ # DCHANNEL: Donchian Channels +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Channel | +| **Inputs** | OHLCV bar (TBar) | +| **Parameters** | `period` | +| **Outputs** | Multiple series (Upper, Lower) | +| **Output range** | Tracks input | +| **Warmup** | `period` bars | + +### TL;DR + +- Donchian Channels track the highest high and lowest low over a fixed lookback period, defining the absolute price boundaries within which an asset ... +- Parameterized by `period`. +- Output range: Tracks input. +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + Donchian Channels track the highest high and lowest low over a fixed lookback period, defining the absolute price boundaries within which an asset has traded. Unlike volatility-based bands that compute statistical dispersion, Donchian Channels represent actual historical extremes — the literal "price box." The implementation uses monotonic deques for $O(1)$ amortized sliding-window max/min, ensuring that computing a 500-period channel costs no more than a 20-period one. The midpoint of the upper and lower bands serves as a simple trend bias indicator. ## Historical Context diff --git a/lib/channels/decaychannel/decaychannel.md b/lib/channels/decaychannel/decaychannel.md index 8041d9f3..64088016 100644 --- a/lib/channels/decaychannel/decaychannel.md +++ b/lib/channels/decaychannel/decaychannel.md @@ -1,5 +1,22 @@ # DECAYCHANNEL: Decay Min-Max Channel +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Channel | +| **Inputs** | OHLCV bar (TBar) | +| **Parameters** | `period` | +| **Outputs** | Multiple series (Upper, Lower) | +| **Output range** | Tracks input | +| **Warmup** | `period` bars | + +### TL;DR + +- Decay Channel combines the absolute price boundaries of Donchian Channels with exponential decay toward the midpoint, creating an envelope that exp... +- Parameterized by `period`. +- Output range: Tracks input. +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + Decay Channel combines the absolute price boundaries of Donchian Channels with exponential decay toward the midpoint, creating an envelope that expands instantly on new volatility but contracts smoothly during consolidation. While Donchian Channels hold their width until an extreme exits the lookback window, Decay Channel allows the bands to "forget" old extremes over time using a half-life model. The period parameter serves as the half-life: after that many bars without a new extreme, the band has decayed 50% of the distance back toward center. The decayed values are always clamped within Donchian bounds, ensuring they never extrapolate beyond actual price history. ## Historical Context diff --git a/lib/channels/fcb/fcb.md b/lib/channels/fcb/fcb.md index 1e0df65f..140a8d11 100644 --- a/lib/channels/fcb/fcb.md +++ b/lib/channels/fcb/fcb.md @@ -1,5 +1,22 @@ # FCB: Fractal Chaos Bands +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Channel | +| **Inputs** | OHLCV bar (TBar) | +| **Parameters** | `period` (default 20) | +| **Outputs** | Multiple series (Upper, Lower) | +| **Output range** | Tracks input | +| **Warmup** | `period + 2` bars | + +### TL;DR + +- Fractal Chaos Bands filter raw price action through Bill Williams' fractal detection logic, tracking the highest confirmed fractal high and lowest ... +- Parameterized by `period` (default 20). +- Output range: Tracks input. +- Requires `period + 2` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + Fractal Chaos Bands filter raw price action through Bill Williams' fractal detection logic, tracking the highest confirmed fractal high and lowest confirmed fractal low over a lookback period. Unlike Donchian Channels which use every bar's high and low, FCB uses only structurally significant turning points — bars where the middle element of a 3-bar pattern is a local extremum. The result is a "cleaner" channel that ignores transient spikes and focuses on confirmed support and resistance levels. The bands tend to remain flat during trends and step discretely when new structural pivots form, making them useful for identifying genuine breakouts versus noise. ## Historical Context diff --git a/lib/channels/jbands/jbands.md b/lib/channels/jbands/jbands.md index 27cd4c1f..c72e18e3 100644 --- a/lib/channels/jbands/jbands.md +++ b/lib/channels/jbands/jbands.md @@ -1,5 +1,22 @@ # JBANDS: Jurik Adaptive Envelope Bands +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Channel | +| **Inputs** | Source (close) | +| **Parameters** | `period`, `phase` (default 0) | +| **Outputs** | Multiple series (Upper, Lower) | +| **Output range** | Tracks input | +| **Warmup** | 1 bar | + +### TL;DR + +- JBANDS expose the internal adaptive envelope mechanism of the Jurik Moving Average (JMA), producing asymmetric bands that snap instantly to new pri... +- Parameterized by `period`, `phase` (default 0). +- Output range: Tracks input. +- Requires 1 bar of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + JBANDS expose the internal adaptive envelope mechanism of the Jurik Moving Average (JMA), producing asymmetric bands that snap instantly to new price extremes and decay exponentially during consolidation. Unlike standard volatility bands (Bollinger, Keltner) which maintain symmetric width around a center line, JBANDS feature "snap-and-decay" hysteresis: expansion is instantaneous (plasticity), contraction is gradual (elasticity). The decay rate is dynamically modulated by a two-stage volatility estimator — a 10-bar SMA feeding a 128-bar trimmed mean — making the bands tight during quiet markets and expansive during trends. The center line is the full JMA: a 2-pole IIR filter with phase control and adaptive alpha. ## Historical Context diff --git a/lib/channels/kchannel/kchannel.md b/lib/channels/kchannel/kchannel.md index 2b6fa278..ec24fe31 100644 --- a/lib/channels/kchannel/kchannel.md +++ b/lib/channels/kchannel/kchannel.md @@ -1,5 +1,22 @@ # KCHANNEL: Keltner Channel +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Channel | +| **Inputs** | OHLCV bar (TBar) | +| **Parameters** | `period` (default 20), `multiplier` (default 2.0) | +| **Outputs** | Multiple series (Upper, Lower) | +| **Output range** | Tracks input | +| **Warmup** | `period * 2` bars | + +### TL;DR + +- Keltner Channel constructs a volatility-adaptive envelope by projecting Average True Range above and below an Exponential Moving Average center line. +- Parameterized by `period` (default 20), `multiplier` (default 2.0). +- Output range: Tracks input. +- Requires `period * 2` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + Keltner Channel constructs a volatility-adaptive envelope by projecting Average True Range above and below an Exponential Moving Average center line. The channel differs from ATR Bands solely in the center line: Keltner uses EMA (faster, more responsive) while ATR Bands use SMA (more stable, more lag). The EMA center combined with ATR width creates a channel that both tracks trend and adapts to volatility, making it one of the most widely used channel indicators for trend-following and mean-reversion strategies. The implementation uses EMA with warmup compensation for accurate early values and Wilder's smoothing (RMA) for ATR. ## Historical Context diff --git a/lib/channels/maenv/maenv.md b/lib/channels/maenv/maenv.md index 9ac11170..a5a021b2 100644 --- a/lib/channels/maenv/maenv.md +++ b/lib/channels/maenv/maenv.md @@ -1,5 +1,22 @@ # MAENV: Moving Average Envelope +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Channel | +| **Inputs** | Source (close) | +| **Parameters** | `period` (default 20), `percentage` (default 1.0), `maType` (default MaenvType.EMA) | +| **Outputs** | Multiple series (Upper, Lower) | +| **Output range** | Tracks input | +| **Warmup** | `period` bars | + +### TL;DR + +- Moving Average Envelope (MA Envelope) constructs symmetric bands at a fixed percentage distance above and below a moving average center line. +- Parameterized by `period` (default 20), `percentage` (default 1.0), `matype` (default maenvtype.ema). +- Output range: Tracks input. +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + Moving Average Envelope (MA Envelope) constructs symmetric bands at a fixed percentage distance above and below a moving average center line. Unlike volatility-adaptive channels (Bollinger, Keltner, ATR Bands) where band width varies with market conditions, MA Envelope uses a constant percentage offset, creating bands whose absolute width scales only with price level. The indicator supports configurable moving average types (SMA, EMA, WMA) for the center line, allowing users to trade off between lag, smoothness, and responsiveness. ## Historical Context diff --git a/lib/channels/mmchannel/mmchannel.md b/lib/channels/mmchannel/mmchannel.md index fe12d138..68361dc6 100644 --- a/lib/channels/mmchannel/mmchannel.md +++ b/lib/channels/mmchannel/mmchannel.md @@ -1,5 +1,22 @@ # MMCHANNEL: Min-Max Channel +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Channel | +| **Inputs** | OHLCV bar (TBar) | +| **Parameters** | `period` | +| **Outputs** | Multiple series (Upper, Lower) | +| **Output range** | Tracks input | +| **Warmup** | `period` bars | + +### TL;DR + +- Min-Max Channel tracks the highest high and lowest low over a lookback period, creating a pure price envelope without any midpoint calculation. +- Parameterized by `period`. +- Output range: Tracks input. +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + Min-Max Channel tracks the highest high and lowest low over a lookback period, creating a pure price envelope without any midpoint calculation. Unlike Donchian Channels which include a middle band, MMCHANNEL delivers only the raw extremes. The implementation uses monotonic deques for O(1) amortized updates: each element enters the deque once and leaves at most once, so total work over $N$ bars is $O(N)$ regardless of period length. ## Historical Context diff --git a/lib/channels/pchannel/pchannel.md b/lib/channels/pchannel/pchannel.md index 6f84429c..ad193ea5 100644 --- a/lib/channels/pchannel/pchannel.md +++ b/lib/channels/pchannel/pchannel.md @@ -1,5 +1,22 @@ # PCHANNEL: Price Channel +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Channel | +| **Inputs** | OHLCV bar (TBar) | +| **Parameters** | `period` | +| **Outputs** | Multiple series (Upper, Lower) | +| **Output range** | Tracks input | +| **Warmup** | `period` bars | + +### TL;DR + +- Price Channel tracks the highest high and lowest low over a lookback period with a midpoint average, creating a three-line price envelope that defi... +- Parameterized by `period`. +- Output range: Tracks input. +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + Price Channel tracks the highest high and lowest low over a lookback period with a midpoint average, creating a three-line price envelope that defines where the market has been. Functionally identical to Donchian Channels, the indicator uses actual price extremes rather than volatility estimates, producing bands that represent real support and resistance levels. This implementation uses monotonic deques for O(1) amortized updates instead of the naive O(n) rescan that most platforms use internally. ## Historical Context diff --git a/lib/channels/regchannel/regchannel.md b/lib/channels/regchannel/regchannel.md index 9066512b..bea236ad 100644 --- a/lib/channels/regchannel/regchannel.md +++ b/lib/channels/regchannel/regchannel.md @@ -1,5 +1,22 @@ # REGCHANNEL: Linear Regression Channel +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Channel | +| **Inputs** | Source (close) | +| **Parameters** | `period` (default 20), `multiplier` (default 2.0) | +| **Outputs** | Multiple series (Upper, Lower) | +| **Output range** | Tracks input | +| **Warmup** | `period` bars | + +### TL;DR + +- Linear Regression Channel plots a best-fit line through price data over a specified period with parallel bands at a configurable standard deviation... +- Parameterized by `period` (default 20), `multiplier` (default 2.0). +- Output range: Tracks input. +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + Linear Regression Channel plots a best-fit line through price data over a specified period with parallel bands at a configurable standard deviation of residuals. Unlike moving average envelopes that offset from a smoothed price, regression channels adapt their slope to the underlying trend and their width to actual dispersion around that trend. The algorithm uses ordinary least squares with precomputed index sums, requiring two passes per bar: one for the regression coefficients and one for the residual standard deviation. ## Historical Context diff --git a/lib/channels/sdchannel/sdchannel.md b/lib/channels/sdchannel/sdchannel.md index cbfb957b..86a15a2a 100644 --- a/lib/channels/sdchannel/sdchannel.md +++ b/lib/channels/sdchannel/sdchannel.md @@ -1,5 +1,22 @@ # SDCHANNEL: Standard Deviation Channel +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Channel | +| **Inputs** | Source (close) | +| **Parameters** | `period` (default 20), `multiplier` (default 2.0) | +| **Outputs** | Multiple series (Upper, Lower) | +| **Output range** | Tracks input | +| **Warmup** | `period` bars | + +### TL;DR + +- Standard Deviation Channel plots a linear regression line through price data with parallel bands at a specified number of standard deviations of re... +- Parameterized by `period` (default 20), `multiplier` (default 2.0). +- Output range: Tracks input. +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + Standard Deviation Channel plots a linear regression line through price data with parallel bands at a specified number of standard deviations of residuals above and below. Unlike Bollinger Bands which measure deviation from a moving average, SDCHANNEL measures deviation from the best-fit trend line, capturing how much price wanders from its underlying trajectory rather than from its simple average. The algorithm is identical to REGCHANNEL; the distinction is purely a naming convention found across different platforms and literature. ## Historical Context diff --git a/lib/channels/starchannel/starchannel.md b/lib/channels/starchannel/starchannel.md index 1808a654..87800333 100644 --- a/lib/channels/starchannel/starchannel.md +++ b/lib/channels/starchannel/starchannel.md @@ -1,5 +1,22 @@ # STARCHANNEL: Stoller Average Range Channel +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Channel | +| **Inputs** | OHLCV bar (TBar) | +| **Parameters** | `period` (default 20), `multiplier` (default 2.0), `atrPeriod` (default 0) | +| **Outputs** | Multiple series (Upper, Lower) | +| **Output range** | Tracks input | +| **Warmup** | `Math.Max(period, effectiveAtrPeriod)` bars | + +### TL;DR + +- Stoller Average Range Channel creates a volatility-adaptive price envelope using Average True Range (ATR) to determine band width around a simple m... +- Parameterized by `period` (default 20), `multiplier` (default 2.0), `atrperiod` (default 0). +- Output range: Tracks input. +- Requires `Math.Max(period, effectiveAtrPeriod)` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + Stoller Average Range Channel creates a volatility-adaptive price envelope using Average True Range (ATR) to determine band width around a simple moving average centerline. The bands automatically expand during volatile periods and contract during calmer markets. The implementation uses a circular buffer for the SMA running sum and Wilder's RMA with a warmup compensator for ATR, achieving O(1) streaming updates per bar. ## Historical Context diff --git a/lib/channels/stbands/stbands.md b/lib/channels/stbands/stbands.md index 51528253..2498e60f 100644 --- a/lib/channels/stbands/stbands.md +++ b/lib/channels/stbands/stbands.md @@ -1,5 +1,22 @@ # STBANDS: Super Trend Bands +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Channel | +| **Inputs** | OHLCV bar (TBar) | +| **Parameters** | `period` (default DefaultPeriod), `multiplier` (default DefaultMultiplier) | +| **Outputs** | Multiple series (Upper, Lower, Trend, Width) | +| **Output range** | Tracks input | +| **Warmup** | `period` bars | + +### TL;DR + +- Super Trend Bands provide ATR-based dynamic support and resistance levels with asymmetric ratchet logic: the upper band only tightens downward duri... +- Parameterized by `period` (default defaultperiod), `multiplier` (default defaultmultiplier). +- Output range: Tracks input. +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + Super Trend Bands provide ATR-based dynamic support and resistance levels with asymmetric ratchet logic: the upper band only tightens downward during downtrends, and the lower band only tightens upward during uptrends. This creates natural trailing stop-loss levels that respect market momentum. A trend direction signal ($+1$ or $-1$) flips when price breaches the opposite band. The ATR is computed as a simple moving average of True Range via a ring buffer with running sum, providing O(1) streaming updates. ## Historical Context diff --git a/lib/channels/ttm_lrc/TtmLrc.md b/lib/channels/ttm_lrc/TtmLrc.md index 19dbb51a..cccbd415 100644 --- a/lib/channels/ttm_lrc/TtmLrc.md +++ b/lib/channels/ttm_lrc/TtmLrc.md @@ -1,5 +1,22 @@ # TTM_LRC: TTM Linear Regression Channel +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Channel | +| **Inputs** | Source (close) | +| **Parameters** | `period` (default 100) | +| **Outputs** | Multiple series (Midline, Upper1, Lower1, Upper2, Lower2) | +| **Output range** | Tracks input | +| **Warmup** | `period` bars | + +### TL;DR + +- TTM Linear Regression Channel plots a least-squares regression line through price data with dual standard deviation bands at $\pm 1\sigma$ and $\pm... +- Parameterized by `period` (default 100). +- Output range: Tracks input. +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + TTM Linear Regression Channel plots a least-squares regression line through price data with dual standard deviation bands at $\pm 1\sigma$ and $\pm 2\sigma$. Developed by John Carter as part of his TTM (Trade The Markets) indicator suite, it extends the standard regression channel by providing two band levels that create statistically meaningful trading zones. The algorithm is identical to REGCHANNEL/SDCHANNEL in its regression and residual computation, but uses a longer default period (100) and emits four bands instead of two. ## Historical Context diff --git a/lib/channels/ubands/ubands.md b/lib/channels/ubands/ubands.md index 1913a1ed..1fab3ada 100644 --- a/lib/channels/ubands/ubands.md +++ b/lib/channels/ubands/ubands.md @@ -1,5 +1,22 @@ # UBANDS: Ehlers Ultimate Bands +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Channel | +| **Inputs** | Source (close) | +| **Parameters** | `period` (default DefaultPeriod), `multiplier` (default DefaultMultiplier) | +| **Outputs** | Multiple series (Upper, Middle, Lower, Width) | +| **Output range** | Tracks input | +| **Warmup** | `period` bars | + +### TL;DR + +- Ehlers Ultimate Bands replace the conventional SMA foundation of Bollinger Bands with the Ultrasmooth Filter (USF), a 2-pole IIR filter with zero o... +- Parameterized by `period` (default defaultperiod), `multiplier` (default defaultmultiplier). +- Output range: Tracks input. +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + Ehlers Ultimate Bands replace the conventional SMA foundation of Bollinger Bands with the Ultrasmooth Filter (USF), a 2-pole IIR filter with zero overshoot and minimal lag. Band width is determined by the RMS (Root Mean Square) of residuals between price and the smoothed centerline, providing a mathematically rigorous deviation measure that makes no assumptions about the distribution of returns. The USF is a recursive filter requiring O(1) computation per bar, while the RMS calculation scans the lookback window at O(n) per bar. ## Historical Context diff --git a/lib/channels/uchannel/uchannel.md b/lib/channels/uchannel/uchannel.md index 71b268fe..c82672b9 100644 --- a/lib/channels/uchannel/uchannel.md +++ b/lib/channels/uchannel/uchannel.md @@ -1,5 +1,22 @@ # UCHANNEL: Ehlers Ultimate Channel +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Channel | +| **Inputs** | OHLCV bar (TBar) | +| **Parameters** | `strPeriod` (default DefaultStrPeriod), `centerPeriod` (default DefaultCenterPeriod), `multiplier` (default DefaultMultiplier) | +| **Outputs** | Multiple series (Upper, Middle, Lower, STR) | +| **Output range** | Tracks input | +| **Warmup** | 1 bar | + +### TL;DR + +- Ehlers Ultimate Channel applies the Ultrasmooth Filter (USF) twice: once to the close price for the centerline and once to True Range for band widt... +- Parameterized by `strperiod` (default defaultstrperiod), `centerperiod` (default defaultcenterperiod), `multiplier` (default defaultmultiplier). +- Output range: Tracks input. +- Requires 1 bar of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + Ehlers Ultimate Channel applies the Ultrasmooth Filter (USF) twice: once to the close price for the centerline and once to True Range for band width, creating a channel where both the trend estimate and the volatility measure share the same low-lag, zero-overshoot filter characteristics. Unlike UBANDS which uses RMS of price residuals, UCHANNEL uses Smoothed True Range (STR) for band width, making it responsive to gap-inclusive volatility. Separate period parameters allow independent tuning of centerline smoothness and band-width responsiveness. ## Historical Context diff --git a/lib/channels/vwapbands/vwapbands.md b/lib/channels/vwapbands/vwapbands.md index 147b6cad..d7454199 100644 --- a/lib/channels/vwapbands/vwapbands.md +++ b/lib/channels/vwapbands/vwapbands.md @@ -1,5 +1,22 @@ # VWAPBANDS: VWAP with Dual Standard Deviation Bands +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Channel | +| **Inputs** | OHLCV bar (TBar) | +| **Parameters** | `multiplier` (default DefaultMultiplier) | +| **Outputs** | Multiple series (Upper1, Lower1, Upper2, Lower2, Vwap, StdDev, Width) | +| **Output range** | Tracks input | +| **Warmup** | `2` bars | + +### TL;DR + +- VWAP Bands extend the Volume Weighted Average Price with dual standard deviation bands at $\pm 1\sigma$ and $\pm 2\sigma$ levels, creating a five-l... +- Parameterized by `multiplier` (default defaultmultiplier). +- Output range: Tracks input. +- Requires `2` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + VWAP Bands extend the Volume Weighted Average Price with dual standard deviation bands at $\pm 1\sigma$ and $\pm 2\sigma$ levels, creating a five-line channel system anchored to volume-weighted fair value. Three running sums (cumulative price×volume, cumulative volume, cumulative price²×volume) enable O(1) streaming updates per bar. A session reset mechanism clears accumulations at configurable intervals, keeping the indicator anchored to current market structure. ## Historical Context diff --git a/lib/channels/vwapsd/vwapsd.md b/lib/channels/vwapsd/vwapsd.md index 2bf1c8d1..30e135bd 100644 --- a/lib/channels/vwapsd/vwapsd.md +++ b/lib/channels/vwapsd/vwapsd.md @@ -1,5 +1,22 @@ # VWAPSD: VWAP with Standard Deviation Bands +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Channel | +| **Inputs** | OHLCV bar (TBar) | +| **Parameters** | `numDevs` (default DefaultNumDevs) | +| **Outputs** | Multiple series (Upper, Lower, Vwap, StdDev, Width) | +| **Output range** | Tracks input | +| **Warmup** | `2` bars | + +### TL;DR + +- VWAP with Standard Deviation Bands combines the Volume Weighted Average Price with a single configurable standard deviation band pair, providing a ... +- Parameterized by `numdevs` (default defaultnumdevs). +- Output range: Tracks input. +- Requires `2` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + VWAP with Standard Deviation Bands combines the Volume Weighted Average Price with a single configurable standard deviation band pair, providing a simpler alternative to VWAPBANDS (which uses dual $\pm 1\sigma$ and $\pm 2\sigma$ levels). Three running sums enable O(1) streaming updates. A session reset mechanism clears accumulations at configurable intervals, keeping the indicator anchored to current market structure. The configurable deviation parameter allows traders to select their desired confidence level ($1\sigma$ ≈ 68%, $2\sigma$ ≈ 95%, $3\sigma$ ≈ 99.7%). ## Historical Context diff --git a/lib/core/avgprice/Avgprice.md b/lib/core/avgprice/Avgprice.md index eee96a89..caab131e 100644 --- a/lib/core/avgprice/Avgprice.md +++ b/lib/core/avgprice/Avgprice.md @@ -1,5 +1,22 @@ # AVGPRICE: Average Price +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Core | +| **Inputs** | OHLCV bar (TBar) | +| **Parameters** | None | +| **Outputs** | Single series (AVGPRICE) | +| **Output range** | Varies (see docs) | +| **Warmup** | `1` bars | + +### TL;DR + +- AVGPRICE computes the arithmetic mean of a bar's four canonical prices: Open, High, Low, and Close. +- No configurable parameters; computation is stateless per bar. +- Output range: Varies (see docs). +- Requires `1` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + AVGPRICE computes the arithmetic mean of a bar's four canonical prices: Open, High, Low, and Close. The formula $\frac{O + H + L + C}{4}$ produces a single representative price that weights all four price components equally, unlike Typical Price (which excludes Open) or Weighted Close (which double-weights Close). This equal weighting makes AVGPRICE the least biased single-bar summary statistic, useful as a neutral input to downstream indicators when no particular price component deserves emphasis. The calculation is stateless, requires no warmup, and costs a single FMA instruction per bar. ## Historical Context diff --git a/lib/core/ha/Ha.md b/lib/core/ha/Ha.md index 7a8eab13..6fe89f59 100644 --- a/lib/core/ha/Ha.md +++ b/lib/core/ha/Ha.md @@ -1,5 +1,22 @@ # HA: Heikin-Ashi +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Core | +| **Inputs** | OHLCV bar (TBar) | +| **Parameters** | None | +| **Outputs** | Single series (HA) | +| **Output range** | Varies (see docs) | +| **Warmup** | `1` bars | + +### TL;DR + +- HA transforms standard OHLC bars into smoothed Heikin-Ashi candles by averaging each component with its predecessor. +- No configurable parameters; computation is stateless per bar. +- Output range: Varies (see docs). +- Requires `1` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "The trend is your friend — but only if the noise doesn't make you abandon it at the first bump." — Every trader, eventually HA transforms standard OHLC bars into smoothed Heikin-Ashi candles by averaging each component with its predecessor. The Close is the bar's four-price mean $(O+H+L+C)/4$, the Open is a recursive midpoint of the prior HA Open and HA Close, and High/Low are clamped extremes that guarantee the HA body always fits inside the HA wick. Unlike most indicators that reduce a bar to a single scalar, HA outputs a complete `TBar` — four smoothed prices per bar — making it a bar-to-bar transform rather than a bar-to-value reduction. The recursive Open gives HA an IIR character: each bar carries a decaying memory of the entire price history, which is what flattens trend noise but also why HA prices do not match any actual traded price. diff --git a/lib/core/medprice/Medprice.md b/lib/core/medprice/Medprice.md index 8c562344..8b52556d 100644 --- a/lib/core/medprice/Medprice.md +++ b/lib/core/medprice/Medprice.md @@ -1,5 +1,22 @@ # MEDPRICE: Median Price +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Core | +| **Inputs** | OHLCV bar (TBar) | +| **Parameters** | None | +| **Outputs** | Single series (MEDPRICE) | +| **Output range** | Varies (see docs) | +| **Warmup** | `1` bars | + +### TL;DR + +- MEDPRICE computes the midpoint of a bar's High and Low: $(H + L) \times 0.5$. +- No configurable parameters; computation is stateless per bar. +- Output range: Varies (see docs). +- Requires `1` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + MEDPRICE computes the midpoint of a bar's High and Low: $(H + L) \times 0.5$. This is the simplest possible estimate of a bar's "fair value," splitting the difference between the session's extremes while ignoring both the opening gap and closing settlement. The result represents the geometric center of the bar's vertical range. Because it excludes Open and Close, MEDPRICE responds purely to the supply/demand boundaries that the market tested, making it a useful input for range-based indicators like CCI or as a detrending reference. Stateless, zero-warmup, one addition and one multiply per bar. ## Historical Context diff --git a/lib/core/midpoint/Midpoint.md b/lib/core/midpoint/Midpoint.md index 9135ff1f..c2ff8cc5 100644 --- a/lib/core/midpoint/Midpoint.md +++ b/lib/core/midpoint/Midpoint.md @@ -1,5 +1,22 @@ # MIDPOINT: Rolling Range Midpoint +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Core | +| **Inputs** | Source (close) | +| **Parameters** | `period` | +| **Outputs** | Single series (Midpoint) | +| **Output range** | Varies (see docs) | +| **Warmup** | `period` bars | + +### TL;DR + +- Single-series rolling midpoint: `(Highest(V, N) + Lowest(V, N)) * 0.5`. +- Parameterized by `period`. +- Output range: Varies (see docs). +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "The center holds, but only for the window you're watching." — Statistical folk wisdom Single-series rolling midpoint: `(Highest(V, N) + Lowest(V, N)) * 0.5`. Returns the center of the value range within a lookback window. TA-Lib compatible (`MIDPOINT` function). Unlike MIDPRICE which operates on separate High/Low bar channels, MIDPOINT operates on a single value series. diff --git a/lib/core/midprice/Midprice.md b/lib/core/midprice/Midprice.md index a572e0b4..1318b61c 100644 --- a/lib/core/midprice/Midprice.md +++ b/lib/core/midprice/Midprice.md @@ -1,5 +1,22 @@ # MIDPRICE: Midpoint Price over Period +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Core | +| **Inputs** | OHLCV bar (TBar) | +| **Parameters** | `period` | +| **Outputs** | Single series (Midprice) | +| **Output range** | Varies (see docs) | +| **Warmup** | `period` bars | + +### TL;DR + +- MIDPRICE computes the center of a rolling price channel by averaging the highest High and lowest Low over the past $N$ bars: $(\text{Highest}(H, N)... +- Parameterized by `period`. +- Output range: Varies (see docs). +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + MIDPRICE computes the center of a rolling price channel by averaging the highest High and lowest Low over the past $N$ bars: $(\text{Highest}(H, N) + \text{Lowest}(L, N)) \times 0.5$. Unlike the stateless price transforms (AVGPRICE, MEDPRICE, TYPPRICE, WCLPRICE) that operate on a single bar, MIDPRICE maintains a lookback window and produces a rolling estimate of the price range's midpoint. This makes it a simplified channel center line, equivalent to the midpoint of a Donchian Channel. The calculation uses two internal RingBuffers for $O(N)$ max/min computation per bar. TA-Lib compatible via `TA_MIDPRICE`. ## Historical Context diff --git a/lib/core/simd/SimdExtensions.md b/lib/core/simd/SimdExtensions.md index c3cbd18a..0350c96b 100644 --- a/lib/core/simd/SimdExtensions.md +++ b/lib/core/simd/SimdExtensions.md @@ -1,5 +1,22 @@ # SimdExtensions Class +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Core | +| **Inputs** | Source (close) | +| **Parameters** | None | +| **Outputs** | Single series (SimdExtensions) | +| **Output range** | Varies (see docs) | +| **Warmup** | 1 bar | + +### TL;DR + +- `SimdExtensions` provides high-performance, SIMD-accelerated extension methods for `ReadOnlySpan`. +- No configurable parameters; computation is stateless per bar. +- Output range: Varies (see docs). +- Requires 1 bar of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + `SimdExtensions` provides high-performance, SIMD-accelerated extension methods for `ReadOnlySpan`. It leverages .NET's `Vector` to achieve 4-8x speedups on supported hardware (AVX2, AVX-512) while automatically falling back to scalar implementations on older hardware. ## Key Features diff --git a/lib/core/tbar/TBar.md b/lib/core/tbar/TBar.md index 95f4254d..4f9cc15c 100644 --- a/lib/core/tbar/TBar.md +++ b/lib/core/tbar/TBar.md @@ -1,5 +1,22 @@ # TBar: OHLCV Bar Struct +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Core | +| **Inputs** | OHLCV bar (TBar) | +| **Parameters** | None | +| **Outputs** | Multiple series (O, H, L, C, V) | +| **Output range** | Varies (see docs) | +| **Warmup** | 1 bar | + +### TL;DR + +- `TBar` is a lightweight, immutable struct representing a single OHLCV (Open, High, Low, Close, Volume) bar. +- No configurable parameters; computation is stateless per bar. +- Output range: Varies (see docs). +- Requires 1 bar of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + ## What It Does `TBar` is a lightweight, immutable struct representing a single OHLCV (Open, High, Low, Close, Volume) bar. It serves as the fundamental unit for price data in QuanTAlib, designed to hold market data with minimal memory overhead while providing convenient accessors for common price derivations. diff --git a/lib/core/tbarseries/TBarSeries.md b/lib/core/tbarseries/TBarSeries.md index 80454272..8edd2b82 100644 --- a/lib/core/tbarseries/TBarSeries.md +++ b/lib/core/tbarseries/TBarSeries.md @@ -1,5 +1,22 @@ # TBarSeries: OHLCV Data Container +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Core | +| **Inputs** | OHLCV bar (TBar) | +| **Parameters** | None | +| **Outputs** | Multiple series (Open, High, Low, Close, Volume) | +| **Output range** | Varies (see docs) | +| **Warmup** | 1 bar | + +### TL;DR + +- `TBarSeries` is a high-performance collection of OHLCV bars. +- No configurable parameters; computation is stateless per bar. +- Output range: Varies (see docs). +- Requires 1 bar of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + ## What It Does `TBarSeries` is a high-performance collection of OHLCV bars. It is the primary data structure for managing historical and real-time market data in QuanTAlib. It uses a **Structure of Arrays (SoA)** layout to optimize memory access and enable efficient SIMD operations across individual price components. diff --git a/lib/core/tseries/TSeries.md b/lib/core/tseries/TSeries.md index 1172d94c..c5b1978b 100644 --- a/lib/core/tseries/TSeries.md +++ b/lib/core/tseries/TSeries.md @@ -1,5 +1,22 @@ # TSeries: Time Series Data Container +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Core | +| **Inputs** | Source (close) | +| **Parameters** | None | +| **Outputs** | Single series (TSeries) | +| **Output range** | Varies (see docs) | +| **Warmup** | 1 bar | + +### TL;DR + +- `TSeries` is a high-performance, memory-efficient container for time-series data. +- No configurable parameters; computation is stateless per bar. +- Output range: Varies (see docs). +- Requires 1 bar of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + ## What It Does `TSeries` is a high-performance, memory-efficient container for time-series data. Unlike standard collections (like `List`), it uses a **Structure of Arrays (SoA)** layout internally. This means it stores timestamps and values in separate contiguous arrays, optimizing memory access patterns for numerical processing and SIMD vectorization. diff --git a/lib/core/tvalue/TValue.md b/lib/core/tvalue/TValue.md index f0edea49..d8815d66 100644 --- a/lib/core/tvalue/TValue.md +++ b/lib/core/tvalue/TValue.md @@ -1,5 +1,22 @@ # TValue: Time-Value Pair +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Core | +| **Inputs** | Source (close) | +| **Parameters** | None | +| **Outputs** | Single series (TValue) | +| **Output range** | Varies (see docs) | +| **Warmup** | 1 bar | + +### TL;DR + +- `TValue` is the fundamental atomic unit of data in QuanTAlib. +- No configurable parameters; computation is stateless per bar. +- Output range: Varies (see docs). +- Requires 1 bar of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + ## What It Does `TValue` is the fundamental atomic unit of data in QuanTAlib. It represents a single point in a time series, consisting of a timestamp and a double-precision floating-point value. It serves as the standard input and output format for all indicators and data streams. diff --git a/lib/core/typprice/Typprice.md b/lib/core/typprice/Typprice.md index ad9f4659..b12d7759 100644 --- a/lib/core/typprice/Typprice.md +++ b/lib/core/typprice/Typprice.md @@ -1,5 +1,22 @@ # TYPPRICE: Typical Price +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Core | +| **Inputs** | OHLCV bar (TBar) | +| **Parameters** | None | +| **Outputs** | Single series (TYPPRICE) | +| **Output range** | Varies (see docs) | +| **Warmup** | `1` bars | + +### TL;DR + +- TYPPRICE computes the equal-weighted average of High, Low, and Close: $(H + L + C) \times \frac{1}{3}$. +- No configurable parameters; computation is stateless per bar. +- Output range: Varies (see docs). +- Requires `1` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + TYPPRICE computes the equal-weighted average of High, Low, and Close: $(H + L + C) \times \frac{1}{3}$. This three-component mean is the most widely used "representative price" in technical analysis, serving as the default input for CCI, MFI, and many other indicators. By including Close but excluding Open, Typical Price captures both the range extremes and the settlement point, giving slightly more weight to closing action than AVGPRICE does. The calculation is stateless and costs a single FMA instruction per bar. ## Historical Context diff --git a/lib/core/wclprice/Wclprice.md b/lib/core/wclprice/Wclprice.md index 969726d9..006c93c4 100644 --- a/lib/core/wclprice/Wclprice.md +++ b/lib/core/wclprice/Wclprice.md @@ -1,5 +1,22 @@ # WCLPRICE: Weighted Close Price +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Core | +| **Inputs** | OHLCV bar (TBar) | +| **Parameters** | None | +| **Outputs** | Single series (WCLPRICE) | +| **Output range** | Varies (see docs) | +| **Warmup** | `1` bars | + +### TL;DR + +- WCLPRICE computes a Close-biased average of High, Low, and Close by double-weighting the closing price: $(H + L + 2C) \times 0.25$. +- No configurable parameters; computation is stateless per bar. +- Output range: Varies (see docs). +- Requires `1` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + WCLPRICE computes a Close-biased average of High, Low, and Close by double-weighting the closing price: $(H + L + 2C) \times 0.25$. This gives Close 50% of the total weight versus 25% each for High and Low, reflecting the widely held belief that the closing price is the most important price of the bar because it represents the final consensus of buyers and sellers. The calculation is stateless, costs a single FMA instruction per bar, and is TA-Lib compatible (`TA_WCLPRICE`). ## Historical Context diff --git a/lib/cycles/ccor/Ccor.md b/lib/cycles/ccor/Ccor.md index dd1c08e6..ec764b5c 100644 --- a/lib/cycles/ccor/Ccor.md +++ b/lib/cycles/ccor/Ccor.md @@ -1,5 +1,22 @@ # CCOR: Ehlers Correlation Cycle +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Cycle | +| **Inputs** | Source (close) | +| **Parameters** | `period` (default 20), `threshold` (default 9.0) | +| **Outputs** | Single series (Ccor) | +| **Output range** | Varies (see docs) | +| **Warmup** | `period` bars | + +### TL;DR + +- CCOR extracts cycle phase by computing Pearson correlation of a price window against cosine (Real) and negative-sine (Imaginary) reference waves of... +- Parameterized by `period` (default 20), `threshold` (default 9.0). +- Output range: Varies (see docs). +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + CCOR extracts cycle phase by computing Pearson correlation of a price window against cosine (Real) and negative-sine (Imaginary) reference waves of a presumed fixed period, converting the resulting phasor to an angle with a monotonic constraint, and classifying the market state as trending or cycling based on the angle rate of change. Unlike Hilbert Transform approaches that rely on analytic signal construction, CCOR uses the statistical machinery of correlation to measure how well price "fits" each quadrature component, yielding bounded $[-1, +1]$ outputs that double as confidence measures. The method was introduced to address the instability of Hilbert-based phasors during trend-dominated regimes. ## Historical Context diff --git a/lib/cycles/ccyc/Ccyc.Validation.Tests.cs b/lib/cycles/ccyc/Ccyc.Validation.Tests.cs index a44561a7..eb726c0a 100644 --- a/lib/cycles/ccyc/Ccyc.Validation.Tests.cs +++ b/lib/cycles/ccyc/Ccyc.Validation.Tests.cs @@ -161,12 +161,12 @@ public class CcycValidationTests var ccycNoise = new Ccyc(0.07); var ccycSine = new Ccyc(0.07); - var rng = new Random(42); + var rng = new GBM(startPrice: 100.0, sigma: 0.1, seed: 42); double sineEnergy = 0; for (int i = 0; i < 300; i++) { - double noiseVal = 100 + rng.NextDouble() * 10; + double noiseVal = rng.Next().Close; ccycNoise.Update(new TValue(DateTime.UtcNow.AddMinutes(i), noiseVal), true); double sineVal = 100 + 10 * Math.Sin(2 * Math.PI * i / 20.0); diff --git a/lib/cycles/ccyc/Ccyc.md b/lib/cycles/ccyc/Ccyc.md index e30dabd4..e8be3894 100644 --- a/lib/cycles/ccyc/Ccyc.md +++ b/lib/cycles/ccyc/Ccyc.md @@ -1,5 +1,22 @@ # CCYC: Ehlers Cyber Cycle +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Cycle | +| **Inputs** | Source (close) | +| **Parameters** | `alpha` (default 0.07) | +| **Outputs** | Single series (Ccyc) | +| **Output range** | Varies (see docs) | +| **Warmup** | `7` bars | + +### TL;DR + +- CCYC isolates the dominant cycle component from price data using a 2-pole high-pass IIR filter applied to a 4-tap FIR-smoothed input, producing an ... +- Parameterized by `alpha` (default 0.07). +- Output range: Varies (see docs). +- Requires `7` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + CCYC isolates the dominant cycle component from price data using a 2-pole high-pass IIR filter applied to a 4-tap FIR-smoothed input, producing an oscillator that strips trend while preserving cyclical content with minimal lag. The companion trigger line (one-bar delay of the cycle output) provides crossover signals for timing entries and exits. Unlike band-pass approaches that require specifying a center frequency, CCYC's high-pass architecture extracts whatever cyclic energy exists above a cutoff controlled by a single $\alpha$ damping parameter, making it adaptive to the dominant period present in the data. ## Historical Context diff --git a/lib/cycles/cg/cg.md b/lib/cycles/cg/cg.md index dd923acd..fa265099 100644 --- a/lib/cycles/cg/cg.md +++ b/lib/cycles/cg/cg.md @@ -1,5 +1,22 @@ # CG: Ehlers Center of Gravity +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Cycle | +| **Inputs** | Source (close) | +| **Parameters** | `period` (default 10) | +| **Outputs** | Single series (Cg) | +| **Output range** | Varies (see docs) | +| **Warmup** | `period` bars | + +### TL;DR + +- CG identifies potential turning points using the physics concept of weighted center of mass applied to a price window. +- Parameterized by `period` (default 10). +- Output range: Varies (see docs). +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + CG identifies potential turning points using the physics concept of weighted center of mass applied to a price window. Developed by John Ehlers, the oscillator measures where the "weight" of prices is concentrated within a lookback period, producing a leading indicator that oscillates around zero with minimal lag compared to traditional moving average crossover systems. ## Historical Context diff --git a/lib/cycles/dsp/dsp.md b/lib/cycles/dsp/dsp.md index b654b6d9..2d4796a4 100644 --- a/lib/cycles/dsp/dsp.md +++ b/lib/cycles/dsp/dsp.md @@ -1,5 +1,22 @@ # DSP: Ehlers Detrended Synthetic Price +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Cycle | +| **Inputs** | Source (close) | +| **Parameters** | `period` (default 40) | +| **Outputs** | Single series (Dsp) | +| **Output range** | Varies (see docs) | +| **Warmup** | `slowPeriod * 3` bars | + +### TL;DR + +- DSP creates a zero-centered oscillator by subtracting a half-cycle EMA from a quarter-cycle EMA, isolating the dominant cyclical component of price... +- Parameterized by `period` (default 40). +- Output range: Varies (see docs). +- Requires `slowPeriod * 3` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + DSP creates a zero-centered oscillator by subtracting a half-cycle EMA from a quarter-cycle EMA, isolating the dominant cyclical component of price while cancelling longer-term trends. Developed by John Ehlers, the indicator is grounded in cycle theory rather than arbitrary period selection, making it a principled alternative to MACD for cycle-aware trading. Bias-corrected EMAs ensure accurate amplitude during warmup. ## Historical Context diff --git a/lib/cycles/eacp/eacp.md b/lib/cycles/eacp/eacp.md index 43464a49..c94502f1 100644 --- a/lib/cycles/eacp/eacp.md +++ b/lib/cycles/eacp/eacp.md @@ -1,5 +1,22 @@ # EACP: Ehlers Autocorrelation Periodogram +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Cycle | +| **Inputs** | Source (close) | +| **Parameters** | `minPeriod` (default 8), `maxPeriod` (default 48), `avgLength` (default 3), `enhance` (default true) | +| **Outputs** | Single series (Eacp) | +| **Output range** | Varies (see docs) | +| **Warmup** | `maxPeriod * 2` bars | + +### TL;DR + +- EACP estimates the dominant cycle period of a financial time series by computing autocorrelation across multiple lags and transforming the result i... +- Parameterized by `minperiod` (default 8), `maxperiod` (default 48), `avglength` (default 3), `enhance` (default true). +- Output range: Varies (see docs). +- Requires `maxPeriod * 2` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + EACP estimates the dominant cycle period of a financial time series by computing autocorrelation across multiple lags and transforming the result into a power spectrum via the Wiener-Khinchin theorem. The output is a continuously updating cycle period measurement (in bars) that can adaptively tune other indicators to the market's current rhythm, making fixed-period assumptions unnecessary. ## Historical Context diff --git a/lib/cycles/ebsw/ebsw.md b/lib/cycles/ebsw/ebsw.md index 65629c06..f2859512 100644 --- a/lib/cycles/ebsw/ebsw.md +++ b/lib/cycles/ebsw/ebsw.md @@ -1,5 +1,22 @@ # EBSW: Ehlers Even Better Sinewave +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Cycle | +| **Inputs** | Source (close) | +| **Parameters** | `hpLength` (default 40), `ssfLength` (default 10) | +| **Outputs** | Single series (Ebsw) | +| **Output range** | Varies (see docs) | +| **Warmup** | 1 bar | + +### TL;DR + +- EBSW is a refined cycle oscillator that combines a high-pass filter (trend removal), a Super-Smoother filter (noise removal), and Automatic Gain Co... +- Parameterized by `hplength` (default 40), `ssflength` (default 10). +- Output range: Varies (see docs). +- Requires 1 bar of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + EBSW is a refined cycle oscillator that combines a high-pass filter (trend removal), a Super-Smoother filter (noise removal), and Automatic Gain Control to produce a normalized $[-1, +1]$ output representing the current position within the dominant market cycle. Developed by John Ehlers as an improvement over the original Hilbert Transform SineWave, it provides cleaner turning point detection without requiring complex phase extraction mathematics. ## Historical Context diff --git a/lib/cycles/homod/homod.md b/lib/cycles/homod/homod.md index e8fbd3f0..7366c1cb 100644 --- a/lib/cycles/homod/homod.md +++ b/lib/cycles/homod/homod.md @@ -1,5 +1,22 @@ # HOMOD: Ehlers Homodyne Discriminator +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Cycle | +| **Inputs** | Source (close) | +| **Parameters** | `minPeriod` (default 6.0), `maxPeriod` (default 50.0) | +| **Outputs** | Single series (Homod) | +| **Output range** | Varies (see docs) | +| **Warmup** | 1 bar | + +### TL;DR + +- HOMOD estimates the dominant cycle period of a market using homodyne mixing, a technique from radio engineering where a signal is multiplied by a d... +- Parameterized by `minperiod` (default 6.0), `maxperiod` (default 50.0). +- Output range: Varies (see docs). +- Requires 1 bar of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + HOMOD estimates the dominant cycle period of a market using homodyne mixing, a technique from radio engineering where a signal is multiplied by a delayed copy of itself to expose the angular phase change between samples. The output is a continuously varying period measurement (in bars) that tracks the market's instantaneous cycle length, enabling adaptive indicator tuning. Developed by John Ehlers, it offers better noise rejection and stability than the raw Hilbert Transform period estimator. ## Historical Context diff --git a/lib/cycles/ht_dcperiod/HtDcperiod.md b/lib/cycles/ht_dcperiod/HtDcperiod.md index 3b113637..6c5bc1d7 100644 --- a/lib/cycles/ht_dcperiod/HtDcperiod.md +++ b/lib/cycles/ht_dcperiod/HtDcperiod.md @@ -1,5 +1,22 @@ # HT_DCPERIOD: Ehlers Hilbert Transform Dominant Cycle Period +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Cycle | +| **Inputs** | Source (close) | +| **Parameters** | None | +| **Outputs** | Single series (HT_DCPERIOD) | +| **Output range** | Varies (see docs) | +| **Warmup** | `LOOKBACK` bars | + +### TL;DR + +- HT_DCPERIOD estimates the period of the dominant market cycle using Ehlers' Hilbert Transform cascade. +- No configurable parameters; computation is stateless per bar. +- Output range: Varies (see docs). +- Requires `LOOKBACK` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + HT_DCPERIOD estimates the period of the dominant market cycle using Ehlers' Hilbert Transform cascade. The algorithm extracts In-Phase and Quadrature components from price, computes instantaneous phase via homodyne discrimination, and derives the period from the phase rate of change. Output is a continuously varying period (typically 6-50 bars) compatible with TA-Lib's `HT_DCPERIOD` function. The indicator enables dynamic tuning of other indicators to the market's actual rhythm rather than fixed-parameter assumptions. ## Historical Context diff --git a/lib/cycles/ht_dcphase/HtDcphase.md b/lib/cycles/ht_dcphase/HtDcphase.md index 48d2e207..bd1c2812 100644 --- a/lib/cycles/ht_dcphase/HtDcphase.md +++ b/lib/cycles/ht_dcphase/HtDcphase.md @@ -1,5 +1,22 @@ # HT_DCPHASE: Ehlers Hilbert Transform Dominant Cycle Phase +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Cycle | +| **Inputs** | Source (close) | +| **Parameters** | None | +| **Outputs** | Single series (HT_DCPHASE) | +| **Output range** | Varies (see docs) | +| **Warmup** | `LOOKBACK` bars | + +### TL;DR + +- HT_DCPHASE measures the instantaneous phase angle of the dominant market cycle using Ehlers' Hilbert Transform cascade. +- No configurable parameters; computation is stateless per bar. +- Output range: Varies (see docs). +- Requires `LOOKBACK` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + HT_DCPHASE measures the instantaneous phase angle of the dominant market cycle using Ehlers' Hilbert Transform cascade. The output ranges from $-45°$ to $315°$, with phase discontinuities at cycle completions marking the transition from one cycle to the next. Compatible with TA-Lib's `HT_DCPHASE` function, the indicator enables cycle-position timing for entries and exits based on where price currently sits within the dominant cycle. ## Historical Context diff --git a/lib/cycles/ht_phasor/HtPhasor.md b/lib/cycles/ht_phasor/HtPhasor.md index 783ac075..0ff56d51 100644 --- a/lib/cycles/ht_phasor/HtPhasor.md +++ b/lib/cycles/ht_phasor/HtPhasor.md @@ -1,5 +1,22 @@ # HT_PHASOR: Ehlers Hilbert Transform Phasor Components +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Cycle | +| **Inputs** | Source (close) | +| **Parameters** | None | +| **Outputs** | Single series (HT_PHASOR) | +| **Output range** | Varies (see docs) | +| **Warmup** | `LOOKBACK` bars | + +### TL;DR + +- HT_PHASOR decomposes the price signal into two orthogonal components, InPhase ($I$) and Quadrature ($Q$), using the Hilbert Transform. +- No configurable parameters; computation is stateless per bar. +- Output range: Varies (see docs). +- Requires `LOOKBACK` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + HT_PHASOR decomposes the price signal into two orthogonal components, InPhase ($I$) and Quadrature ($Q$), using the Hilbert Transform. Together these form a complex phasor $Z = I + jQ$ that describes the instantaneous amplitude and phase of the dominant market cycle. Compatible with TA-Lib's `HT_PHASOR` function, this dual-output indicator provides the fundamental building blocks for cycle analysis, phasor crossover timing, and instantaneous amplitude measurement. ## Historical Context diff --git a/lib/cycles/ht_sine/HtSine.md b/lib/cycles/ht_sine/HtSine.md index 37b492ae..2eeb04b3 100644 --- a/lib/cycles/ht_sine/HtSine.md +++ b/lib/cycles/ht_sine/HtSine.md @@ -1,5 +1,22 @@ # HT_SINE: Ehlers Hilbert Transform SineWave (also known as SINE) +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Cycle | +| **Inputs** | Source (close) | +| **Parameters** | None | +| **Outputs** | Single series (HT_SINE) | +| **Output range** | Varies (see docs) | +| **Warmup** | `LOOKBACK` bars | + +### TL;DR + +- HT_SINE extracts the dominant market cycle phase and outputs both Sine and LeadSine (45° phase advance) for cycle timing. +- No configurable parameters; computation is stateless per bar. +- Output range: Varies (see docs). +- Requires `LOOKBACK` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + HT_SINE extracts the dominant market cycle phase and outputs both Sine and LeadSine (45° phase advance) for cycle timing. The crossover of these two waves identifies turning points in ranging markets up to one-eighth of a cycle early. Compatible with TA-Lib's `HT_SINE` function, the indicator builds on the full Hilbert Transform cascade (phasor extraction, homodyne period estimation, DFT phase accumulation) to produce dual bounded $[-1, +1]$ oscillators that track cycle position rather than price amplitude. ## Historical Context diff --git a/lib/cycles/lunar/Lunar.md b/lib/cycles/lunar/Lunar.md index ae29595a..0d2e5f94 100644 --- a/lib/cycles/lunar/Lunar.md +++ b/lib/cycles/lunar/Lunar.md @@ -1,5 +1,22 @@ # LUNAR: Lunar Phase Indicator +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Cycle | +| **Inputs** | Source (close) | +| **Parameters** | None | +| **Outputs** | Single series (LUNAR) | +| **Output range** | Varies (see docs) | +| **Warmup** | `0` bars | + +### TL;DR + +- LUNAR calculates the Moon's illumination fraction using precise orbital mechanics from Jean Meeus' *Astronomical Algorithms*. +- No configurable parameters; computation is stateless per bar. +- Output range: Varies (see docs). +- Requires `0` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + LUNAR calculates the Moon's illumination fraction using precise orbital mechanics from Jean Meeus' *Astronomical Algorithms*. Output ranges from 0.0 (New Moon) through 0.5 (Quarter) to 1.0 (Full Moon), providing a continuous astronomical cycle for research into potential lunar-correlated market behavior. The indicator is purely time-based, requires no price data, and has zero warmup since the calculation is deterministic from any timestamp. ## Historical Context diff --git a/lib/cycles/solar/Solar.md b/lib/cycles/solar/Solar.md index 12e7e96b..14a6696b 100644 --- a/lib/cycles/solar/Solar.md +++ b/lib/cycles/solar/Solar.md @@ -1,5 +1,22 @@ # SOLAR: Solar Cycle Indicator +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Cycle | +| **Inputs** | Source (close) | +| **Parameters** | None | +| **Outputs** | Single series (SOLAR) | +| **Output range** | Varies (see docs) | +| **Warmup** | `0` bars | + +### TL;DR + +- SOLAR models Earth's seasonal position relative to the Sun using astronomical ephemeris calculations. +- No configurable parameters; computation is stateless per bar. +- Output range: Varies (see docs). +- Requires `0` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + SOLAR models Earth's seasonal position relative to the Sun using astronomical ephemeris calculations. Output oscillates continuously from $-1.0$ (Winter Solstice) through $0.0$ (Equinoxes) to $+1.0$ (Summer Solstice), providing a smooth, mathematically precise seasonal phase for econometric modeling. Like LUNAR, the indicator is purely time-based, requires no price data, and has zero warmup since the calculation is deterministic from any timestamp. ## Historical Context diff --git a/lib/cycles/ssfdsp/Ssfdsp.md b/lib/cycles/ssfdsp/Ssfdsp.md index ab87c33a..b849e68e 100644 --- a/lib/cycles/ssfdsp/Ssfdsp.md +++ b/lib/cycles/ssfdsp/Ssfdsp.md @@ -1,5 +1,22 @@ # SSFDSP: Ehlers SSF Detrended Synthetic Price +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Cycle | +| **Inputs** | Source (close) | +| **Parameters** | `period` (default 40) | +| **Outputs** | Single series (SsfDsp) | +| **Output range** | Varies (see docs) | +| **Warmup** | `slowPeriod * 2` bars | + +### TL;DR + +- SSFDSP isolates the dominant cycle by subtracting a half-cycle Super-Smoother from a quarter-cycle Super-Smoother, producing a zero-centered oscill... +- Parameterized by `period` (default 40). +- Output range: Varies (see docs). +- Requires `slowPeriod * 2` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + SSFDSP isolates the dominant cycle by subtracting a half-cycle Super-Smoother from a quarter-cycle Super-Smoother, producing a zero-centered oscillator with superior noise rejection compared to the EMA-based DSP. The 2-pole Butterworth characteristic of the Super-Smoother filter provides zero phase lag at the cutoff frequency and sharper rolloff than exponential smoothing, making SSFDSP the preferred variant for cycle-aware trading when the approximate dominant period is known. ## Historical Context diff --git a/lib/dynamics/adx/Adx.md b/lib/dynamics/adx/Adx.md index fd01d8c3..b342b31c 100644 --- a/lib/dynamics/adx/Adx.md +++ b/lib/dynamics/adx/Adx.md @@ -1,4 +1,21 @@ -# ADX: Average Directional Index +# ADX: Average Directional Index + +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Dynamic | +| **Inputs** | OHLCV bar (TBar) | +| **Parameters** | `period` | +| **Outputs** | Multiple series (DiPlus, DiMinus) | +| **Output range** | Varies (see docs) | +| **Warmup** | `period * 2` bars | + +### TL;DR + +- The Average Directional Index is the industry-standard measure of trend strength, ignoring direction entirely to focus on the velocity of price exp... +- Parameterized by `period`. +- Output range: Varies (see docs). +- Requires `period * 2` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. The Average Directional Index is the industry-standard measure of trend strength, ignoring direction entirely to focus on the velocity of price expansion. Wilder's pipeline decomposes range into directional movement (+DM, -DM), normalizes against True Range to produce directional indicators (+DI, -DI), derives a directional index (DX) from their ratio, then smooths DX with a final RMA pass. The double-smoothed architecture creates significant lag but exceptional noise rejection, making ADX a regime filter rather than a timing tool. Output is unbounded above 0, with readings above 25 conventionally indicating trending conditions and below 20 indicating choppy markets. diff --git a/lib/dynamics/adxr/Adxr.md b/lib/dynamics/adxr/Adxr.md index 5fb2a474..c64b87e5 100644 --- a/lib/dynamics/adxr/Adxr.md +++ b/lib/dynamics/adxr/Adxr.md @@ -1,4 +1,21 @@ -# ADXR: Average Directional Movement Rating +# ADXR: Average Directional Movement Rating + +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Dynamic | +| **Inputs** | OHLCV bar (TBar) | +| **Parameters** | `period` | +| **Outputs** | Single series (Adxr) | +| **Output range** | Varies (see docs) | +| **Warmup** | `adx.WarmupPeriod + period - 1` bars | + +### TL;DR + +- The Average Directional Movement Rating is a smoothed version of ADX that dampens short-term fluctuations in trend strength by averaging the curren... +- Parameterized by `period`. +- Output range: Varies (see docs). +- Requires `adx.WarmupPeriod + period - 1` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. The Average Directional Movement Rating is a smoothed version of ADX that dampens short-term fluctuations in trend strength by averaging the current ADX with a historical ADX value. This creates a doubly-lagged metric that sacrifices all timing utility in exchange for stable regime classification. ADXR answers one question: does the current market environment reward trend-following strategies? If ADXR is high, deploy momentum logic. If low, deploy mean-reversion. It is a strategic filter, not a tactical signal. diff --git a/lib/dynamics/alligator/Alligator.md b/lib/dynamics/alligator/Alligator.md index eded1caa..5c45cd14 100644 --- a/lib/dynamics/alligator/Alligator.md +++ b/lib/dynamics/alligator/Alligator.md @@ -1,4 +1,21 @@ -# ALLIGATOR: Williams Alligator +# ALLIGATOR: Williams Alligator + +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Dynamic | +| **Inputs** | OHLCV bar (TBar) | +| **Parameters** | `jawPeriod`, `jawOffset`, `teethPeriod`, `teethOffset`, `lipsPeriod`, `lipsOffset` | +| **Outputs** | Multiple series (Jaw, Teeth, Lips) | +| **Output range** | Varies (see docs) | +| **Warmup** | `Math.Max(Math.Max(jawPeriod, teethPeriod), lipsPeriod)` bars | + +### TL;DR + +- The Williams Alligator is a trend-following system that uses three Smoothed Moving Averages (SMMA/RMA) with different periods and forward display o... +- Parameterized by `jawperiod`, `jawoffset`, `teethperiod`, `teethoffset`, `lipsperiod`, `lipsoffset`. +- Output range: Varies (see docs). +- Requires `Math.Max(Math.Max(jawPeriod, teethPeriod), lipsPeriod)` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. The Williams Alligator is a trend-following system that uses three Smoothed Moving Averages (SMMA/RMA) with different periods and forward display offsets to visualize market phases. The Jaw (13-period, offset 8), Teeth (8-period, offset 5), and Lips (5-period, offset 3) create a layered structure where intertwined lines indicate consolidation ("sleeping") and separated, aligned lines indicate trending conditions ("eating"). The metaphor maps directly to position management: stay out when the alligator sleeps, ride when it eats. Each line uses Wilder's smoothing ($\alpha = 1/N$), which is heavier than standard EMA, providing superior noise rejection at the cost of additional lag. diff --git a/lib/dynamics/amat/Amat.md b/lib/dynamics/amat/Amat.md index fb2916c4..f2d61255 100644 --- a/lib/dynamics/amat/Amat.md +++ b/lib/dynamics/amat/Amat.md @@ -1,4 +1,21 @@ -# AMAT: Archer Moving Averages Trends +# AMAT: Archer Moving Averages Trends + +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Dynamic | +| **Inputs** | OHLCV bar (TBar) | +| **Parameters** | `fastPeriod` (default 10), `slowPeriod` (default 50) | +| **Outputs** | Multiple series (Strength, FastEma, SlowEma) | +| **Output range** | Varies (see docs) | +| **Warmup** | `slowPeriod` bars | + +### TL;DR + +- The Archer Moving Averages Trends indicator is a triple-confirmation trend identification system that uses dual EMAs to produce discrete directiona... +- Parameterized by `fastperiod` (default 10), `slowperiod` (default 50). +- Output range: Varies (see docs). +- Requires `slowPeriod` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. The Archer Moving Averages Trends indicator is a triple-confirmation trend identification system that uses dual EMAs to produce discrete directional signals (+1 bullish, -1 bearish, 0 neutral). Unlike simple crossover systems that trigger on any intersection, AMAT requires alignment of three conditions: relative position (fast above/below slow), fast EMA direction (rising/falling), and slow EMA direction (rising/falling). This triple gate filters out the whipsaw endemic to single-condition crossover systems in ranging markets. A secondary output quantifies trend strength as the percentage separation between EMAs, providing a conviction metric for position sizing. diff --git a/lib/dynamics/aroon/Aroon.md b/lib/dynamics/aroon/Aroon.md index 2d1752bd..483b84a8 100644 --- a/lib/dynamics/aroon/Aroon.md +++ b/lib/dynamics/aroon/Aroon.md @@ -1,4 +1,21 @@ -# AROON: Aroon Indicator +# AROON: Aroon Indicator + +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Dynamic | +| **Inputs** | OHLCV bar (TBar) | +| **Parameters** | `period` | +| **Outputs** | Multiple series (Up, Down) | +| **Output range** | Varies (see docs) | +| **Warmup** | `period` bars | + +### TL;DR + +- The Aroon indicator measures the temporal freshness of price extremes, answering not "how much did price move?" but "how long ago did it make a new... +- Parameterized by `period`. +- Output range: Varies (see docs). +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. The Aroon indicator measures the temporal freshness of price extremes, answering not "how much did price move?" but "how long ago did it make a new high or low?" Aroon Up tracks the recency of the highest high within the lookback window; Aroon Down tracks the recency of the lowest low. Both are normalized to 0-100 where 100 means the extreme occurred on the current bar and 0 means it occurred at the far edge of the window. A companion Aroon Oscillator (Up minus Down) provides a single zero-centered metric for trend bias. Unlike recursive indicators that accumulate floating-point drift, Aroon is purely windowed — its value depends only on data within the lookback period, making it immune to initialization artifacts. diff --git a/lib/dynamics/aroonosc/AroonOsc.md b/lib/dynamics/aroonosc/AroonOsc.md index 7454819e..302555bc 100644 --- a/lib/dynamics/aroonosc/AroonOsc.md +++ b/lib/dynamics/aroonosc/AroonOsc.md @@ -1,4 +1,21 @@ -# AROONOSC: Aroon Oscillator +# AROONOSC: Aroon Oscillator + +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Dynamic | +| **Inputs** | OHLCV bar (TBar) | +| **Parameters** | `period` | +| **Outputs** | Single series (AroonOsc) | +| **Output range** | $-100$ to $+100$ | +| **Warmup** | `period` bars | + +### TL;DR + +- The Aroon Oscillator condenses the dual-line Aroon system into a single zero-centered value by computing $\text{AroonUp} - \text{AroonDown}$. +- Parameterized by `period`. +- Output range: $-100$ to $+100$. +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. The Aroon Oscillator condenses the dual-line Aroon system into a single zero-centered value by computing $\text{AroonUp} - \text{AroonDown}$. This distills the temporal battle between fresh highs and fresh lows into a bounded $[-100, +100]$ metric where positive values indicate bullish recency dominance and negative values indicate bearish. Unlike recursive indicators that accumulate floating-point drift, the Aroon Oscillator is purely windowed — its value depends only on data within the lookback period, making it stateless in the long term and immune to initialization poisoning. The step-function output reflects discrete events (new extremes appearing or aging out) rather than smooth price trajectories. diff --git a/lib/dynamics/chop/Chop.md b/lib/dynamics/chop/Chop.md index 3613cf79..ebb8be5a 100644 --- a/lib/dynamics/chop/Chop.md +++ b/lib/dynamics/chop/Chop.md @@ -1,4 +1,21 @@ -# CHOP: Choppiness Index +# CHOP: Choppiness Index + +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Dynamic | +| **Inputs** | OHLCV bar (TBar) | +| **Parameters** | `period` (default 14) | +| **Outputs** | Single series (CHOP) | +| **Output range** | Varies (see docs) | +| **Warmup** | `period` bars | + +### TL;DR + +- The Choppiness Index is a non-directional regime indicator that measures whether the market is trending or trading sideways. +- Parameterized by `period` (default 14). +- Output range: Varies (see docs). +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. The Choppiness Index is a non-directional regime indicator that measures whether the market is trending or trading sideways. It compares total price movement (sum of True Range) to net price movement (high-low channel width) using a logarithmic ratio, producing a bounded value where high readings indicate choppy/consolidating conditions and low readings indicate trending conditions. CHOP does not indicate direction — only whether directional strategies are likely to succeed. The logarithmic scaling normalizes the output to approximately 0-100 regardless of price level or volatility magnitude. diff --git a/lib/dynamics/dmx/Dmx.md b/lib/dynamics/dmx/Dmx.md index d218e7ab..797ae38f 100644 --- a/lib/dynamics/dmx/Dmx.md +++ b/lib/dynamics/dmx/Dmx.md @@ -1,4 +1,21 @@ -# DMX: Directional Movement Index (Jurik) +# DMX: Directional Movement Index (Jurik) + +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Dynamic | +| **Inputs** | OHLCV bar (TBar) | +| **Parameters** | `period` | +| **Outputs** | Single series (Dmx) | +| **Output range** | Varies (see docs) | +| **Warmup** | `period` bars | + +### TL;DR + +- The DMX is Mark Jurik's modernized overhaul of Wilder's Directional Movement system, replacing the sluggish RMA smoothing with the Jurik Moving Ave... +- Parameterized by `period`. +- Output range: Varies (see docs). +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. The DMX is Mark Jurik's modernized overhaul of Wilder's Directional Movement system, replacing the sluggish RMA smoothing with the Jurik Moving Average (JMA) to achieve faster trend detection with superior noise rejection. The core directional movement logic (+DM, -DM, True Range) is preserved faithfully from Wilder, but the three parallel smoothing passes use JMA's adaptive bandwidth instead of RMA's fixed $\alpha = 1/N$. The result is a directional indicator that reacts 3-5 bars earlier to trend changes than standard DMI while filtering out more noise during consolidation. Output is the difference between smoothed directional indicators: $DMX = DI^+ - DI^-$, positive for uptrends and negative for downtrends. diff --git a/lib/dynamics/dx/Dx.md b/lib/dynamics/dx/Dx.md index c059a691..da6cd1af 100644 --- a/lib/dynamics/dx/Dx.md +++ b/lib/dynamics/dx/Dx.md @@ -1,4 +1,21 @@ -# DX: Directional Movement Index +# DX: Directional Movement Index + +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Dynamic | +| **Inputs** | OHLCV bar (TBar) | +| **Parameters** | `period` (default 14) | +| **Outputs** | Multiple series (DiPlus, DiMinus) | +| **Output range** | Varies (see docs) | +| **Warmup** | `period` bars | + +### TL;DR + +- The Directional Movement Index is the raw, unsmoothed measure of trend strength from Wilder's directional movement system. +- Parameterized by `period` (default 14). +- Output range: Varies (see docs). +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. The Directional Movement Index is the raw, unsmoothed measure of trend strength from Wilder's directional movement system. It decomposes price expansion into +DM and -DM, normalizes against True Range using RMA smoothing to produce +DI and -DI, then computes the ratio $DX = 100 \times |{+DI - {-DI}}| / ({+DI + {-DI}})$. Unlike ADX, which applies a final RMA pass to DX, the raw DX responds immediately to changes in directional dominance — making it noisier but approximately one full period faster. Output ranges from 0 to 100, where high values indicate strong directional movement regardless of up/down direction. DX is the building block from which ADX is derived. diff --git a/lib/dynamics/ghla/Ghla.md b/lib/dynamics/ghla/Ghla.md index ed7dbb86..5682d7c2 100644 --- a/lib/dynamics/ghla/Ghla.md +++ b/lib/dynamics/ghla/Ghla.md @@ -1,5 +1,22 @@ # GHLA: Gann High-Low Activator +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Dynamic | +| **Inputs** | OHLCV bar (TBar) | +| **Parameters** | `period` (default 13) | +| **Outputs** | Single series (Ghla) | +| **Output range** | Varies (see docs) | +| **Warmup** | `period` bars | + +### TL;DR + +- The Gann High-Low Activator (GHLA) is a trend-following stop/reversal indicator that alternates between the Simple Moving Average of Highs and the ... +- Parameterized by `period` (default 13). +- Output range: Varies (see docs). +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "The simplest indicators are the hardest to argue with. Two averages, one rule, and the market tells you which side of the fence to stand on." The Gann High-Low Activator (GHLA) is a trend-following stop/reversal indicator that alternates between the Simple Moving Average of Highs and the Simple Moving Average of Lows based on a three-state crossover rule. Developed by Robert Krausz and published in *Technical Analysis of Stocks & Commodities* (February 1998), the indicator produces a single trailing line: SMA(Low) during uptrends (acting as dynamic support) and SMA(High) during downtrends (acting as dynamic resistance). The flip between states occurs only when price closes decisively beyond the opposing SMA, creating a hysteresis zone that filters minor whipsaws. With a default period of 3 bars, GHLA responds aggressively to trend changes while requiring just $O(N)$ additions and one comparison per bar. diff --git a/lib/dynamics/ht_trendmode/HtTrendmode.md b/lib/dynamics/ht_trendmode/HtTrendmode.md index 9ecaa09a..020d908d 100644 --- a/lib/dynamics/ht_trendmode/HtTrendmode.md +++ b/lib/dynamics/ht_trendmode/HtTrendmode.md @@ -1,4 +1,21 @@ -# HT_TRENDMODE: Hilbert Transform Trend vs Cycle Mode +# HT_TRENDMODE: Hilbert Transform Trend vs Cycle Mode + +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Dynamic | +| **Inputs** | Source (close) | +| **Parameters** | None | +| **Outputs** | Single series (HT_TRENDMODE) | +| **Output range** | $0$ to $1$ | +| **Warmup** | `LOOKBACK` bars | + +### TL;DR + +- The Hilbert Transform Trend Mode indicator is a binary regime classifier that determines whether price action is dominated by trending behavior (ou... +- No configurable parameters; computation is stateless per bar. +- Output range: $0$ to $1$. +- Requires `LOOKBACK` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. The Hilbert Transform Trend Mode indicator is a binary regime classifier that determines whether price action is dominated by trending behavior (output = 1) or cyclical/mean-reverting behavior (output = 0). It uses the full Ehlers Hilbert Transform pipeline — 4-bar WMA smoothing, Hilbert FIR filters, homodyne discriminator for period estimation, DC phase extraction, and SineWave indicators — then applies four decision criteria to classify the current regime. The implementation follows TA-Lib's Ehlers-faithful algorithm from the February 2002 publication. Output is discrete {0, 1}, making it a direct strategy selector: deploy trend-following logic when mode = 1, and mean-reversion logic when mode = 0. diff --git a/lib/dynamics/ichimoku/Ichimoku.md b/lib/dynamics/ichimoku/Ichimoku.md index 6abc9a05..6064b004 100644 --- a/lib/dynamics/ichimoku/Ichimoku.md +++ b/lib/dynamics/ichimoku/Ichimoku.md @@ -1,4 +1,21 @@ -# ICHIMOKU: Ichimoku Kinko Hyo +# ICHIMOKU: Ichimoku Kinko Hyo + +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Dynamic | +| **Inputs** | OHLCV bar (TBar) | +| **Parameters** | `tenkanPeriod`, `kijunPeriod`, `senkouBPeriod`, `displacement` | +| **Outputs** | Multiple series (Tenkan, Kijun, SenkouA, SenkouB, Chikou) | +| **Output range** | Varies (see docs) | +| **Warmup** | `maxPeriod` bars | + +### TL;DR + +- Ichimoku Kinko Hyo ("One Glance Equilibrium Chart") is a comprehensive trend-following system that provides five distinct components revealing tren... +- Parameterized by `tenkanperiod`, `kijunperiod`, `senkoubperiod`, `displacement`. +- Output range: Varies (see docs). +- Requires `maxPeriod` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. Ichimoku Kinko Hyo ("One Glance Equilibrium Chart") is a comprehensive trend-following system that provides five distinct components revealing trend direction, momentum, support/resistance levels, and potential future price zones simultaneously. The Tenkan-sen and Kijun-sen are midpoints of high-low ranges at different timescales (not moving averages of closes). Senkou Span A and B form the "cloud" (Kumo) — a projected equilibrium zone displaced forward in time. Chikou Span is simply the current close displaced backward. All components use sliding window min/max arithmetic, producing step-function behavior on breakouts rather than the smooth curves of EMA-based systems. The system requires OHLC bar input. diff --git a/lib/dynamics/impulse/Impulse.md b/lib/dynamics/impulse/Impulse.md index 5a71965c..a5f77a54 100644 --- a/lib/dynamics/impulse/Impulse.md +++ b/lib/dynamics/impulse/Impulse.md @@ -1,4 +1,21 @@ -# IMPULSE: Elder Impulse System +# IMPULSE: Elder Impulse System + +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Dynamic | +| **Inputs** | OHLCV bar (TBar) | +| **Parameters** | `emaPeriod` (default 13), `macdFast` (default 12), `macdSlow` (default 26), `macdSignal` (default 9) | +| **Outputs** | Single series (Impulse) | +| **Output range** | Varies (see docs) | +| **Warmup** | 1 bar | + +### TL;DR + +- The Elder Impulse System combines a 13-period EMA (trend inertia) with the MACD(12,26,9) histogram (momentum acceleration) to classify each bar as ... +- Parameterized by `emaperiod` (default 13), `macdfast` (default 12), `macdslow` (default 26), `macdsignal` (default 9). +- Output range: Varies (see docs). +- Requires 1 bar of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. > "The Impulse System identifies inflection points where a trend speeds up or slows down." -- Alexander Elder, *Come Into My Trading Room* diff --git a/lib/dynamics/pfe/Pfe.md b/lib/dynamics/pfe/Pfe.md index 556aa6d8..9bc03de2 100644 --- a/lib/dynamics/pfe/Pfe.md +++ b/lib/dynamics/pfe/Pfe.md @@ -1,5 +1,22 @@ # PFE: Polarized Fractal Efficiency +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Dynamic | +| **Inputs** | Source (close) | +| **Parameters** | `period` (default 10), `smoothPeriod` (default 5) | +| **Outputs** | Single series (Pfe) | +| **Output range** | Varies (see docs) | +| **Warmup** | `period + 1` bars | + +### TL;DR + +- Polarized Fractal Efficiency (PFE) quantifies trend strength by comparing the Euclidean distance a price series actually travels bar-to-bar against... +- Parameterized by `period` (default 10), `smoothperiod` (default 5). +- Output range: Varies (see docs). +- Requires `period + 1` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "The shortest distance between two points is a straight line. The market never takes the shortest distance. PFE measures how badly it misses." Polarized Fractal Efficiency (PFE) quantifies trend strength by comparing the Euclidean distance a price series actually travels bar-to-bar against the straight-line distance between the endpoints over the same window. The ratio, scaled to [-100, +100] and smoothed with an EMA, distinguishes efficient trending motion (values near ±100) from fractal, self-similar noise (values near 0). Created by Hans Hannula and published in *Technical Analysis of Stocks & Commodities* (January 1994), PFE applies fractal geometry to price action without requiring Hurst exponent estimation or rescaled-range analysis. With default parameters (period=10, smooth=5), the indicator needs 11 close values for the first raw reading plus 5 bars of EMA convergence, totaling ~16 bars of warmup. The core loop executes $N$ square roots per bar, making it $O(N)$ per update in streaming mode. diff --git a/lib/dynamics/qstick/Qstick.md b/lib/dynamics/qstick/Qstick.md index a62de044..635392e5 100644 --- a/lib/dynamics/qstick/Qstick.md +++ b/lib/dynamics/qstick/Qstick.md @@ -1,4 +1,21 @@ -# QSTICK: Qstick Indicator +# QSTICK: Qstick Indicator + +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Dynamic | +| **Inputs** | OHLCV bar (TBar) | +| **Parameters** | `period` (default DefaultPeriod), `useEma` (default DefaultUseEma) | +| **Outputs** | Single series (QSTICK) | +| **Output range** | Varies (see docs) | +| **Warmup** | `period` bars | + +### TL;DR + +- The Qstick indicator, developed by Tushar Chande, computes a moving average of the close-minus-open difference over a lookback period, quantifying ... +- Parameterized by `period` (default defaultperiod), `useema` (default defaultuseema). +- Output range: Varies (see docs). +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. > "The average candlestick body reveals the market's true conviction." diff --git a/lib/dynamics/ravi/Ravi.md b/lib/dynamics/ravi/Ravi.md index 2a3a7fb8..99f84928 100644 --- a/lib/dynamics/ravi/Ravi.md +++ b/lib/dynamics/ravi/Ravi.md @@ -1,5 +1,22 @@ # RAVI: Chande Range Action Verification Index +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Dynamic | +| **Inputs** | Source (close) | +| **Parameters** | `shortPeriod` (default 7), `longPeriod` (default 65) | +| **Outputs** | Single series (Ravi) | +| **Output range** | Varies (see docs) | +| **Warmup** | 1 bar | + +### TL;DR + +- RAVI (Range Action Verification Index) measures trend strength by computing the absolute percentage divergence between a short-period SMA and a lon... +- Parameterized by `shortperiod` (default 7), `longperiod` (default 65). +- Output range: Varies (see docs). +- Requires 1 bar of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "The simplest question in technical analysis is also the most important: is this market trending or not? RAVI answers it with two moving averages and a division." RAVI (Range Action Verification Index) measures trend strength by computing the absolute percentage divergence between a short-period SMA and a long-period SMA. Created by Tushar Chande and published in *Beyond Technical Analysis* (Wiley, 2001), the indicator classifies markets into trending (RAVI > 3%) and ranging (RAVI < 3%) regimes using a single threshold. With default parameters (short=7, long=65), RAVI requires 65 bars of warmup for the first valid reading. The core computation is three operations per bar in streaming mode: two running-sum updates and one division. No square roots, no exponentials, no recursion. The entire indicator reduces to normalized SMA spread, making it one of the cheapest dynamics classifiers available. diff --git a/lib/dynamics/super/Super.md b/lib/dynamics/super/Super.md index 0a0be1a4..88836e18 100644 --- a/lib/dynamics/super/Super.md +++ b/lib/dynamics/super/Super.md @@ -1,4 +1,21 @@ -# SUPER: SuperTrend +# SUPER: SuperTrend + +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Dynamic | +| **Inputs** | OHLCV bar (TBar) | +| **Parameters** | `period` (default 10), `multiplier` (default 3.0) | +| **Outputs** | Multiple series (UpperBand, LowerBand) | +| **Output range** | Varies (see docs) | +| **Warmup** | `> period + 1` bars | + +### TL;DR + +- SuperTrend is a trend-following overlay that uses ATR-scaled bands around the HL2 midpoint, switching between upper and lower bands based on close ... +- Parameterized by `period` (default 10), `multiplier` (default 3.0). +- Output range: Varies (see docs). +- Requires `> period + 1` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. > "It's not an indicator; it's a trailing stop with a marketing budget." diff --git a/lib/dynamics/ttm_squeeze/TtmSqueeze.md b/lib/dynamics/ttm_squeeze/TtmSqueeze.md index a58eaa4e..7a4dcf28 100644 --- a/lib/dynamics/ttm_squeeze/TtmSqueeze.md +++ b/lib/dynamics/ttm_squeeze/TtmSqueeze.md @@ -1,4 +1,21 @@ -# TTM_SQUEEZE: TTM Squeeze +# TTM_SQUEEZE: TTM Squeeze + +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Dynamic | +| **Inputs** | OHLCV bar (TBar) | +| **Parameters** | `bbPeriod` (default 20), `bbMult` (default 2.0), `kcPeriod` (default 20), `kcMult` (default 1.5), `momPeriod` (default 20) | +| **Outputs** | Single series (TtmSqueeze) | +| **Output range** | Varies (see docs) | +| **Warmup** | `Math.Max(Math.Max(bbPeriod, kcPeriod), momPeriod)` bars | + +### TL;DR + +- John Carter's TTM Squeeze detects low-volatility compression by comparing Bollinger Band width against Keltner Channel width: when BB fits inside K... +- Parameterized by `bbperiod` (default 20), `bbmult` (default 2.0), `kcperiod` (default 20), `kcmult` (default 1.5), `momperiod` (default 20). +- Output range: Varies (see docs). +- Requires `Math.Max(Math.Max(bbPeriod, kcPeriod), momPeriod)` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. > "Volatility compression is the market holding its breath before screaming." diff --git a/lib/dynamics/ttm_trend/TtmTrend.md b/lib/dynamics/ttm_trend/TtmTrend.md index 8461a190..58b15e00 100644 --- a/lib/dynamics/ttm_trend/TtmTrend.md +++ b/lib/dynamics/ttm_trend/TtmTrend.md @@ -1,4 +1,21 @@ -# TTM_TREND: TTM Trend +# TTM_TREND: TTM Trend + +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Dynamic | +| **Inputs** | OHLCV bar (TBar) | +| **Parameters** | `period` (default DefaultPeriod) | +| **Outputs** | Single series (TTM_TREND) | +| **Output range** | Varies (see docs) | +| **Warmup** | `> 2` bars | + +### TL;DR + +- John Carter's TTM Trend uses a fast EMA (default period 6) applied to typical price (HLC/3) to determine short-term trend direction via slope sign. +- Parameterized by `period` (default defaultperiod). +- Output range: Varies (see docs). +- Requires `> 2` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. > "The simplest trend indicator is the one you actually follow." diff --git a/lib/dynamics/vhf/Vhf.md b/lib/dynamics/vhf/Vhf.md index 74816fa6..53434137 100644 --- a/lib/dynamics/vhf/Vhf.md +++ b/lib/dynamics/vhf/Vhf.md @@ -1,5 +1,22 @@ # VHF: Vertical Horizontal Filter +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Dynamic | +| **Inputs** | Source (close) | +| **Parameters** | `period` (default 28) | +| **Outputs** | Single series (Vhf) | +| **Output range** | Varies (see docs) | +| **Warmup** | `period + 1` bars | + +### TL;DR + +- VHF (Vertical Horizontal Filter) measures trend strength by dividing the price range over $N$ periods by the total absolute bar-to-bar path distanc... +- Parameterized by `period` (default 28). +- Output range: Varies (see docs). +- Requires `period + 1` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "Before you ask which way the market is going, ask whether it is going anywhere at all. VHF answers the second question with a ratio and a ruler." VHF (Vertical Horizontal Filter) measures trend strength by dividing the price range over $N$ periods by the total absolute bar-to-bar path distance over the same window. Created by Adam White and published in the August 1991 issue of *Futures* magazine, VHF produces a single positive value where higher readings indicate trending conditions and lower readings indicate choppy, range-bound markets. With the default period of 28, the indicator requires 29 close values for the first valid output. The core computation in streaming mode is O(1) per bar when implemented with deque-based min/max tracking and a running sum of absolute changes. No square roots, no exponentials, no recursion. VHF is one of the simplest and cheapest trend-strength classifiers available, requiring approximately 12 operations per bar at steady state. diff --git a/lib/dynamics/vortex/Vortex.md b/lib/dynamics/vortex/Vortex.md index a04c6bd0..153bf6f8 100644 --- a/lib/dynamics/vortex/Vortex.md +++ b/lib/dynamics/vortex/Vortex.md @@ -1,4 +1,21 @@ -# VORTEX: Vortex Indicator +# VORTEX: Vortex Indicator + +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Dynamic | +| **Inputs** | OHLCV bar (TBar) | +| **Parameters** | `period` (default 14) | +| **Outputs** | Multiple series (ViPlus, ViMinus) | +| **Output range** | Varies (see docs) | +| **Warmup** | `period` bars | + +### TL;DR + +- The Vortex Indicator measures upward and downward trend momentum by computing the ratio of positive and negative vortex movements to true range ove... +- Parameterized by `period` (default 14). +- Output range: Varies (see docs). +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. > "When bulls and bears clash, the Vortex measures the violence." diff --git a/lib/errors/huber/Huber.md b/lib/errors/huber/Huber.md index c2317e13..047e477c 100644 --- a/lib/errors/huber/Huber.md +++ b/lib/errors/huber/Huber.md @@ -1,4 +1,21 @@ -# Huber: Huber Loss +# Huber: Huber Loss + +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Error Metric | +| **Inputs** | Source (close) | +| **Parameters** | `period`, `delta` (default 1.345) | +| **Outputs** | Single series (Huber) | +| **Output range** | $\geq 0$ | +| **Warmup** | 1 bar | + +### TL;DR + +- Huber Loss is a hybrid loss function that combines the best properties of Mean Squared Error (MSE) and Mean Absolute Error (MAE). +- Parameterized by `period`, `delta` (default 1.345). +- Output range: $\geq 0$. +- Requires 1 bar of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. > "The Goldilocks of loss functions: not too sensitive, not too robust, just right." diff --git a/lib/errors/logcosh/LogCosh.md b/lib/errors/logcosh/LogCosh.md index 92a6cd08..6b740e21 100644 --- a/lib/errors/logcosh/LogCosh.md +++ b/lib/errors/logcosh/LogCosh.md @@ -1,4 +1,21 @@ -# Log-Cosh: Logarithm of Hyperbolic Cosine Loss +# Log-Cosh: Logarithm of Hyperbolic Cosine Loss + +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Error Metric | +| **Inputs** | Source (close) | +| **Parameters** | `period` | +| **Outputs** | Single series (UNKNOWN) | +| **Output range** | $\geq 0$ | +| **Warmup** | 1 bar | + +### TL;DR + +- Log-Cosh Loss combines the best properties of L1 (absolute) and L2 (squared) error metrics through the logarithm of the hyperbolic cosine function. +- Parameterized by `period`. +- Output range: $\geq 0$. +- Requires 1 bar of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. > "The smooth operator that acts like L2 for small errors and L1 for large ones." diff --git a/lib/errors/maape/Maape.md b/lib/errors/maape/Maape.md index a0516649..850c738d 100644 --- a/lib/errors/maape/Maape.md +++ b/lib/errors/maape/Maape.md @@ -1,4 +1,21 @@ -# MAAPE: Mean Arctangent Absolute Percentage Error +# MAAPE: Mean Arctangent Absolute Percentage Error + +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Error Metric | +| **Inputs** | Source (close) | +| **Parameters** | `period` | +| **Outputs** | Single series (MAAPE) | +| **Output range** | $\geq 0$ | +| **Warmup** | 1 bar | + +### TL;DR + +- Mean Arctangent Absolute Percentage Error (MAAPE) transforms percentage errors through the arctangent function, naturally bounding the metric betwe... +- Parameterized by `period`. +- Output range: $\geq 0$. +- Requires 1 bar of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. > "When percentage errors need boundaries, arctangent provides the walls." diff --git a/lib/errors/mae/Mae.md b/lib/errors/mae/Mae.md index 47b00543..b8d4d4a0 100644 --- a/lib/errors/mae/Mae.md +++ b/lib/errors/mae/Mae.md @@ -1,4 +1,21 @@ -# MAE: Mean Absolute Error +# MAE: Mean Absolute Error + +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Error Metric | +| **Inputs** | Source (close) | +| **Parameters** | `period` | +| **Outputs** | Single series (MAE) | +| **Output range** | $\geq 0$ | +| **Warmup** | 1 bar | + +### TL;DR + +- Mean Absolute Error (MAE) measures the average magnitude of errors in a set of predictions, without considering their direction. +- Parameterized by `period`. +- Output range: $\geq 0$. +- Requires 1 bar of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. > "When you need to know how wrong you are on average, without the drama of squared errors." diff --git a/lib/errors/mapd/Mapd.md b/lib/errors/mapd/Mapd.md index b2e89e68..57604b0c 100644 --- a/lib/errors/mapd/Mapd.md +++ b/lib/errors/mapd/Mapd.md @@ -1,4 +1,21 @@ -# MAPD: Mean Absolute Percentage Deviation +# MAPD: Mean Absolute Percentage Deviation + +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Error Metric | +| **Inputs** | Source (close) | +| **Parameters** | `period` | +| **Outputs** | Single series (MAPD) | +| **Output range** | $\geq 0$ | +| **Warmup** | 1 bar | + +### TL;DR + +- Mean Absolute Percentage Deviation (MAPD) measures the average absolute percentage difference between actual and predicted values, using the predic... +- Parameterized by `period`. +- Output range: $\geq 0$. +- Requires 1 bar of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. > "Like MAPE, but divides by what you predicted instead of what actually happened." diff --git a/lib/errors/mape/Mape.md b/lib/errors/mape/Mape.md index d6fe9f66..3a938cf8 100644 --- a/lib/errors/mape/Mape.md +++ b/lib/errors/mape/Mape.md @@ -1,4 +1,21 @@ -# MAPE: Mean Absolute Percentage Error +# MAPE: Mean Absolute Percentage Error + +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Error Metric | +| **Inputs** | Source (close) | +| **Parameters** | `period` | +| **Outputs** | Single series (MAPE) | +| **Output range** | $\geq 0$ | +| **Warmup** | 1 bar | + +### TL;DR + +- Mean Absolute Percentage Error (MAPE) measures the average absolute percentage difference between actual and predicted values. +- Parameterized by `period`. +- Output range: $\geq 0$. +- Requires 1 bar of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. > "The metric that lets you compare apples to oranges, as long as you don't have any zeros." diff --git a/lib/errors/mase/Mase.md b/lib/errors/mase/Mase.md index f2bf82a0..c4b0ab81 100644 --- a/lib/errors/mase/Mase.md +++ b/lib/errors/mase/Mase.md @@ -1,4 +1,21 @@ -# MASE: Mean Absolute Scaled Error +# MASE: Mean Absolute Scaled Error + +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Error Metric | +| **Inputs** | Source (close) | +| **Parameters** | `period` | +| **Outputs** | Single series (Mase) | +| **Output range** | $\geq 0$ | +| **Warmup** | `period + 1` bars | + +### TL;DR + +- Mean Absolute Scaled Error (MASE) normalizes forecast errors by the average error of a naive "random walk" forecast (using the previous value as th... +- Parameterized by `period`. +- Output range: $\geq 0$. +- Requires `period + 1` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. > "A good forecast is one that's better than guessing. MASE tells you exactly how much better." diff --git a/lib/errors/mdae/Mdae.md b/lib/errors/mdae/Mdae.md index becb876f..9e58dcc3 100644 --- a/lib/errors/mdae/Mdae.md +++ b/lib/errors/mdae/Mdae.md @@ -1,4 +1,21 @@ -# MdAE: Median Absolute Error +# MdAE: Median Absolute Error + +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Error Metric | +| **Inputs** | Source (close) | +| **Parameters** | `period` | +| **Outputs** | Single series (Mdae) | +| **Output range** | $\geq 0$ | +| **Warmup** | `period` bars | + +### TL;DR + +- Median Absolute Error (MdAE) measures the middle value of all absolute errors. +- Parameterized by `period`. +- Output range: $\geq 0$. +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. > "When outliers scream but you need to hear the whisper of typical performance." diff --git a/lib/errors/mdape/Mdape.md b/lib/errors/mdape/Mdape.md index 9a5af812..be37b67b 100644 --- a/lib/errors/mdape/Mdape.md +++ b/lib/errors/mdape/Mdape.md @@ -1,4 +1,21 @@ -# MdAPE: Median Absolute Percentage Error +# MdAPE: Median Absolute Percentage Error + +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Error Metric | +| **Inputs** | Source (close) | +| **Parameters** | `period` | +| **Outputs** | Single series (Mdape) | +| **Output range** | $\geq 0$ | +| **Warmup** | `period` bars | + +### TL;DR + +- Median Absolute Percentage Error (MdAPE) combines the scale-independence of percentage errors with the robustness of median statistics. +- Parameterized by `period`. +- Output range: $\geq 0$. +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. > "When you need relative errors but can't trust the outliers." diff --git a/lib/errors/me/Me.md b/lib/errors/me/Me.md index defdb672..6c090ab3 100644 --- a/lib/errors/me/Me.md +++ b/lib/errors/me/Me.md @@ -1,4 +1,21 @@ -# ME: Mean Error (Mean Bias Error) +# ME: Mean Error (Mean Bias Error) + +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Error Metric | +| **Inputs** | Source (close) | +| **Parameters** | `period` | +| **Outputs** | Single series (ME) | +| **Output range** | $\geq 0$ | +| **Warmup** | 1 bar | + +### TL;DR + +- Mean Error (ME), also known as Mean Bias Error, measures the average error between actual and predicted values while preserving the sign. +- Parameterized by `period`. +- Output range: $\geq 0$. +- Requires 1 bar of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. > "Sometimes you need to know not just how wrong you are, but which direction you're wrong in." diff --git a/lib/errors/mpe/Mpe.md b/lib/errors/mpe/Mpe.md index b0e873d9..f4bfd5e4 100644 --- a/lib/errors/mpe/Mpe.md +++ b/lib/errors/mpe/Mpe.md @@ -1,4 +1,21 @@ -# MPE: Mean Percentage Error +# MPE: Mean Percentage Error + +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Error Metric | +| **Inputs** | Source (close) | +| **Parameters** | `period` | +| **Outputs** | Single series (MPE) | +| **Output range** | $\geq 0$ | +| **Warmup** | 1 bar | + +### TL;DR + +- Mean Percentage Error measures the average percentage difference between actual and predicted values while preserving the sign. +- Parameterized by `period`. +- Output range: $\geq 0$. +- Requires 1 bar of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. > "MAPE tells you how wrong you are; MPE tells you which direction you're wrong in." diff --git a/lib/errors/mrae/Mrae.md b/lib/errors/mrae/Mrae.md index 797ab816..58f16d00 100644 --- a/lib/errors/mrae/Mrae.md +++ b/lib/errors/mrae/Mrae.md @@ -1,4 +1,21 @@ -# MRAE: Mean Relative Absolute Error +# MRAE: Mean Relative Absolute Error + +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Error Metric | +| **Inputs** | Source (close) | +| **Parameters** | `period` | +| **Outputs** | Single series (MRAE) | +| **Output range** | $\geq 0$ | +| **Warmup** | 1 bar | + +### TL;DR + +- Mean Relative Absolute Error (MRAE) measures the average magnitude of errors relative to the actual values. +- Parameterized by `period`. +- Output range: $\geq 0$. +- Requires 1 bar of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. > "When you need to understand your error in the context of what you're predicting." diff --git a/lib/errors/mse/Mse.md b/lib/errors/mse/Mse.md index 8d0d8d9a..168e5dfc 100644 --- a/lib/errors/mse/Mse.md +++ b/lib/errors/mse/Mse.md @@ -1,4 +1,21 @@ -# MSE: Mean Squared Error +# MSE: Mean Squared Error + +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Error Metric | +| **Inputs** | Source (close) | +| **Parameters** | `period` | +| **Outputs** | Single series (MSE) | +| **Output range** | $\geq 0$ | +| **Warmup** | 1 bar | + +### TL;DR + +- Mean Squared Error (MSE) measures the average of the squares of the errors between actual and predicted values. +- Parameterized by `period`. +- Output range: $\geq 0$. +- Requires 1 bar of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. > "The metric that makes outliers pay dearly for their transgressions." diff --git a/lib/errors/msle/Msle.md b/lib/errors/msle/Msle.md index 201ce80a..86b35540 100644 --- a/lib/errors/msle/Msle.md +++ b/lib/errors/msle/Msle.md @@ -1,4 +1,21 @@ -# MSLE: Mean Squared Logarithmic Error +# MSLE: Mean Squared Logarithmic Error + +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Error Metric | +| **Inputs** | Source (close) | +| **Parameters** | `period` | +| **Outputs** | Single series (MSLE) | +| **Output range** | $\geq 0$ | +| **Warmup** | 1 bar | + +### TL;DR + +- Mean Squared Logarithmic Error transforms both actual and predicted values through logarithms before computing squared error. +- Parameterized by `period`. +- Output range: $\geq 0$. +- Requires 1 bar of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. > "When your data spans orders of magnitude, MSLE keeps outliers from hijacking your loss function." diff --git a/lib/errors/pseudohuber/PseudoHuber.md b/lib/errors/pseudohuber/PseudoHuber.md index c705d2de..1cdc332e 100644 --- a/lib/errors/pseudohuber/PseudoHuber.md +++ b/lib/errors/pseudohuber/PseudoHuber.md @@ -1,4 +1,21 @@ -# Pseudo-Huber: Smooth Huber Approximation +# Pseudo-Huber: Smooth Huber Approximation + +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Error Metric | +| **Inputs** | Source (close) | +| **Parameters** | `period`, `delta` (default 1.0) | +| **Outputs** | Single series (UNKNOWN) | +| **Output range** | $\geq 0$ | +| **Warmup** | 1 bar | + +### TL;DR + +- Pseudo-Huber Loss (also called Charbonnier Loss) is a smooth approximation to the Huber loss function. +- Parameterized by `period`, `delta` (default 1.0). +- Output range: $\geq 0$. +- Requires 1 bar of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. > "All the robustness of Huber, none of the discontinuities." diff --git a/lib/errors/quantileloss/QuantileLoss.md b/lib/errors/quantileloss/QuantileLoss.md index f536643f..ff024fad 100644 --- a/lib/errors/quantileloss/QuantileLoss.md +++ b/lib/errors/quantileloss/QuantileLoss.md @@ -1,4 +1,21 @@ -# Quantile Loss: Pinball Loss Function +# Quantile Loss: Pinball Loss Function + +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Error Metric | +| **Inputs** | Source (close) | +| **Parameters** | `period`, `quantile` (default 0.5) | +| **Outputs** | Single series (Quantile) | +| **Output range** | $\geq 0$ | +| **Warmup** | 1 bar | + +### TL;DR + +- Quantile Loss (also called Pinball Loss) measures prediction accuracy with asymmetric penalties for over-prediction versus under-prediction. +- Parameterized by `period`, `quantile` (default 0.5). +- Output range: $\geq 0$. +- Requires 1 bar of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. > "When over-prediction and under-prediction carry different costs, quantiles find the balance." diff --git a/lib/errors/rae/Rae.md b/lib/errors/rae/Rae.md index fa0fe9c4..cd0c3796 100644 --- a/lib/errors/rae/Rae.md +++ b/lib/errors/rae/Rae.md @@ -1,4 +1,21 @@ -# RAE: Relative Absolute Error +# RAE: Relative Absolute Error + +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Error Metric | +| **Inputs** | Source (close) | +| **Parameters** | `period` | +| **Outputs** | Single series (Rae) | +| **Output range** | $\geq 0$ | +| **Warmup** | `period` bars | + +### TL;DR + +- Relative Absolute Error (RAE) measures the total absolute error of predictions relative to the total absolute error of a simple baseline predictor ... +- Parameterized by `period`. +- Output range: $\geq 0$. +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. > "How much better than just guessing the mean? RAE gives you the ratio." diff --git a/lib/errors/rmse/Rmse.md b/lib/errors/rmse/Rmse.md index a81f66d5..904c4d72 100644 --- a/lib/errors/rmse/Rmse.md +++ b/lib/errors/rmse/Rmse.md @@ -1,4 +1,21 @@ -# RMSE: Root Mean Squared Error +# RMSE: Root Mean Squared Error + +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Error Metric | +| **Inputs** | Source (close) | +| **Parameters** | `period` | +| **Outputs** | Single series (RMSE) | +| **Output range** | $\geq 0$ | +| **Warmup** | 1 bar | + +### TL;DR + +- Root Mean Squared Error (RMSE) is the square root of MSE, providing an error metric in the same units as the original data while retaining sensitiv... +- Parameterized by `period`. +- Output range: $\geq 0$. +- Requires 1 bar of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. > "MSE's more interpretable sibling that speaks the language of your data." diff --git a/lib/errors/rmsle/Rmsle.md b/lib/errors/rmsle/Rmsle.md index 85f83b46..be0a42b5 100644 --- a/lib/errors/rmsle/Rmsle.md +++ b/lib/errors/rmsle/Rmsle.md @@ -1,4 +1,21 @@ -# RMSLE: Root Mean Squared Logarithmic Error +# RMSLE: Root Mean Squared Logarithmic Error + +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Error Metric | +| **Inputs** | Source (close) | +| **Parameters** | `period` | +| **Outputs** | Single series (RMSLE) | +| **Output range** | $\geq 0$ | +| **Warmup** | 1 bar | + +### TL;DR + +- Root Mean Squared Logarithmic Error is the square root of MSLE, providing an error metric in log-scale units. +- Parameterized by `period`. +- Output range: $\geq 0$. +- Requires 1 bar of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. > "RMSLE: because sometimes your errors need to be measured in decades, not dollars." diff --git a/lib/errors/rse/Rse.md b/lib/errors/rse/Rse.md index 7a24e21b..82c0d7a0 100644 --- a/lib/errors/rse/Rse.md +++ b/lib/errors/rse/Rse.md @@ -1,4 +1,21 @@ -# RSE: Relative Squared Error +# RSE: Relative Squared Error + +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Error Metric | +| **Inputs** | Source (close) | +| **Parameters** | `period` | +| **Outputs** | Single series (Rse) | +| **Output range** | $\geq 0$ | +| **Warmup** | `period` bars | + +### TL;DR + +- Relative Squared Error (RSE) measures the total squared error of predictions relative to the total squared error of a simple baseline predictor tha... +- Parameterized by `period`. +- Output range: $\geq 0$. +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. > "The squared error version of RAE. RSE and R² are two sides of the same coin: R² = 1 - RSE." diff --git a/lib/errors/rsquared/Rsquared.md b/lib/errors/rsquared/Rsquared.md index 2d474753..b7cbb693 100644 --- a/lib/errors/rsquared/Rsquared.md +++ b/lib/errors/rsquared/Rsquared.md @@ -1,4 +1,21 @@ -# R²: Coefficient of Determination +# R²: Coefficient of Determination + +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Error Metric | +| **Inputs** | Source (close) | +| **Parameters** | `period` | +| **Outputs** | Single series (R) | +| **Output range** | $\geq 0$ | +| **Warmup** | `period` bars | + +### TL;DR + +- The Coefficient of Determination (R²) measures the proportion of variance in the actual values that is predictable from the predicted values. +- Parameterized by `period`. +- Output range: $\geq 0$. +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. > "R² tells you how much of the variance in actual values is explained by your predictions. It's the statistician's favorite metric for good reason." diff --git a/lib/errors/smape/Smape.md b/lib/errors/smape/Smape.md index 52551f10..7880f283 100644 --- a/lib/errors/smape/Smape.md +++ b/lib/errors/smape/Smape.md @@ -1,4 +1,21 @@ -# SMAPE: Symmetric Mean Absolute Percentage Error +# SMAPE: Symmetric Mean Absolute Percentage Error + +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Error Metric | +| **Inputs** | Source (close) | +| **Parameters** | `period` | +| **Outputs** | Single series (SMAPE) | +| **Output range** | $\geq 0$ | +| **Warmup** | 1 bar | + +### TL;DR + +- Symmetric Mean Absolute Percentage Error addresses a fundamental asymmetry in MAPE: the fact that over-predictions and under-predictions of the sam... +- Parameterized by `period`. +- Output range: $\geq 0$. +- Requires 1 bar of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. > "MAPE punishes based on who's right; SMAPE punishes based on how different they are." diff --git a/lib/errors/theilu/TheilU.md b/lib/errors/theilu/TheilU.md index 8cb1479e..de47b848 100644 --- a/lib/errors/theilu/TheilU.md +++ b/lib/errors/theilu/TheilU.md @@ -1,4 +1,21 @@ -# Theil's U: Theil's U Statistic +# Theil's U: Theil's U Statistic + +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Error Metric | +| **Inputs** | Source (close) | +| **Parameters** | `period` | +| **Outputs** | Single series (TheilU) | +| **Output range** | $\geq 0$ | +| **Warmup** | `period` bars | + +### TL;DR + +- Theil's U Statistic measures forecast accuracy relative to a naive no-change forecast. +- Parameterized by `period`. +- Output range: $\geq 0$. +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. > "The forecast that matters is the one that beats a naive guess." diff --git a/lib/errors/tukeybiweight/TukeyBiweight.md b/lib/errors/tukeybiweight/TukeyBiweight.md index c2a4b43b..e390b192 100644 --- a/lib/errors/tukeybiweight/TukeyBiweight.md +++ b/lib/errors/tukeybiweight/TukeyBiweight.md @@ -1,4 +1,21 @@ -# Tukey's Biweight: Robust Loss Function +# Tukey's Biweight: Robust Loss Function + +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Error Metric | +| **Inputs** | Source (close) | +| **Parameters** | `period`, `c` (default DefaultC) | +| **Outputs** | Single series (UNKNOWN) | +| **Output range** | $\geq 0$ | +| **Warmup** | 1 bar | + +### TL;DR + +- Tukey's Biweight (also called Bisquare) is a redescending M-estimator that completely ignores errors beyond a threshold. +- Parameterized by `period`, `c` (default defaultc). +- Output range: $\geq 0$. +- Requires 1 bar of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. > "When outliers need to be silenced, not just quieted." diff --git a/lib/errors/wmape/Wmape.md b/lib/errors/wmape/Wmape.md index f8d3ce1c..2dd10a86 100644 --- a/lib/errors/wmape/Wmape.md +++ b/lib/errors/wmape/Wmape.md @@ -1,4 +1,21 @@ -# WMAPE: Weighted Mean Absolute Percentage Error +# WMAPE: Weighted Mean Absolute Percentage Error + +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Error Metric | +| **Inputs** | Source (close) | +| **Parameters** | `period` | +| **Outputs** | Single series (Wmape) | +| **Output range** | $\geq 0$ | +| **Warmup** | `period` bars | + +### TL;DR + +- Weighted Mean Absolute Percentage Error (WMAPE) adjusts MAPE by weighting each error by the magnitude of the actual value. +- Parameterized by `period`. +- Output range: $\geq 0$. +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. > "When not all errors are created equal, weight them by what matters." diff --git a/lib/errors/wrmse/Wrmse.md b/lib/errors/wrmse/Wrmse.md index 637781bc..1981e738 100644 --- a/lib/errors/wrmse/Wrmse.md +++ b/lib/errors/wrmse/Wrmse.md @@ -1,5 +1,22 @@ # WRMSE: Weighted Root Mean Squared Error +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Error Metric | +| **Inputs** | Source (close) | +| **Parameters** | `period` | +| **Outputs** | Single series (Wrmse) | +| **Output range** | $\geq 0$ | +| **Warmup** | `period` bars | + +### TL;DR + +- WRMSE extends the classic RMSE by incorporating weights for each observation, enabling analysts to emphasize critical data points such as recent ob... +- Parameterized by `period`. +- Output range: $\geq 0$. +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "Not all errors are created equal—WRMSE lets you decide which ones matter most." WRMSE extends the classic RMSE by incorporating weights for each observation, enabling analysts to emphasize critical data points such as recent observations, high-volume periods, or specific market regimes. When all weights are equal, WRMSE reduces exactly to RMSE, making it a strict generalization. This implementation uses dual RingBuffers for O(1) streaming updates with periodic resync to manage floating-point drift. @@ -169,4 +186,4 @@ WRMSE is validated by: - Aitken, A.C. (1936). "On Least Squares and Linear Combinations of Observations." *Proceedings of the Royal Society of Edinburgh*. - Gauss, C.F. (1809). *Theoria Motus Corporum Coelestium*. (Foundation of least squares theory) -- Greene, W.H. (2012). *Econometric Analysis*. 7th ed. Chapter 9: Generalized Least Squares. \ No newline at end of file +- Greene, W.H. (2012). *Econometric Analysis*. 7th ed. Chapter 9: Generalized Least Squares. diff --git a/lib/feeds/IFeed.md b/lib/feeds/IFeed.md index c5f2a912..af56bfd9 100644 --- a/lib/feeds/IFeed.md +++ b/lib/feeds/IFeed.md @@ -1,5 +1,22 @@ # IFeed Interface +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Feed | +| **Inputs** | OHLCV bar (TBar) | +| **Parameters** | None | +| **Outputs** | Single series (IFeed) | +| **Output range** | Varies (see docs) | +| **Warmup** | 1 bar | + +### TL;DR + +- `IFeed` defines the standard contract for all data feeds in QuanTAlib, ensuring consistent behavior across different data sources (synthetic, file-... +- No configurable parameters; computation is stateless per bar. +- Output range: Varies (see docs). +- Requires 1 bar of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + `IFeed` defines the standard contract for all data feeds in QuanTAlib, ensuring consistent behavior across different data sources (synthetic, file-based, or live API). ## Key Concepts diff --git a/lib/feeds/csvfeed/CsvFeed.md b/lib/feeds/csvfeed/CsvFeed.md index 128b575e..9fbde1ed 100644 --- a/lib/feeds/csvfeed/CsvFeed.md +++ b/lib/feeds/csvfeed/CsvFeed.md @@ -1,5 +1,22 @@ # CsvFeed Class +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Feed | +| **Inputs** | OHLCV bar (TBar) | +| **Parameters** | `filePath` | +| **Outputs** | Single series (CsvFeed) | +| **Output range** | Varies (see docs) | +| **Warmup** | 1 bar | + +### TL;DR + +- `CsvFeed` is a file-based feed implementation that loads historical OHLCV data from CSV files. +- Parameterized by `filepath`. +- Output range: Varies (see docs). +- Requires 1 bar of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + `CsvFeed` is a file-based feed implementation that loads historical OHLCV data from CSV files. It supports both streaming access (simulating real-time playback) and batch retrieval. ## Key Features diff --git a/lib/feeds/gbm/GBM.md b/lib/feeds/gbm/GBM.md index 292cb831..35f46011 100644 --- a/lib/feeds/gbm/GBM.md +++ b/lib/feeds/gbm/GBM.md @@ -1,5 +1,22 @@ # GBM Class +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Feed | +| **Inputs** | OHLCV bar (TBar) | +| **Parameters** | None | +| **Outputs** | Single series (GBM) | +| **Output range** | Varies (see docs) | +| **Warmup** | 1 bar | + +### TL;DR + +- `GBM` (Geometric Brownian Motion) is a synthetic data generator that simulates realistic financial price movements. +- No configurable parameters; computation is stateless per bar. +- Output range: Varies (see docs). +- Requires 1 bar of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + `GBM` (Geometric Brownian Motion) is a synthetic data generator that simulates realistic financial price movements. It is useful for testing indicators, strategies, and system performance without relying on external data files. ## Key Features diff --git a/lib/filters/agc/Agc.md b/lib/filters/agc/Agc.md index ebbb93ed..3895e088 100644 --- a/lib/filters/agc/Agc.md +++ b/lib/filters/agc/Agc.md @@ -1,4 +1,21 @@ -# AGC: Ehlers Automatic Gain Control +# AGC: Ehlers Automatic Gain Control + +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Filter | +| **Inputs** | Source (close) | +| **Parameters** | `decay` (default 0.991) | +| **Outputs** | Single series (AGC) | +| **Output range** | Tracks input | +| **Warmup** | `1` bars | + +### TL;DR + +- The Automatic Gain Control normalizes any oscillating signal to the \[-1, +1\] range through exponential peak tracking. +- Parameterized by `decay` (default 0.991). +- Output range: Tracks input. +- Requires `1` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. > "The purpose of the AGC is to normalize the amplitude of any indicator to unity." — John F. Ehlers, TASC January 2015 diff --git a/lib/filters/alaguerre/ALaguerre.md b/lib/filters/alaguerre/ALaguerre.md index c0b7c460..5b537fad 100644 --- a/lib/filters/alaguerre/ALaguerre.md +++ b/lib/filters/alaguerre/ALaguerre.md @@ -1,4 +1,21 @@ -# ALAGUERRE: Ehlers Adaptive Laguerre Filter +# ALAGUERRE: Ehlers Adaptive Laguerre Filter + +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Filter | +| **Inputs** | Source (close) | +| **Parameters** | `length` (default 20), `medianLength` (default 5) | +| **Outputs** | Single series (ALaguerre) | +| **Output range** | Tracks input | +| **Warmup** | 1 bar | + +### TL;DR + +- The Adaptive Laguerre Filter extends Ehlers' four-element all-pass cascade by replacing the fixed damping factor with a per-bar adaptive alpha deri... +- Parameterized by `length` (default 20), `medianlength` (default 5). +- Output range: Tracks input. +- Requires 1 bar of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. > "The best filter is one that knows when to listen closely and when to smooth aggressively." -- John F. Ehlers (paraphrased) @@ -107,7 +124,7 @@ O(1) per bar. Four recursive stages with precomputed gamma constant. ~38 cycles/ | Operation | Vectorizable? | Notes | | :--- | :---: | :--- | -| Laguerre stage recursion | No | Each stage L[k][n] depends on L[k-1][n] and L[k][n-1] | +| Laguerre stage recursion | No | Each stage `L[k][n]` depends on `L[k-1][n]` and `L[k][n-1]` | | Weighted combination | No | Only 4 terms; SIMD overhead not worthwhile | Cascaded IIR stages cannot be vectorized. Batch throughput: ~38 cy/bar. diff --git a/lib/filters/baxterking/BaxterKing.md b/lib/filters/baxterking/BaxterKing.md index fc6524b1..b2acd5bb 100644 --- a/lib/filters/baxterking/BaxterKing.md +++ b/lib/filters/baxterking/BaxterKing.md @@ -1,4 +1,21 @@ -# BK: Baxter-King Band-Pass Filter +# BK: Baxter-King Band-Pass Filter + +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Filter | +| **Inputs** | Source (close) | +| **Parameters** | `pLow` (default 6), `pHigh` (default 32), `k` (default 12) | +| **Outputs** | Single series (BaxterKing) | +| **Output range** | Tracks input | +| **Warmup** | 1 bar | + +### TL;DR + +- The **Baxter-King Band-Pass Filter** is a symmetric finite impulse response (FIR) filter that approximates the ideal spectral band-pass by truncati... +- Parameterized by `plow` (default 6), `phigh` (default 32), `k` (default 12). +- Output range: Tracks input. +- Requires 1 bar of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. > "The business cycle is whatever remains after you strip away the trend and the noise. Baxter and King figured out the stripping." diff --git a/lib/filters/bessel/Bessel.md b/lib/filters/bessel/Bessel.md index 784d898e..6e3239cb 100644 --- a/lib/filters/bessel/Bessel.md +++ b/lib/filters/bessel/Bessel.md @@ -1,4 +1,21 @@ -# BESSEL: Bessel Filter +# BESSEL: Bessel Filter + +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Filter | +| **Inputs** | Source (close) | +| **Parameters** | `length` | +| **Outputs** | Single series (Bessel) | +| **Output range** | Tracks input | +| **Warmup** | 1 bar | + +### TL;DR + +- The Bessel Filter is a 2nd-order low-pass IIR filter designed to preserve the **shape** and **timing** of price moves. +- Parameterized by `length`. +- Output range: Tracks input. +- Requires 1 bar of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. > When you care more about *when* the market turns than how aggressively you can torture the noise, you reach for a Bessel. diff --git a/lib/filters/bilateral/Bilateral.md b/lib/filters/bilateral/Bilateral.md index b44b3f04..7e5c1443 100644 --- a/lib/filters/bilateral/Bilateral.md +++ b/lib/filters/bilateral/Bilateral.md @@ -1,4 +1,21 @@ -# Bilateral Filter +# Bilateral Filter + +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Filter | +| **Inputs** | Source (close) | +| **Parameters** | `period`, `sigmaSRatio` (default 0.5), `sigmaRMult` (default 1.0) | +| **Outputs** | Single series (Bilateral) | +| **Output range** | Tracks input | +| **Warmup** | `period` bars | + +### TL;DR + +- The Bilateral Filter is a non-linear, edge-preserving, and noise-reducing smoothing filter. +- Parameterized by `period`, `sigmasratio` (default 0.5), `sigmarmult` (default 1.0). +- Output range: Tracks input. +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. > "Smoothing without blurring edges? It's not magic, it's just math." diff --git a/lib/filters/bpf/Bpf.md b/lib/filters/bpf/Bpf.md index e415af0f..27a161ea 100644 --- a/lib/filters/bpf/Bpf.md +++ b/lib/filters/bpf/Bpf.md @@ -1,4 +1,21 @@ -# BPF (Bandpass Filter) +# BPF (Bandpass Filter) + +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Filter | +| **Inputs** | Source (close) | +| **Parameters** | `lowerPeriod`, `upperPeriod` | +| **Outputs** | Single series (BPF) | +| **Output range** | Tracks input | +| **Warmup** | `Math.Max(lowerPeriod, upperPeriod)` bars | + +### TL;DR + +- The **BPF** (BandPass Filter) is a second-order IIR architecture designed to surgically excise specific frequency components from a time series. +- Parameterized by `lowerperiod`, `upperperiod`. +- Output range: Tracks input. +- Requires `Math.Max(lowerPeriod, upperPeriod)` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. > "Most market data is noise. A sliver is signal. The rest is just detailed evidence of human panic." diff --git a/lib/filters/butter2/Butter2.md b/lib/filters/butter2/Butter2.md index 9c8fcfe9..9bc7385b 100644 --- a/lib/filters/butter2/Butter2.md +++ b/lib/filters/butter2/Butter2.md @@ -1,4 +1,21 @@ -# BUTTER2: Ehlers 2-Pole Butterworth Filter +# BUTTER2: Ehlers 2-Pole Butterworth Filter + +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Filter | +| **Inputs** | Source (close) | +| **Parameters** | `period` | +| **Outputs** | Single series (Butter2) | +| **Output range** | Tracks input | +| **Warmup** | `4 * period` bars | + +### TL;DR + +- The 2-Pole Butterworth Filter (BUTTER2) is a signal processing tool designed to provide maximally flat frequency response in the passband. +- Parameterized by `period`. +- Output range: Tracks input. +- Requires `4 * period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. > "Maximally flat frequency response in the passband." diff --git a/lib/filters/butter3/Butter3.md b/lib/filters/butter3/Butter3.md index 41c20563..38c1cf12 100644 --- a/lib/filters/butter3/Butter3.md +++ b/lib/filters/butter3/Butter3.md @@ -1,4 +1,21 @@ -# BUTTER3: Ehlers 3-Pole Butterworth Filter +# BUTTER3: Ehlers 3-Pole Butterworth Filter + +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Filter | +| **Inputs** | Source (close) | +| **Parameters** | `period` | +| **Outputs** | Single series (Butter3) | +| **Output range** | Tracks input | +| **Warmup** | `6 * period` bars | + +### TL;DR + +- The 3-Pole Butterworth Filter (BUTTER3) extends the classic Butterworth design to third order, providing -60 dB/decade rolloff compared to -40 dB/d... +- Parameterized by `period`. +- Output range: Tracks input. +- Requires `6 * period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. > "Steeper rolloff demands a third pole." diff --git a/lib/filters/cfitz/Cfitz.md b/lib/filters/cfitz/Cfitz.md index 8c1ddf9d..56ec9909 100644 --- a/lib/filters/cfitz/Cfitz.md +++ b/lib/filters/cfitz/Cfitz.md @@ -1,4 +1,21 @@ -# CFITZ: Christiano-Fitzgerald Band-Pass Filter +# CFITZ: Christiano-Fitzgerald Band-Pass Filter + +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Filter | +| **Inputs** | Source (close) | +| **Parameters** | `pLow` (default 6), `pHigh` (default 32) | +| **Outputs** | Single series (Cfitz) | +| **Output range** | Tracks input | +| **Warmup** | `2` bars | + +### TL;DR + +- The **Christiano-Fitzgerald Band-Pass Filter** is an asymmetric full-sample filter that approximates the ideal spectral band-pass by using time-var... +- Parameterized by `plow` (default 6), `phigh` (default 32). +- Output range: Tracks input. +- Requires `2` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. ## Overview diff --git a/lib/filters/cheby1/Cheby1.md b/lib/filters/cheby1/Cheby1.md index a0dbe5bf..431f8946 100644 --- a/lib/filters/cheby1/Cheby1.md +++ b/lib/filters/cheby1/Cheby1.md @@ -1,4 +1,21 @@ -# CHEBY1: Chebyshev Type I Lowpass Filter +# CHEBY1: Chebyshev Type I Lowpass Filter + +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Filter | +| **Inputs** | Source (close) | +| **Parameters** | `period`, `ripple` (default 1.0) | +| **Outputs** | Single series (Cheby1) | +| **Output range** | Tracks input | +| **Warmup** | `period` bars | + +### TL;DR + +- The Chebyshev Type I filter minimizes the error between the idealized and the actual filter characteristic over the range of the passband, but with... +- Parameterized by `period`, `ripple` (default 1.0). +- Output range: Tracks input. +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. The Chebyshev Type I filter minimizes the error between the idealized and the actual filter characteristic over the range of the passband, but with ripples in the passband. This type of filter has a steeper rolloff and more passband ripple (type I) or stopband ripple (type II) than Butterworth filters. diff --git a/lib/filters/cheby2/Cheby2.md b/lib/filters/cheby2/Cheby2.md index 3281c901..ad731c20 100644 --- a/lib/filters/cheby2/Cheby2.md +++ b/lib/filters/cheby2/Cheby2.md @@ -1,4 +1,21 @@ -# CHEBY2 (Chebyshev Type II / Inverse Chebyshev) +# CHEBY2 (Chebyshev Type II / Inverse Chebyshev) + +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Filter | +| **Inputs** | Source (close) | +| **Parameters** | `period`, `attenuation` (default 5.0) | +| **Outputs** | Single series (Cheby2) | +| **Output range** | Tracks input | +| **Warmup** | `period` bars | + +### TL;DR + +- A Chebyshev Type II filter (also known as Inverse Chebyshev) with O(1) complexity. +- Parameterized by `period`, `attenuation` (default 5.0). +- Output range: Tracks input. +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. A Chebyshev Type II filter (also known as Inverse Chebyshev) with O(1) complexity. Unlike the Type I filter, Type II is maximally flat in the passband (like Butterworth) but has equiripple in the stopband. diff --git a/lib/filters/edcf/Edcf.md b/lib/filters/edcf/Edcf.md index 9aa953fd..9c14754b 100644 --- a/lib/filters/edcf/Edcf.md +++ b/lib/filters/edcf/Edcf.md @@ -1,4 +1,21 @@ -# EDCF: Ehlers Distance Coefficient Filter +# EDCF: Ehlers Distance Coefficient Filter + +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Filter | +| **Inputs** | Source (close) | +| **Parameters** | `length` (default 15) | +| **Outputs** | Single series (Edcf) | +| **Output range** | Tracks input | +| **Warmup** | 1 bar | + +### TL;DR + +- The **Ehlers Distance Coefficient Filter (EDCF)** is a nonlinear adaptive FIR filter created by John F. +- Parameterized by `length` (default 15). +- Output range: Tracks input. +- Requires 1 bar of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. ## Overview diff --git a/lib/filters/elliptic/Elliptic.md b/lib/filters/elliptic/Elliptic.md index 0a09bf8c..426df727 100644 --- a/lib/filters/elliptic/Elliptic.md +++ b/lib/filters/elliptic/Elliptic.md @@ -1,4 +1,21 @@ -# ELLIPTIC: 2nd Order Elliptic Lowpass Filter +# ELLIPTIC: 2nd Order Elliptic Lowpass Filter + +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Filter | +| **Inputs** | Source (close) | +| **Parameters** | `period` | +| **Outputs** | Single series (Elliptic) | +| **Output range** | Tracks input | +| **Warmup** | `period` bars | + +### TL;DR + +- The Elliptic filter (or Cauer filter for the history buffs) is the uncompromising extremist of linear filtering. +- Parameterized by `period`. +- Output range: Tracks input. +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. > "If you want a vertical cliff, you have to accept a few bumps on the plateau." diff --git a/lib/filters/gauss/Gauss.md b/lib/filters/gauss/Gauss.md index 1bce7bd9..4a4082cd 100644 --- a/lib/filters/gauss/Gauss.md +++ b/lib/filters/gauss/Gauss.md @@ -1,4 +1,21 @@ -# Gauss: Gaussian Filter +# Gauss: Gaussian Filter + +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Filter | +| **Inputs** | Source (close) | +| **Parameters** | `sigma` (default 1.0) | +| **Outputs** | Single series (Gauss) | +| **Output range** | Tracks input | +| **Warmup** | 1 bar | + +### TL;DR + +- Gauss (Gaussian Filter) is a smoothing filter that applies a Gaussian kernel to time series data. +- Parameterized by `sigma` (default 1.0). +- Output range: Tracks input. +- Requires 1 bar of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. > "SMA smears data like cheap paint. Gaussian filtering respects the signal's soul." diff --git a/lib/filters/hann/Hann.md b/lib/filters/hann/Hann.md index bad60a40..d45b29a6 100644 --- a/lib/filters/hann/Hann.md +++ b/lib/filters/hann/Hann.md @@ -1,4 +1,21 @@ -# Hann: Hann FIR Filter +# Hann: Hann FIR Filter + +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Filter | +| **Inputs** | Source (close) | +| **Parameters** | `length` | +| **Outputs** | Single series (Hann) | +| **Output range** | Tracks input | +| **Warmup** | 1 bar | + +### TL;DR + +- Hann (Hann Filter) is a Finite Impulse Response (FIR) smoothing filter that applies a Hann window to time series data. +- Parameterized by `length`. +- Output range: Tracks input. +- Requires 1 bar of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. > "The Hanning window whispers where the Boxcar screams. Smoothness is not just an aesthetic; it's a mathematical necessity." diff --git a/lib/filters/hp/Hp.md b/lib/filters/hp/Hp.md index 9768679a..a07fcdf8 100644 --- a/lib/filters/hp/Hp.md +++ b/lib/filters/hp/Hp.md @@ -1,4 +1,21 @@ -# HP - Hodrick-Prescott Filter +# HP - Hodrick-Prescott Filter + +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Filter | +| **Inputs** | Source (close) | +| **Parameters** | `lambda` (default 1600.0) | +| **Outputs** | Single series (HP) | +| **Output range** | Tracks input | +| **Warmup** | 1 bar | + +### TL;DR + +- The Hodrick-Prescott (HP) filter is a widely used tool in macroeconomics for separating the cyclical component of a time series from raw data. +- Parameterized by `lambda` (default 1600.0). +- Output range: Tracks input. +- Requires 1 bar of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. > "Trends are not lines; they are curves that we simplify for our sanity, often at the cost of reality." @@ -94,4 +111,4 @@ TValue trend = hp.Update(new TValue(time, price)); // Static batch calculation double[] prices = ...; double[] trend = new double[prices.Length]; -Hp.Calculate(prices, trend, 1600); \ No newline at end of file +Hp.Calculate(prices, trend, 1600); diff --git a/lib/filters/hpf/Hpf.md b/lib/filters/hpf/Hpf.md index be8371f3..1c54618b 100644 --- a/lib/filters/hpf/Hpf.md +++ b/lib/filters/hpf/Hpf.md @@ -1,4 +1,21 @@ -# HPF: Ehlers Highpass Filter +# HPF: Ehlers Highpass Filter + +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Filter | +| **Inputs** | Source (close) | +| **Parameters** | `length` (default 40) | +| **Outputs** | Single series (HPF) | +| **Output range** | Tracks input | +| **Warmup** | 1 bar | + +### TL;DR + +- The 2-Pole Highpass Filter (HPF) is designed to separate high-frequency components (like cycles and noise) from the underlying trend. +- Parameterized by `length` (default 40). +- Output range: Tracks input. +- Requires 1 bar of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. > "Noise is just signal you haven't figured out how to filter yet. Or maybe, it's the only signal that matters." diff --git a/lib/filters/kalman/Kalman.md b/lib/filters/kalman/Kalman.md index f67ad53a..acd879a1 100644 --- a/lib/filters/kalman/Kalman.md +++ b/lib/filters/kalman/Kalman.md @@ -1,4 +1,21 @@ -# Kalman Filter (KALMAN) +# Kalman Filter (KALMAN) + +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Filter | +| **Inputs** | Source (close) | +| **Parameters** | `q` (default 0.01), `r` (default 0.1) | +| **Outputs** | Single series (Kalman) | +| **Output range** | Tracks input | +| **Warmup** | `10` bars | + +### TL;DR + +- The **Kalman Filter** is a recursive algorithm that estimates the state of a dynamic system from a series of incomplete and noisy measurements. +- Parameterized by `q` (default 0.01), `r` (default 0.1). +- Output range: Tracks input. +- Requires `10` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. > "Prediction is very difficult, especially if it's about the future." — Niels Bohr. The Kalman Filter doesn't just predict; it optimally estimates the present by balancing what it thinks should happen with what actually happened. @@ -108,4 +125,4 @@ Kalman.Calculate(inputs, outputs, q: 0.05, r: 0.5); // Chaining var source = new TSeries(); var kf1 = new Kalman(source, q: 0.01, r: 0.1); -var kf2 = new Kalman(kf1, q: 0.001, r: 0.1); // Double smoothing \ No newline at end of file +var kf2 = new Kalman(kf1, q: 0.001, r: 0.1); // Double smoothing diff --git a/lib/filters/laguerre/Laguerre.md b/lib/filters/laguerre/Laguerre.md index e6387ae7..391b255e 100644 --- a/lib/filters/laguerre/Laguerre.md +++ b/lib/filters/laguerre/Laguerre.md @@ -1,5 +1,22 @@ # LAGUERRE: Ehlers Laguerre Filter +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Filter | +| **Inputs** | Source (close) | +| **Parameters** | `gamma` (default 0.8) | +| **Outputs** | Single series (Laguerre) | +| **Output range** | Tracks input | +| **Warmup** | `WarmupBars` bars | + +### TL;DR + +- The Laguerre Filter is a four-element IIR (Infinite Impulse Response) filter designed by John F. +- Parameterized by `gamma` (default 0.8). +- Output range: Tracks input. +- Requires `WarmupBars` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "The problem with conventional filters is that they use unit delays. All-pass filters replace unit delays with frequency-dependent delays, and that changes everything." — John F. Ehlers ## Introduction diff --git a/lib/filters/lms/Lms.md b/lib/filters/lms/Lms.md index ab351002..6b5a4823 100644 --- a/lib/filters/lms/Lms.md +++ b/lib/filters/lms/Lms.md @@ -1,4 +1,21 @@ -# LMS: Least Mean Squares Adaptive Filter +# LMS: Least Mean Squares Adaptive Filter + +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Filter | +| **Inputs** | Source (close) | +| **Parameters** | `order` (default 16), `mu` (default 0.5) | +| **Outputs** | Single series (LMS) | +| **Output range** | Tracks input | +| **Warmup** | `order + 1` bars | + +### TL;DR + +- The **Least Mean Squares (LMS) Adaptive Filter** is the Widrow-Hoff adaptive FIR filter, the simplest and most widely deployed adaptive algorithm i... +- Parameterized by `order` (default 16), `mu` (default 0.5). +- Output range: Tracks input. +- Requires `order + 1` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. > "The filter that learns from its mistakes, one gradient step at a time." diff --git a/lib/filters/loess/Loess.md b/lib/filters/loess/Loess.md index a9779f90..56af0678 100644 --- a/lib/filters/loess/Loess.md +++ b/lib/filters/loess/Loess.md @@ -1,4 +1,21 @@ -# Loess: Locally Estimated Scatterplot Smoothing +# Loess: Locally Estimated Scatterplot Smoothing + +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Filter | +| **Inputs** | Source (close) | +| **Parameters** | `period` | +| **Outputs** | Single series (Loess) | +| **Output range** | Tracks input | +| **Warmup** | `Period` bars | + +### TL;DR + +- Locally Estimated Scatterplot Smoothing (LOESS) applies a weighted linear regression over a localized window of nearest neighbors. +- Parameterized by `period`. +- Output range: Tracks input. +- Requires `Period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. > "When global models fail, act locally. LOESS fits the data by ignoring the noise and embracing the neighborhood." diff --git a/lib/filters/modf/Modf.md b/lib/filters/modf/Modf.md index 65a01ca6..d7c76ab4 100644 --- a/lib/filters/modf/Modf.md +++ b/lib/filters/modf/Modf.md @@ -1,4 +1,21 @@ -# MODF: Modular Filter +# MODF: Modular Filter + +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Filter | +| **Inputs** | Source (close) | +| **Parameters** | `period`, `beta` (default 0.8), `feedback` (default false), `fbWeight` (default 0.5) | +| **Outputs** | Single series (MODF) | +| **Output range** | Tracks input | +| **Warmup** | `period` bars | + +### TL;DR + +- MODF is a dual-path adaptive filter that maintains separate upper and lower EMA bands with conditional state selection. +- Parameterized by `period`, `beta` (default 0.8), `feedback` (default false), `fbweight` (default 0.5). +- Output range: Tracks input. +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. > "alexgrover designed a filter with two paths — one tracks uptrends, one tracks downtrends — and a state machine that picks between them. Add a beta knob for aggression and an optional feedback loop, and you get one of the most versatile adaptive filters on TradingView." diff --git a/lib/filters/notch/Notch.md b/lib/filters/notch/Notch.md index 9b767770..1d7d0ba0 100644 --- a/lib/filters/notch/Notch.md +++ b/lib/filters/notch/Notch.md @@ -1,4 +1,21 @@ -# Notch Filter +# Notch Filter + +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Filter | +| **Inputs** | Source (close) | +| **Parameters** | `period`, `q` (default 1.0) | +| **Outputs** | Single series (Notch) | +| **Output range** | Tracks input | +| **Warmup** | `period` bars | + +### TL;DR + +- The Notch Filter is a band-stop filter with a narrow bandwidth. +- Parameterized by `period`, `q` (default 1.0). +- Output range: Tracks input. +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. > Sometimes the best way to improved signal clarity isn't amplification, but rather the surgical removal of a specific annoyance. diff --git a/lib/filters/nw/Nw.md b/lib/filters/nw/Nw.md index 778fd6ca..fdd2e068 100644 --- a/lib/filters/nw/Nw.md +++ b/lib/filters/nw/Nw.md @@ -1,4 +1,21 @@ -# NW: Nadaraya-Watson Kernel Regression +# NW: Nadaraya-Watson Kernel Regression + +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Filter | +| **Inputs** | Source (close) | +| **Parameters** | `period` (default 64), `bandwidth` (default 8.0) | +| **Outputs** | Single series (Nw) | +| **Output range** | Tracks input | +| **Warmup** | `period` bars | + +### TL;DR + +- NW computes the Nadaraya-Watson kernel regression estimator with a Gaussian kernel, producing a nonparametric smooth of the price series. +- Parameterized by `period` (default 64), `bandwidth` (default 8.0). +- Output range: Tracks input. +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. > "Nadaraya and Watson independently discovered the same thing in 1964: weight each observation by how close it is, normalize, and average. Fifty years later, it became one of the most popular nonparametric smoothers on TradingView. The math did not change; only our ability to compute it in real time." diff --git a/lib/filters/oneeuro/OneEuro.md b/lib/filters/oneeuro/OneEuro.md index bd9a51d9..9ef21f53 100644 --- a/lib/filters/oneeuro/OneEuro.md +++ b/lib/filters/oneeuro/OneEuro.md @@ -1,4 +1,21 @@ -# OneEuro — One Euro Filter +# OneEuro — One Euro Filter + +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Filter | +| **Inputs** | Source (close) | +| **Parameters** | `minCutoff` (default 1.0), `beta` (default 0.007), `dCutoff` (default 1.0) | +| **Outputs** | Single series (OneEuro) | +| **Output range** | Tracks input | +| **Warmup** | `1` bars | + +### TL;DR + +- The **One Euro Filter** (1€ Filter) is a speed-adaptive first-order low-pass filter designed to balance jitter removal against responsiveness. +- Parameterized by `mincutoff` (default 1.0), `beta` (default 0.007), `dcutoff` (default 1.0). +- Output range: Tracks input. +- Requires `1` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. The **One Euro Filter** (1€ Filter) is a speed-adaptive first-order low-pass filter designed to balance jitter removal against responsiveness. It uses an adaptive cutoff frequency: at low signal speed, a low cutoff stabilizes the signal by reducing jitter; as speed increases, the cutoff rises to reduce lag. diff --git a/lib/filters/rls/Rls.md b/lib/filters/rls/Rls.md index b10c806b..d52e161f 100644 --- a/lib/filters/rls/Rls.md +++ b/lib/filters/rls/Rls.md @@ -1,5 +1,22 @@ # RLS: Recursive Least Squares Adaptive Filter +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Filter | +| **Inputs** | Source (close) | +| **Parameters** | `order` (default 16), `lambda` (default 0.99) | +| **Outputs** | Single series (RLS) | +| **Output range** | Tracks input | +| **Warmup** | `order + 1` bars | + +### TL;DR + +- The Recursive Least Squares (RLS) adaptive filter is the Rolls-Royce of adaptive FIR filters. +- Parameterized by `order` (default 16), `lambda` (default 0.99). +- Output range: Tracks input. +- Requires `order + 1` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "The man who has no patience has no wisdom." — but waiting is not the same as convergence. RLS converges where LMS merely approaches. ## Introduction diff --git a/lib/filters/rmed/Rmed.md b/lib/filters/rmed/Rmed.md index 0162471c..377d64ef 100644 --- a/lib/filters/rmed/Rmed.md +++ b/lib/filters/rmed/Rmed.md @@ -1,4 +1,21 @@ -# RMED: Ehlers Recursive Median Filter +# RMED: Ehlers Recursive Median Filter + +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Filter | +| **Inputs** | Source (close) | +| **Parameters** | `period` (default 12) | +| **Outputs** | Single series (Rmed) | +| **Output range** | Tracks input | +| **Warmup** | 1 bar | + +### TL;DR + +- RMED applies exponential smoothing to a 5-bar running median, creating a nonlinear IIR filter that rejects impulsive spike noise while providing sm... +- Parameterized by `period` (default 12). +- Output range: Tracks input. +- Requires 1 bar of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. > "John Ehlers combined two tools that rarely meet: the median (nonlinear, spike-resistant) and the EMA (smooth, recursive). The median kills the spikes, the EMA smooths the survivors. Together they produce a filter that is both resistant and smooth." diff --git a/lib/filters/roofing/Roofing.md b/lib/filters/roofing/Roofing.md index e053b278..5c29790a 100644 --- a/lib/filters/roofing/Roofing.md +++ b/lib/filters/roofing/Roofing.md @@ -1,4 +1,21 @@ -# ROOFING: Ehlers Roofing Filter +# ROOFING: Ehlers Roofing Filter + +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Filter | +| **Inputs** | Source (close) | +| **Parameters** | `hpLength` (default 48), `ssLength` (default 10) | +| **Outputs** | Single series (ROOFING) | +| **Output range** | Tracks input | +| **Warmup** | 1 bar | + +### TL;DR + +- The **Roofing Filter** is John Ehlers' bandpass architecture designed specifically for oscillator construction. +- Parameterized by `hplength` (default 48), `sslength` (default 10). +- Output range: Tracks input. +- Requires 1 bar of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. > "The trend is your friend until it overwhelms the signal. The noise is your enemy until you mistake it for alpha." diff --git a/lib/filters/sgf/Sgf.md b/lib/filters/sgf/Sgf.md index 56844708..a33e7cd5 100644 --- a/lib/filters/sgf/Sgf.md +++ b/lib/filters/sgf/Sgf.md @@ -1,4 +1,21 @@ -# SGF: Savitzky-Golay Filter +# SGF: Savitzky-Golay Filter + +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Filter | +| **Inputs** | Source (close) | +| **Parameters** | `period`, `polyOrder` (default 2) | +| **Outputs** | Single series (Sgf) | +| **Output range** | Tracks input | +| **Warmup** | `period` bars | + +### TL;DR + +- SGF (Savitzky-Golay Filter) is a digital signal processing technique that smoothes data by fitting successive sub-sets of adjacent data points with... +- Parameterized by `period`, `polyorder` (default 2). +- Output range: Tracks input. +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. > "SMA smoothes. Savitzky-Golay understands." diff --git a/lib/filters/spbf/Spbf.md b/lib/filters/spbf/Spbf.md index e4c61eb8..c13c117c 100644 --- a/lib/filters/spbf/Spbf.md +++ b/lib/filters/spbf/Spbf.md @@ -1,4 +1,21 @@ -# SPBF: Ehlers Super Passband Filter +# SPBF: Ehlers Super Passband Filter + +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Filter | +| **Inputs** | Source (close) | +| **Parameters** | `shortPeriod` (default 40), `longPeriod` (default 60), `rmsPeriod` (default 50) | +| **Outputs** | Single series (SPBF) | +| **Output range** | Tracks input | +| **Warmup** | 1 bar | + +### TL;DR + +- The **Super Passband Filter** is John Ehlers' wide-band bandpass constructed by differencing two z-transformed EMAs with Ehlers-style smoothing ($\... +- Parameterized by `shortperiod` (default 40), `longperiod` (default 60), `rmsperiod` (default 50). +- Output range: Tracks input. +- Requires 1 bar of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. > "Two EMAs walk into a frequency domain. The difference between them is the only thing worth trading." diff --git a/lib/filters/ssf2/Ssf2.md b/lib/filters/ssf2/Ssf2.md index c773c2ac..d30b2a1e 100644 --- a/lib/filters/ssf2/Ssf2.md +++ b/lib/filters/ssf2/Ssf2.md @@ -1,4 +1,21 @@ -# SSF2: Ehlers 2-Pole Super Smoother Filter +# SSF2: Ehlers 2-Pole Super Smoother Filter + +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Filter | +| **Inputs** | Source (close) | +| **Parameters** | `period` | +| **Outputs** | Single series (Ssf2) | +| **Output range** | Tracks input | +| **Warmup** | `period` bars | + +### TL;DR + +- The 2-Pole Super Smooth Filter (SSF2) is a 2-pole Butterworth filter designed by John Ehlers. +- Parameterized by `period`. +- Output range: Tracks input. +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. > "Noise is the enemy of the trend follower. The Super Smooth Filter is the silencer." diff --git a/lib/filters/ssf3/Ssf3.md b/lib/filters/ssf3/Ssf3.md index f44ec864..f0ae994c 100644 --- a/lib/filters/ssf3/Ssf3.md +++ b/lib/filters/ssf3/Ssf3.md @@ -1,4 +1,21 @@ -# SSF3: Ehlers 3-Pole Super Smoother Filter +# SSF3: Ehlers 3-Pole Super Smoother Filter + +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Filter | +| **Inputs** | Source (close) | +| **Parameters** | `period` | +| **Outputs** | Single series (Ssf3) | +| **Output range** | Tracks input | +| **Warmup** | `6 * period` bars | + +### TL;DR + +- The 3-Pole Super Smoother Filter (SSF3) extends Ehlers' Super Smoother concept to third order, providing -60 dB/decade rolloff compared to -40 dB/d... +- Parameterized by `period`. +- Output range: Tracks input. +- Requires `6 * period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. > "Three poles, one sample. Maximum smoothing, minimum ceremony." diff --git a/lib/filters/usf/Usf.md b/lib/filters/usf/Usf.md index f04ecf99..94898642 100644 --- a/lib/filters/usf/Usf.md +++ b/lib/filters/usf/Usf.md @@ -1,4 +1,21 @@ -# USF: Ehlers Ultimate Smoother Filter +# USF: Ehlers Ultimate Smoother Filter + +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Filter | +| **Inputs** | Source (close) | +| **Parameters** | `period` | +| **Outputs** | Single series (Usf) | +| **Output range** | Tracks input | +| **Warmup** | `period` bars | + +### TL;DR + +- The Ultimate Smoother Filter (USF) is a zero-lag smoothing filter introduced by John Ehlers in the April 2024 issue of *Technical Analysis of Stock... +- Parameterized by `period`. +- Output range: Tracks input. +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. > "The Ultimate Smoother achieves superior smoothing by subtracting high-frequency components using a high-pass filter, resulting in zero lag in the passband." diff --git a/lib/filters/voss/Voss.md b/lib/filters/voss/Voss.md index af6eaaab..49a7b45e 100644 --- a/lib/filters/voss/Voss.md +++ b/lib/filters/voss/Voss.md @@ -1,4 +1,21 @@ -# VOSS: Ehlers Voss Predictive Filter +# VOSS: Ehlers Voss Predictive Filter + +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Filter | +| **Inputs** | Source (close) | +| **Parameters** | `period` (default 20), `predict` (default 3), `bandwidth` (default 0.25) | +| **Outputs** | Single series (VOSS) | +| **Output range** | Tracks input | +| **Warmup** | `period` bars | + +### TL;DR + +- The Voss Predictive Filter is a two-stage signal processing pipeline that extracts a dominant cycle from noisy price data and then predicts its fut... +- Parameterized by `period` (default 20), `predict` (default 3), `bandwidth` (default 0.25). +- Output range: Tracks input. +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. > "The best filter is one that tells you what is about to happen, not what already did." — paraphrasing Ehlers diff --git a/lib/filters/wavelet/Wavelet.md b/lib/filters/wavelet/Wavelet.md index 74192d47..abec9960 100644 --- a/lib/filters/wavelet/Wavelet.md +++ b/lib/filters/wavelet/Wavelet.md @@ -1,5 +1,22 @@ # WAVELET: Denoising Wavelet Filter +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Filter | +| **Inputs** | Source (close) | +| **Parameters** | `levels` (default 4), `threshMult` (default 1.0) | +| **Outputs** | Single series (Wavelet) | +| **Output range** | Tracks input | +| **Warmup** | 1 bar | + +### TL;DR + +- The Wavelet Denoising Filter applies an *à trous* (with holes) Haar wavelet decomposition with soft thresholding to remove high-frequency noise fro... +- Parameterized by `levels` (default 4), `threshmult` (default 1.0). +- Output range: Tracks input. +- Requires 1 bar of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "The wavelet transform is to the Fourier transform what a microscope is to a telescope: same math, different scale." ## Introduction diff --git a/lib/filters/wiener/Wiener.md b/lib/filters/wiener/Wiener.md index 731a9ece..5c0ff7b7 100644 --- a/lib/filters/wiener/Wiener.md +++ b/lib/filters/wiener/Wiener.md @@ -1,4 +1,21 @@ -# Wiener Filter +# Wiener Filter + +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Filter | +| **Inputs** | Source (close) | +| **Parameters** | `period`, `smoothPeriod` (default 10) | +| **Outputs** | Single series (Wiener) | +| **Output range** | Tracks input | +| **Warmup** | `Math.Max(period, smoothPeriod)` bars | + +### TL;DR + +- The Wiener Filter is an optimal linear filter that attempts to minimize the mean square error between the estimated random process and the desired ... +- Parameterized by `period`, `smoothperiod` (default 10). +- Output range: Tracks input. +- Requires `Math.Max(period, smoothPeriod)` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. > "The signal is the truth. The noise is just an opinion." diff --git a/lib/forecasts/afirma/Afirma.md b/lib/forecasts/afirma/Afirma.md index 83b11e39..3bf9d084 100644 --- a/lib/forecasts/afirma/Afirma.md +++ b/lib/forecasts/afirma/Afirma.md @@ -1,5 +1,22 @@ # AFIRMA: Autoregressive FIR Moving Average +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Forecast | +| **Inputs** | Source (close) | +| **Parameters** | `period`, `window` (default WindowType.BlackmanHarris), `leastSquares` (default false) | +| **Outputs** | Single series (Afirma) | +| **Output range** | Tracks input | +| **Warmup** | `period` bars | + +### TL;DR + +- AFIRMA is a Windowed Weighted Moving Average that replaces standard linear weighting with weights derived from signal processing window functions (... +- Parameterized by `period`, `window` (default windowtype.blackmanharris), `leastsquares` (default false). +- Output range: Tracks input. +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "Standard Moving Averages assume linear or exponential weights. AFIRMA asks: what if we used signal processing window functions instead?" AFIRMA is a Windowed Weighted Moving Average that replaces standard linear weighting with weights derived from signal processing window functions (Hanning, Hamming, Blackman, Blackman-Harris). This approach achieves specific frequency response characteristics tailored to noise reduction. @@ -186,4 +203,4 @@ For identical period, different windows trade smoothness for responsiveness: ## References - Harris, F. J. (1978). "On the use of windows for harmonic analysis with the discrete Fourier transform." *Proceedings of the IEEE*, 66(1), 51-83. -- Nuttall, A. H. (1981). "Some windows with very good sidelobe behavior." *IEEE Transactions on Acoustics, Speech, and Signal Processing*, 29(1), 84-91. \ No newline at end of file +- Nuttall, A. H. (1981). "Some windows with very good sidelobe behavior." *IEEE Transactions on Acoustics, Speech, and Signal Processing*, 29(1), 84-91. diff --git a/lib/momentum/asi/Asi.md b/lib/momentum/asi/Asi.md index 94cf89e6..d00bf7eb 100644 --- a/lib/momentum/asi/Asi.md +++ b/lib/momentum/asi/Asi.md @@ -1,4 +1,21 @@ -# ASI: Accumulation Swing Index +# ASI: Accumulation Swing Index + +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Momentum | +| **Inputs** | OHLCV bar (TBar) | +| **Parameters** | `limitMove` (default 3.0) | +| **Outputs** | Single series (Asi) | +| **Output range** | Varies (see docs) | +| **Warmup** | `> 2` bars | + +### TL;DR + +- The Accumulation Swing Index is Wilder's method for separating genuine breakouts from whipsaw noise. +- Parameterized by `limitmove` (default 3.0). +- Output range: Varies (see docs). +- Requires `> 2` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. > "Price tells us what is happening. The Accumulation Swing Index tells us whether to believe it." — J. Welles Wilder Jr. diff --git a/lib/momentum/bias/Bias.md b/lib/momentum/bias/Bias.md index f62d0d98..2dc3f83f 100644 --- a/lib/momentum/bias/Bias.md +++ b/lib/momentum/bias/Bias.md @@ -1,5 +1,22 @@ # BIAS: Price Deviation from Moving Average (also known as Disparity Index) +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Momentum | +| **Inputs** | Source (close) | +| **Parameters** | `period` | +| **Outputs** | Single series (Bias) | +| **Output range** | Varies (see docs) | +| **Warmup** | `period` bars | + +### TL;DR + +- The Bias indicator measures the percentage difference between the current price and its Simple Moving Average (SMA). +- Parameterized by `period`. +- Output range: Varies (see docs). +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "When traders ask 'how overbought is it?', they're really asking how far price has strayed from its anchor. Bias answers that question in percentage terms, telling you whether the current price is 5% above or 10% below its moving average. It's the market's stretch marks made visible." The Bias indicator measures the percentage difference between the current price and its Simple Moving Average (SMA). A positive bias indicates price is above the average (potentially overbought), while negative bias suggests price is below average (potentially oversold). This is one of the simplest yet most effective tools for identifying mean-reversion opportunities. diff --git a/lib/momentum/bop/Bop.md b/lib/momentum/bop/Bop.md index 7939b051..4a1a7e50 100644 --- a/lib/momentum/bop/Bop.md +++ b/lib/momentum/bop/Bop.md @@ -1,5 +1,22 @@ # BOP: Balance of Power +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Momentum | +| **Inputs** | OHLCV bar (TBar) | +| **Parameters** | None | +| **Outputs** | Single series (BOP) | +| **Output range** | Varies (see docs) | +| **Warmup** | `> 0` bars | + +### TL;DR + +- The Balance of Power measures buying versus selling pressure by comparing the body (Close minus Open) to the range (High minus Low). +- No configurable parameters; computation is stateless per bar. +- Output range: Varies (see docs). +- Requires `> 0` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "The market is a tug of war between buyers and sellers. BOP tells you who's pulling harder." The Balance of Power measures buying versus selling pressure by comparing the body (Close minus Open) to the range (High minus Low). Created by Igor Livshin in 2001, this ratio oscillates between -1 and +1, providing instantaneous momentum readings with zero lag. A stateless indicator: each bar evaluated independently, no memory of previous values required. @@ -333,4 +350,4 @@ Zero per-bar allocations. No state accumulation. Memory footprint independent of - Livshin, I. (2001). "Balance of Power." *Technical Analysis of Stocks & Commodities*, August 2001. - Investopedia. "Balance of Power (BOP) Indicator." https://www.investopedia.com/terms/b/bop.asp -- Achelis, S. (2000). *Technical Analysis from A to Z*. McGraw-Hill. (General indicator theory) \ No newline at end of file +- Achelis, S. (2000). *Technical Analysis from A to Z*. McGraw-Hill. (General indicator theory) diff --git a/lib/momentum/cci/Cci.md b/lib/momentum/cci/Cci.md index d8e8619b..105e0c44 100644 --- a/lib/momentum/cci/Cci.md +++ b/lib/momentum/cci/Cci.md @@ -1,4 +1,21 @@ -# CCI - Commodity Channel Index +# CCI - Commodity Channel Index + +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Momentum | +| **Inputs** | OHLCV bar (TBar) | +| **Parameters** | `period` (default DefaultPeriod) | +| **Outputs** | Single series (CCI) | +| **Output range** | Varies (see docs) | +| **Warmup** | `> period` bars | + +### TL;DR + +- The Commodity Channel Index (CCI) is a versatile momentum-based oscillator developed by Donald Lambert in 1980. +- Parameterized by `period` (default defaultperiod). +- Output range: Varies (see docs). +- Requires `> period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. ## Overview diff --git a/lib/momentum/cfb/Cfb.md b/lib/momentum/cfb/Cfb.md index 33c7405e..74ab8fba 100644 --- a/lib/momentum/cfb/Cfb.md +++ b/lib/momentum/cfb/Cfb.md @@ -1,5 +1,22 @@ # CFB: Jurik Composite Fractal Behavior +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Momentum | +| **Inputs** | Source (close) | +| **Parameters** | int[]? lengths = null | +| **Outputs** | Single series (CFB) | +| **Output range** | Varies (see docs) | +| **Warmup** | 1 bar | + +### TL;DR + +- The Composite Fractal Behavior index measures trend duration by analyzing fractal efficiency across 96 simultaneous lookback periods (2 to 192 bars... +- Parameterized by int[]? lengths = null. +- Output range: Varies (see docs). +- Requires 1 bar of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "Mark Jurik's CFB is not a momentum indicator. It is a stopwatch for chaos." The Composite Fractal Behavior index measures trend duration by analyzing fractal efficiency across 96 simultaneous lookback periods (2 to 192 bars by default). Rather than asking "how strong is the trend," CFB asks "how long has the market been moving efficiently." The answer: a single integer representing the dominant trending timeframe. Use CFB to dynamically tune other indicators: instead of RSI(14), use RSI(CFB). @@ -351,4 +368,4 @@ Compact state record holds previous CFB (for decay), last price (for volatility - Jurik Research. "Composite Fractal Behavior." http://jurikres.com/ - Mandelbrot, B. (1997). *Fractals and Scaling in Finance*. Springer. (Theoretical foundation) -- Peters, E. (1994). *Fractal Market Analysis*. Wiley. (Fractal efficiency concepts) \ No newline at end of file +- Peters, E. (1994). *Fractal Market Analysis*. Wiley. (Fractal efficiency concepts) diff --git a/lib/momentum/cmo/Cmo.md b/lib/momentum/cmo/Cmo.md index 04c8920e..50334c43 100644 --- a/lib/momentum/cmo/Cmo.md +++ b/lib/momentum/cmo/Cmo.md @@ -1,4 +1,21 @@ -# CMO (Chande Momentum Oscillator) +# CMO (Chande Momentum Oscillator) + +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Momentum | +| **Inputs** | Source (close) | +| **Parameters** | `period` (default DefaultPeriod) | +| **Outputs** | Single series (Cmo) | +| **Output range** | $-100$ to $+100$ | +| **Warmup** | `period + 1` bars | + +### TL;DR + +- The Chande Momentum Oscillator (CMO) is a momentum indicator developed by Tushar Chande. +- Parameterized by `period` (default defaultperiod). +- Output range: $-100$ to $+100$. +- Requires `period + 1` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. The Chande Momentum Oscillator (CMO) is a momentum indicator developed by Tushar Chande. Unlike RSI which uses smoothed averages of gains and losses, CMO uses raw sums of up and down movements, making it more responsive to price changes. The indicator oscillates between -100 and +100. diff --git a/lib/momentum/macd/Macd.md b/lib/momentum/macd/Macd.md index f90bb814..fa919674 100644 --- a/lib/momentum/macd/Macd.md +++ b/lib/momentum/macd/Macd.md @@ -1,5 +1,22 @@ # MACD: Moving Average Convergence Divergence +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Momentum | +| **Inputs** | Source (close) | +| **Parameters** | `fastPeriod` (default 12), `slowPeriod` (default 26), `signalPeriod` (default 9) | +| **Outputs** | Multiple series (Signal, Histogram) | +| **Output range** | Varies (see docs) | +| **Warmup** | 1 bar | + +### TL;DR + +- The Moving Average Convergence Divergence measures momentum through the relationship between two exponential moving averages. +- Parameterized by `fastperiod` (default 12), `slowperiod` (default 26), `signalperiod` (default 9). +- Output range: Varies (see docs). +- Requires 1 bar of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "The trend is your friend, until it bends." — Ed Seykota The Moving Average Convergence Divergence measures momentum through the relationship between two exponential moving averages. Created by Gerald Appel in 1979, the indicator transforms price into a bounded oscillator that reveals trend strength, direction, and potential reversals. Standard parameters (12, 26, 9) detect monthly and biweekly cycles: the 26-period represents roughly one trading month, the 12-period half that duration. @@ -370,4 +387,4 @@ Zero allocations in streaming hot path. Batch mode uses ArrayPool, returning mem - Aspray, T. (1986). "MACD Histogram." *Technical Analysis of Stocks & Commodities*. - Murphy, J. (1999). *Technical Analysis of the Financial Markets*. New York Institute of Finance. - Pring, M. (2002). *Technical Analysis Explained*. McGraw-Hill. -- Elder, A. (1993). *Trading for a Living*. Wiley. (Discussion of MACD histogram interpretation) \ No newline at end of file +- Elder, A. (1993). *Trading for a Living*. Wiley. (Discussion of MACD histogram interpretation) diff --git a/lib/momentum/mom/Mom.md b/lib/momentum/mom/Mom.md index 390f5b61..d6316102 100644 --- a/lib/momentum/mom/Mom.md +++ b/lib/momentum/mom/Mom.md @@ -1,5 +1,22 @@ # MOM: Momentum (Absolute Price Change) +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Momentum | +| **Inputs** | Source (close) | +| **Parameters** | `period` (default 10) | +| **Outputs** | Single series (Mom) | +| **Output range** | Varies (see docs) | +| **Warmup** | `period + 1` bars | + +### TL;DR + +- MOM (Momentum) calculates the absolute price difference between the current value and the value N periods ago. +- Parameterized by `period` (default 10). +- Output range: Varies (see docs). +- Requires `period + 1` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "The market's simplest question answered: how much has price moved in N bars? No ratios, no percentages. Just the raw delta." MOM (Momentum) calculates the absolute price difference between the current value and the value N periods ago. It is the purest expression of directional price movement, returning a signed value in the same units as the input. Positive MOM indicates rising prices; negative indicates falling. This is functionally identical to ROC but with a configurable lookback period (default 10 vs ROC's convention), and maps directly to TA-Lib's `MOM` function. diff --git a/lib/momentum/pmo/Pmo.md b/lib/momentum/pmo/Pmo.md index 7c560de5..f2e31579 100644 --- a/lib/momentum/pmo/Pmo.md +++ b/lib/momentum/pmo/Pmo.md @@ -1,5 +1,22 @@ # PMO: Price Momentum Oscillator +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Momentum | +| **Inputs** | Source (close) | +| **Parameters** | `timePeriods` (default DefaultTimePeriods), `smoothPeriods` (default DefaultSmoothPeriods), `signalPeriods` (default DefaultSignalPeriods) | +| **Outputs** | Single series (Pmo) | +| **Output range** | Varies (see docs) | +| **Warmup** | `timePeriods + smoothPeriods` bars | + +### TL;DR + +- PMO (Price Momentum Oscillator), developed by Carl Swenlin at DecisionPoint, is a double-smoothed 1-bar rate of change. +- Parameterized by `timeperiods` (default defaulttimeperiods), `smoothperiods` (default defaultsmoothperiods), `signalperiods` (default defaultsignalperiods). +- Output range: Varies (see docs). +- Requires `timePeriods + smoothPeriods` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "Double-smooth the rate of change and you get something that actually tells you where momentum is headed, not where it was five bars ago." PMO (Price Momentum Oscillator), developed by Carl Swenlin at DecisionPoint, is a double-smoothed 1-bar rate of change. It applies two custom EMA passes to a percentage ROC, producing a momentum oscillator that is smoother than raw ROC yet more responsive than triple-smoothed alternatives like TRIX. The custom EMA uses $\alpha = 2/N$ rather than the standard $2/(N+1)$, and seeds with the SMA of the first N values. PMO oscillates around zero: positive values indicate upward momentum, negative values indicate downward momentum. diff --git a/lib/momentum/ppo/Ppo.md b/lib/momentum/ppo/Ppo.md index 20c77794..9a513615 100644 --- a/lib/momentum/ppo/Ppo.md +++ b/lib/momentum/ppo/Ppo.md @@ -1,5 +1,22 @@ # PPO: Percentage Price Oscillator +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Momentum | +| **Inputs** | Source (close) | +| **Parameters** | `fastPeriod` (default DefaultFastPeriod), `slowPeriod` (default DefaultSlowPeriod), `signalPeriod` (default DefaultSignalPeriod) | +| **Outputs** | Multiple series (Signal, Histogram) | +| **Output range** | Varies (see docs) | +| **Warmup** | 1 bar | + +### TL;DR + +- PPO (Percentage Price Oscillator) measures the percentage difference between a fast EMA and a slow EMA. +- Parameterized by `fastperiod` (default defaultfastperiod), `slowperiod` (default defaultslowperiod), `signalperiod` (default defaultsignalperiod). +- Output range: Varies (see docs). +- Requires 1 bar of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "MACD told you the spread in dollars. PPO tells you the spread in percent. One of those actually works across instruments." PPO (Percentage Price Oscillator) measures the percentage difference between a fast EMA and a slow EMA. It is functionally equivalent to MACD normalized by the slow EMA, producing values that are comparable across instruments with different price levels. The implementation outputs three components: the PPO line, a signal line (EMA of PPO), and a histogram (PPO minus Signal). diff --git a/lib/momentum/prs/Prs.md b/lib/momentum/prs/Prs.md index a7a99c85..000bc435 100644 --- a/lib/momentum/prs/Prs.md +++ b/lib/momentum/prs/Prs.md @@ -1,4 +1,21 @@ -# PRS: Price Relative Strength +# PRS: Price Relative Strength + +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Momentum | +| **Inputs** | Source (close) | +| **Parameters** | `smoothPeriod` (default 1) | +| **Outputs** | Single series (PRS) | +| **Output range** | Varies (see docs) | +| **Warmup** | `smoothPeriod` bars | + +### TL;DR + +- **Category:** Momentum **Also known as:** Relative Strength Comparison, Price Ratio, Performance Ratio +- Parameterized by `smoothperiod` (default 1). +- Output range: Varies (see docs). +- Requires `smoothPeriod` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. **Category:** Momentum **Also known as:** Relative Strength Comparison, Price Ratio, Performance Ratio diff --git a/lib/momentum/roc/Roc.md b/lib/momentum/roc/Roc.md index b657e04a..58d12341 100644 --- a/lib/momentum/roc/Roc.md +++ b/lib/momentum/roc/Roc.md @@ -1,5 +1,22 @@ # ROC: Rate of Change (Absolute) +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Momentum | +| **Inputs** | Source (close) | +| **Parameters** | `period` (default 9) | +| **Outputs** | Single series (Roc) | +| **Output range** | Varies (see docs) | +| **Warmup** | `period + 1` bars | + +### TL;DR + +- ROC (Rate of Change) calculates the absolute price difference between the current value and the value N periods ago. +- Parameterized by `period` (default 9). +- Output range: Varies (see docs). +- Requires `period + 1` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "The simplest momentum measure: how far has price moved? Not percentage, not ratio - just the raw difference." ROC (Rate of Change) calculates the absolute price difference between the current value and the value N periods ago. This is the most basic form of momentum measurement, returning the raw price change in the same units as the input data. Unlike ROCP (percentage) or ROCR (ratio), ROC preserves the original scale, making it directly interpretable in dollar/point terms. diff --git a/lib/momentum/rocp/Rocp.md b/lib/momentum/rocp/Rocp.md index dc65afc2..7e3e3021 100644 --- a/lib/momentum/rocp/Rocp.md +++ b/lib/momentum/rocp/Rocp.md @@ -1,5 +1,22 @@ # ROCP: Rate of Change Percentage +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Momentum | +| **Inputs** | Source (close) | +| **Parameters** | `period` (default 9) | +| **Outputs** | Single series (Rocp) | +| **Output range** | Varies (see docs) | +| **Warmup** | `period + 1` bars | + +### TL;DR + +- ROCP (Rate of Change Percentage) calculates the percentage change between the current value and the value N periods ago. +- Parameterized by `period` (default 9). +- Output range: Varies (see docs). +- Requires `period + 1` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "The percentage form of momentum: by what percent has price changed? The most intuitive momentum measure." ROCP (Rate of Change Percentage) calculates the percentage change between the current value and the value N periods ago. This is the most commonly used form of rate of change, expressing change in percentage terms that are directly interpretable (e.g., 5.0 = 5% increase). diff --git a/lib/momentum/rocr/Rocr.md b/lib/momentum/rocr/Rocr.md index f0468b13..07c6d12b 100644 --- a/lib/momentum/rocr/Rocr.md +++ b/lib/momentum/rocr/Rocr.md @@ -1,5 +1,22 @@ # ROCR: Rate of Change Ratio +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Momentum | +| **Inputs** | Source (close) | +| **Parameters** | `period` (default 9) | +| **Outputs** | Single series (Rocr) | +| **Output range** | Varies (see docs) | +| **Warmup** | `period + 1` bars | + +### TL;DR + +- ROCR (Rate of Change Ratio) calculates the ratio between the current value and the value N periods ago. +- Parameterized by `period` (default 9). +- Output range: Varies (see docs). +- Requires `period + 1` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "The ratio form of momentum: how many times larger is the current price compared to the past? A multiplier view of market movement." ROCR (Rate of Change Ratio) calculates the ratio between the current value and the value N periods ago. Values hover around 1.0, with values above 1.0 indicating price increase and values below 1.0 indicating price decrease. Unlike ROC (absolute) or ROCP (percentage), ROCR provides a dimensionless multiplier that directly shows the price ratio. diff --git a/lib/momentum/rsi/Rsi.md b/lib/momentum/rsi/Rsi.md index ce9e47fc..f1e06cb9 100644 --- a/lib/momentum/rsi/Rsi.md +++ b/lib/momentum/rsi/Rsi.md @@ -1,5 +1,22 @@ # RSI: Relative Strength Index +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Momentum | +| **Inputs** | Source (close) | +| **Parameters** | `period` (default 14) | +| **Outputs** | Single series (Rsi) | +| **Output range** | Varies (see docs) | +| **Warmup** | `period + 1` bars | + +### TL;DR + +- The Relative Strength Index measures the speed and magnitude of price changes. +- Parameterized by `period` (default 14). +- Output range: Varies (see docs). +- Requires `period + 1` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "Momentum is the premier anomaly." — Clifford Asness, AQR Capital (who actually said it, and meant it) The Relative Strength Index measures the speed and magnitude of price changes. Introduced by J. Welles Wilder Jr. in 1978, it oscillates between 0 and 100, identifying overbought and oversold conditions. The "Relative Strength" name is misleading: RSI measures internal strength (price versus itself) not relative strength (asset versus benchmark). Wilder knew this. He kept the name anyway. Marketing, perhaps. @@ -303,4 +320,4 @@ finally - Wilder, J. W. (1978). *New Concepts in Technical Trading Systems*. Trend Research. Chapter: Relative Strength Index. - Constance Brown. (1999). *Technical Analysis for the Trading Professional*. McGraw-Hill. (RSI divergence patterns) -- Cutler, David. (1991). "RSI Revisited." *Technical Analysis of Stocks & Commodities*. (Smoothed RSI variants) \ No newline at end of file +- Cutler, David. (1991). "RSI Revisited." *Technical Analysis of Stocks & Commodities*. (Smoothed RSI variants) diff --git a/lib/momentum/rsx/Rsx.md b/lib/momentum/rsx/Rsx.md index b1d40818..353d56e4 100644 --- a/lib/momentum/rsx/Rsx.md +++ b/lib/momentum/rsx/Rsx.md @@ -1,5 +1,22 @@ # RSX: Relative Strength Quality Index +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Momentum | +| **Inputs** | Source (close) | +| **Parameters** | `period` | +| **Outputs** | Single series (Rsx) | +| **Output range** | Varies (see docs) | +| **Warmup** | `period` bars | + +### TL;DR + +- Mark Jurik's RSX represents the pinnacle of bounded momentum oscillator design. +- Parameterized by `period`. +- Output range: Varies (see docs). +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "RSX is to RSI what a Tesla is to a horse-drawn carriage: same basic concept, vastly superior engineering." Mark Jurik's RSX represents the pinnacle of bounded momentum oscillator design. Standard RSI suffers from a fundamental paradox: raw RSI produces jagged noise triggering false signals at overbought/oversold boundaries, but smoothing introduces unacceptable lag that delays turning points. RSX solves this through cascaded IIR filter topology that eliminates high-frequency noise while preserving linear phase response. The result: output so smooth it resembles a sine wave, yet turns precisely at market extrema with zero effective lag. @@ -358,4 +375,4 @@ Epsilon threshold prevents division by zero while maintaining meaningful output - Jurik, M. (1990s). "RSX: Relative Strength Quality Index." Jurik Research. Proprietary documentation. - Ehlers, J. F. (2001). *Rocket Science for Traders*. Wiley. IIR filter design principles. - ProRealCode. "Jurik RSX Implementation." https://www.prorealcode.com/prorealtime-indicators/jurik-rsx/ -- Scribd. "Jurik RSX Algorithm Reference." https://scribd.com/document/253633684/Jurik-RSX \ No newline at end of file +- Scribd. "Jurik RSX Algorithm Reference." https://scribd.com/document/253633684/Jurik-RSX diff --git a/lib/momentum/sam/Sam.md b/lib/momentum/sam/Sam.md index fd90370c..7ba8ac42 100644 --- a/lib/momentum/sam/Sam.md +++ b/lib/momentum/sam/Sam.md @@ -1,4 +1,21 @@ -# SAM: Smoothed Adaptive Momentum +# SAM: Smoothed Adaptive Momentum + +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Momentum | +| **Inputs** | Source (close) | +| **Parameters** | `alpha` (default 0.07), `cutoff` (default 8) | +| **Outputs** | Single series (Sam) | +| **Output range** | Varies (see docs) | +| **Warmup** | `MaxCyclePeriod * 2` bars | + +### TL;DR + +- The Smoothed Adaptive Momentum oscillator measures price momentum over an adaptively determined lookback period equal to the dominant cycle length,... +- Parameterized by `alpha` (default 0.07), `cutoff` (default 8). +- Output range: Varies (see docs). +- Requires `MaxCyclePeriod * 2` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. The Smoothed Adaptive Momentum oscillator measures price momentum over an adaptively determined lookback period equal to the dominant cycle length, then smooths the result with a 2-pole Super Smoother filter. Unlike fixed-period momentum indicators (ROC, TRIX) that use an arbitrary lookback, SAM measures the dominant cycle via Ehlers' Homodyne Discriminator and uses that cycle length as the momentum window, ensuring that the momentum measurement always spans exactly one full cycle. This eliminates the half-cycle phase distortion that plagues fixed-period momentum, producing a zero-lag momentum oscillator that naturally adapts to changing market rhythm. diff --git a/lib/momentum/tsi/Tsi.md b/lib/momentum/tsi/Tsi.md index 31329f95..319e6132 100644 --- a/lib/momentum/tsi/Tsi.md +++ b/lib/momentum/tsi/Tsi.md @@ -1,4 +1,21 @@ -# TSI: True Strength Index +# TSI: True Strength Index + +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Momentum | +| **Inputs** | Source (close) | +| **Parameters** | `longPeriod` (default DefaultLongPeriod), `shortPeriod` (default DefaultShortPeriod), `signalPeriod` (default DefaultSignalPeriod) | +| **Outputs** | Single series (Tsi) | +| **Output range** | $-1$ to $+1$ | +| **Warmup** | 1 bar | + +### TL;DR + +- The True Strength Index (TSI) is a momentum oscillator developed by William Blau that uses double-smoothed exponential moving averages of price mom... +- Parameterized by `longperiod` (default defaultlongperiod), `shortperiod` (default defaultshortperiod), `signalperiod` (default defaultsignalperiod). +- Output range: $-1$ to $+1$. +- Requires 1 bar of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. The True Strength Index (TSI) is a momentum oscillator developed by William Blau that uses double-smoothed exponential moving averages of price momentum to reduce noise and identify trend strength and direction. diff --git a/lib/momentum/vel/Vel.md b/lib/momentum/vel/Vel.md index 484dee79..63acf5f9 100644 --- a/lib/momentum/vel/Vel.md +++ b/lib/momentum/vel/Vel.md @@ -1,5 +1,22 @@ # VEL: Jurik Velocity +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Momentum | +| **Inputs** | Source (close) | +| **Parameters** | `period` | +| **Outputs** | Single series (Vel) | +| **Output range** | Varies (see docs) | +| **Warmup** | `period` bars | + +### TL;DR + +- Jurik Velocity (VEL) measures price rate-of-change through the differential between two weighted moving averages with distinct inertia profiles. +- Parameterized by `period`. +- Output range: Varies (see docs). +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "Momentum is easy. Smooth momentum without lag is hard. Jurik Velocity is the answer." Jurik Velocity (VEL) measures price rate-of-change through the differential between two weighted moving averages with distinct inertia profiles. Standard momentum ($P_t - P_{t-n}$) amplifies noise: single outlier bars create false signals. VEL exploits the different convergence speeds of Parabolic Weighted Moving Average (PWMA) and linear Weighted Moving Average (WMA) to isolate clean velocity information. The quadratic weighting of PWMA responds faster than linear WMA; their difference captures acceleration without bar-to-bar noise. @@ -363,4 +380,4 @@ Reset propagates to composed indicators, ensuring clean state. - Jurik, M. (1990s). "Jurik Velocity (VEL)." Jurik Research. Proprietary documentation. - Kaufman, P. J. (2013). *Trading Systems and Methods*. 5th ed. Wiley. Chapter on weighted moving averages. -- Ehlers, J. F. (2001). *Rocket Science for Traders*. Wiley. Filter design principles. \ No newline at end of file +- Ehlers, J. F. (2001). *Rocket Science for Traders*. Wiley. Filter design principles. diff --git a/lib/numerics/accel/Accel.md b/lib/numerics/accel/Accel.md index e46f961d..b44f9397 100644 --- a/lib/numerics/accel/Accel.md +++ b/lib/numerics/accel/Accel.md @@ -1,5 +1,22 @@ # ACCEL: Second Derivative (Acceleration) +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Numeric | +| **Inputs** | Source (close) | +| **Parameters** | None | +| **Outputs** | Single series (ACCEL) | +| **Output range** | Varies (see docs) | +| **Warmup** | `3` bars | + +### TL;DR + +- ACCEL measures the rate of change of velocity—the acceleration of a time series. +- No configurable parameters; computation is stateless per bar. +- Output range: Varies (see docs). +- Requires `3` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "Velocity tells you where you're going. Acceleration tells you if you're getting there faster or slower." ACCEL measures the rate of change of velocity—the acceleration of a time series. As the second derivative, it reveals momentum shifts before they manifest in price direction. Positive acceleration means velocity is increasing (trend strengthening); negative means velocity is decreasing (trend weakening). This O(1) streaming implementation uses FMA optimization and SIMD batch processing. diff --git a/lib/numerics/betadist/Betadist.md b/lib/numerics/betadist/Betadist.md index 4c905258..8d361dc3 100644 --- a/lib/numerics/betadist/Betadist.md +++ b/lib/numerics/betadist/Betadist.md @@ -1,5 +1,22 @@ # BETADIST: Beta Distribution CDF +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Numeric | +| **Inputs** | Source (close) | +| **Parameters** | `period` (default 50), `alpha` (default 2.0), `beta` (default 2.0) | +| **Outputs** | Single series (Betadist) | +| **Output range** | Varies (see docs) | +| **Warmup** | `period` bars | + +### TL;DR + +- BETADIST computes the cumulative distribution function of the Beta distribution applied to a min-max normalized price series. +- Parameterized by `period` (default 50), `alpha` (default 2.0), `beta` (default 2.0). +- Output range: Varies (see docs). +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + BETADIST computes the cumulative distribution function of the Beta distribution applied to a min-max normalized price series. The source price is first normalized to $[0, 1]$ over a lookback window, then passed through the regularized incomplete beta function $I_x(\alpha, \beta)$ to produce a probability-mapped oscillator. The two shape parameters $\alpha$ and $\beta$ control the nonlinear mapping: symmetric parameters ($\alpha = \beta$) produce a sigmoid-like transformation centered at 0.5, while asymmetric parameters skew the mapping to emphasize extremes in either direction. ## Historical Context diff --git a/lib/numerics/binomdist/Binomdist.md b/lib/numerics/binomdist/Binomdist.md index c81e57d0..7659060e 100644 --- a/lib/numerics/binomdist/Binomdist.md +++ b/lib/numerics/binomdist/Binomdist.md @@ -1,5 +1,22 @@ # BINOMDIST: Binomial Distribution CDF +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Numeric | +| **Inputs** | Source (close) | +| **Parameters** | `period` (default 50), `trials` (default 20), `threshold` (default 10) | +| **Outputs** | Single series (Binomdist) | +| **Output range** | Varies (see docs) | +| **Warmup** | `period` bars | + +### TL;DR + +- BINOMDIST computes the cumulative distribution function of the Binomial distribution, mapping a min-max normalized price to a success probability $... +- Parameterized by `period` (default 50), `trials` (default 20), `threshold` (default 10). +- Output range: Varies (see docs). +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + BINOMDIST computes the cumulative distribution function of the Binomial distribution, mapping a min-max normalized price to a success probability $p$ and evaluating $P(X \leq k)$ for $X \sim \text{Binomial}(n, p)$. The normalized price position within its lookback range determines the probability of success per trial, while the trial count $n$ and threshold $k$ control the shape of the CDF response. The output is a $[0, 1]$ bounded oscillator where values near 0 indicate the price-derived probability makes $k$ or fewer successes very unlikely (bullish pressure), and values near 1 indicate $k$ successes are very likely (established range). ## Historical Context diff --git a/lib/numerics/change/Change.md b/lib/numerics/change/Change.md index 76fcf02f..aad94e5a 100644 --- a/lib/numerics/change/Change.md +++ b/lib/numerics/change/Change.md @@ -1,5 +1,22 @@ # CHANGE: Relative Price Change +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Numeric | +| **Inputs** | Source (close) | +| **Parameters** | `period` (default 1) | +| **Outputs** | Single series (Change) | +| **Output range** | Varies (see docs) | +| **Warmup** | `period + 1` bars | + +### TL;DR + +- CHANGE calculates the percentage change between the current value and a value N periods ago. +- Parameterized by `period` (default 1). +- Output range: Varies (see docs). +- Requires `period + 1` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "The simplest measure of movement is often the most powerful." CHANGE calculates the percentage change between the current value and a value N periods ago. This fundamental indicator forms the basis for momentum analysis, rate of change calculations, and relative performance comparisons. diff --git a/lib/numerics/cwt/Cwt.md b/lib/numerics/cwt/Cwt.md index 133e892e..1a59b34f 100644 --- a/lib/numerics/cwt/Cwt.md +++ b/lib/numerics/cwt/Cwt.md @@ -1,5 +1,22 @@ # CWT: Continuous Wavelet Transform +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Numeric | +| **Inputs** | Source (close) | +| **Parameters** | `scale` (default 10.0), `omega0` (default 6.0) | +| **Outputs** | Single series (Cwt) | +| **Output range** | Varies (see docs) | +| **Warmup** | 1 bar | + +### TL;DR + +- CWT computes the magnitude of the Continuous Wavelet Transform at a specified scale using the Morlet wavelet, providing a time-frequency decomposit... +- Parameterized by `scale` (default 10.0), `omega0` (default 6.0). +- Output range: Varies (see docs). +- Requires 1 bar of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + CWT computes the magnitude of the Continuous Wavelet Transform at a specified scale using the Morlet wavelet, providing a time-frequency decomposition that measures the energy content of a specific frequency band at each point in time. Unlike Fourier analysis which loses time localization, the wavelet transform maintains both time and frequency information simultaneously. The output is a non-negative magnitude series where peaks indicate strong presence of the target frequency (determined by the scale parameter) and troughs indicate absence of that frequency component. ## Historical Context diff --git a/lib/numerics/dwt/Dwt.md b/lib/numerics/dwt/Dwt.md index 17a06375..9af7a77f 100644 --- a/lib/numerics/dwt/Dwt.md +++ b/lib/numerics/dwt/Dwt.md @@ -1,5 +1,22 @@ # DWT: Discrete Wavelet Transform +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Numeric | +| **Inputs** | Source (close) | +| **Parameters** | `levels` (default 4), `output` (default 0) | +| **Outputs** | Single series (Dwt) | +| **Output range** | Varies (see docs) | +| **Warmup** | `bufferSize` bars | + +### TL;DR + +- The Discrete Wavelet Transform decomposes a price series into multi-resolution frequency components using the a trous (with holes) stationary Haar ... +- Parameterized by `levels` (default 4), `output` (default 0). +- Output range: Varies (see docs). +- Requires `bufferSize` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + The Discrete Wavelet Transform decomposes a price series into multi-resolution frequency components using the a trous (with holes) stationary Haar wavelet. Unlike decimated DWT, the stationary variant preserves time alignment at every scale, producing an approximation (trend) and detail coefficients (noise/cycles) at each decomposition level. Each level doubles the effective receptive field: level $L$ captures structure at $2^L$ bars. With 1-8 levels and $O(L)$ per-bar cost, DWT provides a complete multi-scale decomposition that cleanly separates trend from noise without the phase distortion inherent in moving-average cascades. ## Historical Context diff --git a/lib/numerics/expdist/Expdist.md b/lib/numerics/expdist/Expdist.md index be5da63c..3319456d 100644 --- a/lib/numerics/expdist/Expdist.md +++ b/lib/numerics/expdist/Expdist.md @@ -1,5 +1,22 @@ # EXPDIST: Exponential Distribution CDF +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Numeric | +| **Inputs** | Source (close) | +| **Parameters** | `period` (default 50), `lambda` (default 3.0) | +| **Outputs** | Single series (Expdist) | +| **Output range** | Varies (see docs) | +| **Warmup** | `period` bars | + +### TL;DR + +- The Exponential Distribution CDF transforms a min-max normalized price into the cumulative distribution function of the exponential distribution, p... +- Parameterized by `period` (default 50), `lambda` (default 3.0). +- Output range: Varies (see docs). +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + The Exponential Distribution CDF transforms a min-max normalized price into the cumulative distribution function of the exponential distribution, producing an output in $[0, 1]$. The exponential distribution models memoryless waiting times: the probability that a normalized value falls below a threshold depends only on the rate parameter $\lambda$, not on any history. Higher $\lambda$ values compress the CDF curve toward zero, making the indicator more sensitive to small normalized deviations. With $O(N)$ normalization and $O(1)$ CDF evaluation, EXPDIST provides a nonlinear percentile ranking that emphasizes the lower end of the price range while compressing the upper end. ## Historical Context diff --git a/lib/numerics/exptrans/Exptrans.md b/lib/numerics/exptrans/Exptrans.md index 0919f910..7bf3e012 100644 --- a/lib/numerics/exptrans/Exptrans.md +++ b/lib/numerics/exptrans/Exptrans.md @@ -1,5 +1,22 @@ # EXPTRANS: Exponential Function +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Numeric | +| **Inputs** | Source (close) | +| **Parameters** | None | +| **Outputs** | Single series (EXPTRANS) | +| **Output range** | Varies (see docs) | +| **Warmup** | `0` bars | + +### TL;DR + +- The Exponential (EXP) transformer applies the natural exponential function $e^x$ to each value in a time series. +- No configurable parameters; computation is stateless per bar. +- Output range: Varies (see docs). +- Requires `0` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "The exponential function is the only function that is its own derivative—a mathematical curiosity that makes it indispensable for modeling growth, decay, and everything compounding." The Exponential (EXP) transformer applies the natural exponential function $e^x$ to each value in a time series. As the inverse of the natural logarithm, it converts additive relationships back to multiplicative ones, making it essential for reconstructing price levels from log-returns and implementing models that assume log-normal distributions. diff --git a/lib/numerics/fdist/Fdist.md b/lib/numerics/fdist/Fdist.md index af9656cd..1bd206f4 100644 --- a/lib/numerics/fdist/Fdist.md +++ b/lib/numerics/fdist/Fdist.md @@ -1,5 +1,22 @@ # FDIST: F-Distribution CDF +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Numeric | +| **Inputs** | Source (close) | +| **Parameters** | `d1` (default 1), `d2` (default 1), `period` (default 14) | +| **Outputs** | Single series (Fdist) | +| **Output range** | Varies (see docs) | +| **Warmup** | `period` bars | + +### TL;DR + +- The F-Distribution CDF transforms a min-max normalized price into the cumulative distribution function of the F-distribution (Fisher-Snedecor distr... +- Parameterized by `d1` (default 1), `d2` (default 1), `period` (default 14). +- Output range: Varies (see docs). +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + The F-Distribution CDF transforms a min-max normalized price into the cumulative distribution function of the F-distribution (Fisher-Snedecor distribution), producing an output in $[0, 1]$. The F-distribution arises as the ratio of two chi-squared random variables divided by their respective degrees of freedom, making it the natural distribution for variance ratio tests. By mapping normalized price through the regularized incomplete beta function with parameters tied to degrees of freedom $d_1$ and $d_2$, FDIST provides a probabilistic ranking that is asymmetric: the CDF shape changes qualitatively depending on whether $d_1 < d_2$, $d_1 = d_2$, or $d_1 > d_2$, giving traders control over the nonlinear response curve. ## Historical Context diff --git a/lib/numerics/fft/Fft.md b/lib/numerics/fft/Fft.md index 422f27dd..2cf7b0b3 100644 --- a/lib/numerics/fft/Fft.md +++ b/lib/numerics/fft/Fft.md @@ -1,5 +1,22 @@ # FFT: Fast Fourier Transform (Dominant Cycle Detector) +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Numeric | +| **Inputs** | Source (close) | +| **Parameters** | `windowSize` (default 64), `minPeriod` (default 4), `maxPeriod` (default 32) | +| **Outputs** | Single series (Fft) | +| **Output range** | Varies (see docs) | +| **Warmup** | 1 bar | + +### TL;DR + +- The FFT indicator computes the dominant cycle period in a price series using a Discrete Fourier Transform with a Hanning window. +- Parameterized by `windowsize` (default 64), `minperiod` (default 4), `maxperiod` (default 32). +- Output range: Varies (see docs). +- Requires 1 bar of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + The FFT indicator computes the dominant cycle period in a price series using a Discrete Fourier Transform with a Hanning window. Rather than outputting frequency-domain magnitudes, it returns the estimated dominant cycle period in bars, making it directly usable as an adaptive period input for other indicators. The implementation uses a brute-force DFT over a constrained frequency band (not a radix-2 FFT), with parabolic interpolation on the magnitude spectrum to achieve sub-bin frequency resolution. With window sizes of 32, 64, or 128 and $O(N \cdot N/2)$ complexity per bar, the indicator trades computational cost for precise cycle detection within user-specified period bounds. ## Historical Context diff --git a/lib/numerics/gammadist/Gammadist.md b/lib/numerics/gammadist/Gammadist.md index 6a1d7dde..3b34da32 100644 --- a/lib/numerics/gammadist/Gammadist.md +++ b/lib/numerics/gammadist/Gammadist.md @@ -1,5 +1,22 @@ # GAMMADIST: Gamma Distribution CDF +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Numeric | +| **Inputs** | Source (close) | +| **Parameters** | `alpha` (default 2.0), `beta` (default 1.0), `period` (default 14) | +| **Outputs** | Single series (Gammadist) | +| **Output range** | Varies (see docs) | +| **Warmup** | `period` bars | + +### TL;DR + +- The Gamma Distribution CDF transforms a min-max normalized price into the cumulative distribution function of the gamma distribution, producing an ... +- Parameterized by `alpha` (default 2.0), `beta` (default 1.0), `period` (default 14). +- Output range: Varies (see docs). +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + The Gamma Distribution CDF transforms a min-max normalized price into the cumulative distribution function of the gamma distribution, producing an output in $[0, 1]$. The gamma distribution generalizes the exponential distribution by adding a shape parameter $\alpha$ that controls whether the PDF is monotonically decreasing ($\alpha < 1$), exponential ($\alpha = 1$), or bell-shaped with a right skew ($\alpha > 1$). Combined with a rate parameter $\beta$ that scales the normalized input, GAMMADIST provides a flexible nonlinear mapping with controllable asymmetry. The CDF is computed via the regularized lower incomplete gamma function using series expansion or Lentz continued fraction, selecting the faster-converging method based on the argument relative to the shape parameter. ## Historical Context diff --git a/lib/numerics/highest/Highest.md b/lib/numerics/highest/Highest.md index 82af14c8..1a53f9c0 100644 --- a/lib/numerics/highest/Highest.md +++ b/lib/numerics/highest/Highest.md @@ -1,5 +1,22 @@ # HIGHEST: Rolling Maximum +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Numeric | +| **Inputs** | Source (close) | +| **Parameters** | `period` | +| **Outputs** | Single series (Highest) | +| **Output range** | Varies (see docs) | +| **Warmup** | `period` bars | + +### TL;DR + +- HIGHEST calculates the maximum value over a rolling lookback window. +- Parameterized by `period`. +- Output range: Varies (see docs). +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "What's the peak? The answer to that question defines support, resistance, and breakout levels." HIGHEST calculates the maximum value over a rolling lookback window. This O(1) amortized streaming implementation uses a monotonic deque algorithm, enabling real-time updates without re-scanning the entire window. Validated against TA-Lib MAX and Tulip max functions. diff --git a/lib/numerics/ifft/Ifft.md b/lib/numerics/ifft/Ifft.md index 5cc91cb8..279707ec 100644 --- a/lib/numerics/ifft/Ifft.md +++ b/lib/numerics/ifft/Ifft.md @@ -1,5 +1,22 @@ # IFFT: Inverse Fast Fourier Transform (Spectral Filter) +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Numeric | +| **Inputs** | Source (close) | +| **Parameters** | `windowSize` (default 64), `numHarmonics` (default 5) | +| **Outputs** | Single series (Ifft) | +| **Output range** | Varies (see docs) | +| **Warmup** | 1 bar | + +### TL;DR + +- The Inverse FFT indicator reconstructs a smoothed version of the price series by performing a forward DFT, retaining only the lowest-frequency harm... +- Parameterized by `windowsize` (default 64), `numharmonics` (default 5). +- Output range: Varies (see docs). +- Requires 1 bar of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + The Inverse FFT indicator reconstructs a smoothed version of the price series by performing a forward DFT, retaining only the lowest-frequency harmonics, and synthesizing the output via inverse transform. The result is a spectral low-pass filter that preserves the dominant cyclical components while discarding high-frequency noise. By controlling the number of retained harmonics $H$, the user adjusts the smoothness/responsiveness trade-off: $H = 1$ yields a near-sinusoidal trend, while $H = N/2$ reproduces the original (windowed) signal. The indicator overlays on price and provides a frequency-domain alternative to conventional moving averages. ## Historical Context diff --git a/lib/numerics/jerk/Jerk.md b/lib/numerics/jerk/Jerk.md index 3b570e81..71ddaeff 100644 --- a/lib/numerics/jerk/Jerk.md +++ b/lib/numerics/jerk/Jerk.md @@ -1,5 +1,22 @@ # JERK: Third Derivative +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Numeric | +| **Inputs** | Source (close) | +| **Parameters** | None | +| **Outputs** | Single series (JERK) | +| **Output range** | Varies (see docs) | +| **Warmup** | `4` bars | + +### TL;DR + +- JERK measures the rate of change of acceleration—called "jerk" in physics. +- No configurable parameters; computation is stateless per bar. +- Output range: Varies (see docs). +- Requires `4` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "Acceleration tells you the trend is changing. Jerk tells you that change is itself changing—the earliest possible warning." JERK measures the rate of change of acceleration—called "jerk" in physics. As the third derivative, it detects changes in momentum dynamics before they appear in acceleration, velocity, or price. A positive jerk means acceleration is increasing; negative means acceleration is decreasing. This O(1) streaming implementation uses dual FMA optimization and SIMD batch processing for four-point calculations. diff --git a/lib/numerics/lineartrans/Lineartrans.md b/lib/numerics/lineartrans/Lineartrans.md index b59f1ecf..7384f6be 100644 --- a/lib/numerics/lineartrans/Lineartrans.md +++ b/lib/numerics/lineartrans/Lineartrans.md @@ -1,5 +1,22 @@ # LINEARTRANS: Linear Scaling Transformer +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Numeric | +| **Inputs** | Source (close) | +| **Parameters** | `slope` (default 1.0), `intercept` (default 0.0) | +| **Outputs** | Single series (Lineartrans) | +| **Output range** | Varies (see docs) | +| **Warmup** | `0` bars | + +### TL;DR + +- The Linear transformer applies an affine transformation $y = \text{slope} \cdot x + \text{intercept}$ to each value in a time series. +- Parameterized by `slope` (default 1.0), `intercept` (default 0.0). +- Output range: Varies (see docs). +- Requires `0` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "The simplest transformations are often the most powerful—linear scaling is the mathematical equivalent of adjusting the volume and tuning the dial." The Linear transformer applies an affine transformation $y = \text{slope} \cdot x + \text{intercept}$ to each value in a time series. This fundamental operation enables scaling, offsetting, unit conversion, and normalization—the building blocks for preparing data for analysis or combining signals from different sources. diff --git a/lib/numerics/lognormdist/Lognormdist.md b/lib/numerics/lognormdist/Lognormdist.md index 8eee5306..64289cab 100644 --- a/lib/numerics/lognormdist/Lognormdist.md +++ b/lib/numerics/lognormdist/Lognormdist.md @@ -1,5 +1,22 @@ # LOGNORMDIST: Log-Normal Distribution CDF +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Numeric | +| **Inputs** | Source (close) | +| **Parameters** | `mu` (default 0.0), `sigma` (default 1.0), `period` (default 14) | +| **Outputs** | Single series (Lognormdist) | +| **Output range** | Varies (see docs) | +| **Warmup** | `period` bars | + +### TL;DR + +- The Log-Normal Distribution CDF transforms a min-max normalized price into the cumulative distribution function of the log-normal distribution, pro... +- Parameterized by `mu` (default 0.0), `sigma` (default 1.0), `period` (default 14). +- Output range: Varies (see docs). +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + The Log-Normal Distribution CDF transforms a min-max normalized price into the cumulative distribution function of the log-normal distribution, producing an output in $[0, 1]$. A random variable $X$ is log-normally distributed when $\ln(X)$ follows a normal distribution. This makes the log-normal CDF natural for financial data, where multiplicative returns (log-returns) are approximately normally distributed. The indicator min-max normalizes the source to $(0, 1]$, takes the natural logarithm, standardizes by parameters $\mu$ and $\sigma$, then evaluates the standard normal CDF. The result emphasizes values near the bottom of the recent range (where the logarithm diverges) and compresses values near the top. ## Historical Context diff --git a/lib/numerics/logtrans/Logtrans.md b/lib/numerics/logtrans/Logtrans.md index a2b60fd4..566cf456 100644 --- a/lib/numerics/logtrans/Logtrans.md +++ b/lib/numerics/logtrans/Logtrans.md @@ -1,5 +1,22 @@ # LOGTRANS: Natural Logarithm Transformer +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Numeric | +| **Inputs** | Source (close) | +| **Parameters** | None | +| **Outputs** | Single series (LOGTRANS) | +| **Output range** | Varies (see docs) | +| **Warmup** | `0` bars | + +### TL;DR + +- The LOG transformer applies the natural logarithm function $\ln(x)$ to input values. +- No configurable parameters; computation is stateless per bar. +- Output range: Varies (see docs). +- Requires `0` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "The logarithm is one of the most useful mathematical functions, turning multiplicative relationships into additive ones—a property that makes many financial calculations tractable." The LOG transformer applies the natural logarithm function $\ln(x)$ to input values. This point-wise transformation compresses large values and expands small ones, making it essential for analyzing multiplicative processes like compounded returns. diff --git a/lib/numerics/lowest/Lowest.md b/lib/numerics/lowest/Lowest.md index aec65fa6..88b3b706 100644 --- a/lib/numerics/lowest/Lowest.md +++ b/lib/numerics/lowest/Lowest.md @@ -1,5 +1,22 @@ # LOWEST: Rolling Minimum +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Numeric | +| **Inputs** | Source (close) | +| **Parameters** | `period` | +| **Outputs** | Single series (Lowest) | +| **Output range** | Varies (see docs) | +| **Warmup** | `period` bars | + +### TL;DR + +- LOWEST calculates the minimum value over a rolling lookback window. +- Parameterized by `period`. +- Output range: Varies (see docs). +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "Know your floor. Support levels are just historical minimums waiting to be tested." LOWEST calculates the minimum value over a rolling lookback window. This O(1) amortized streaming implementation uses a monotonic deque algorithm, enabling real-time updates without re-scanning the entire window. Validated against TA-Lib MIN and Tulip min functions. diff --git a/lib/numerics/normalize/Normalize.md b/lib/numerics/normalize/Normalize.md index 8f307560..a5656164 100644 --- a/lib/numerics/normalize/Normalize.md +++ b/lib/numerics/normalize/Normalize.md @@ -1,5 +1,22 @@ # NORMALIZE: Min-Max Normalization +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Numeric | +| **Inputs** | Source (close) | +| **Parameters** | `period` (default 14) | +| **Outputs** | Single series (Normalize) | +| **Output range** | Varies (see docs) | +| **Warmup** | `period` bars | + +### TL;DR + +- The Normalize transformer applies min-max scaling to map any value series into the bounded range [0, 1] based on the observed minimum and maximum w... +- Parameterized by `period` (default 14). +- Output range: Varies (see docs). +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "Normalization is the art of making apples and oranges comparable—by insisting that everything lives on the same scale from 0 to 1." The Normalize transformer applies min-max scaling to map any value series into the bounded range [0, 1] based on the observed minimum and maximum within a rolling lookback window. This technique is fundamental for feature scaling, creating bounded oscillators, and comparing series with different magnitudes. diff --git a/lib/numerics/normdist/Normdist.md b/lib/numerics/normdist/Normdist.md index ca7c8613..717c2a1c 100644 --- a/lib/numerics/normdist/Normdist.md +++ b/lib/numerics/normdist/Normdist.md @@ -1,5 +1,22 @@ # NORMDIST: Normal Distribution CDF +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Numeric | +| **Inputs** | Source (close) | +| **Parameters** | `mu` (default 0.0), `sigma` (default 1.0), `period` (default 14) | +| **Outputs** | Single series (Normdist) | +| **Output range** | Varies (see docs) | +| **Warmup** | `period` bars | + +### TL;DR + +- The Normal Distribution CDF transforms a z-score normalized price into the cumulative distribution function of the Gaussian distribution, producing... +- Parameterized by `mu` (default 0.0), `sigma` (default 1.0), `period` (default 14). +- Output range: Varies (see docs). +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + The Normal Distribution CDF transforms a z-score normalized price into the cumulative distribution function of the Gaussian distribution, producing an output in $[0, 1]$. Unlike other distribution indicators in this library that use min-max normalization, NORMDIST computes a rolling mean and standard deviation over the lookback window, converting the raw price to a z-score, then applies optional $\mu$ and $\sigma$ parameters for further shaping. The result represents the probability that a standard normal random variable would fall at or below the observed z-score. This makes NORMDIST a direct percentile ranking under the assumption of normally distributed returns, with the output naturally centered at 0.5 when the price is at its rolling mean. ## Historical Context diff --git a/lib/numerics/poissondist/Poissondist.md b/lib/numerics/poissondist/Poissondist.md index 3f686635..4c9b39f7 100644 --- a/lib/numerics/poissondist/Poissondist.md +++ b/lib/numerics/poissondist/Poissondist.md @@ -1,5 +1,22 @@ # POISSONDIST: Poisson Distribution CDF +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Numeric | +| **Inputs** | Source (close) | +| **Parameters** | `lambda` (default 1.0), `period` (default 14), `threshold` (default 5) | +| **Outputs** | Single series (Poissondist) | +| **Output range** | Varies (see docs) | +| **Warmup** | `period` bars | + +### TL;DR + +- The Poisson Distribution CDF computes the probability $P(X \le k)$ for a Poisson random variable whose rate parameter $\lambda$ is derived from the... +- Parameterized by `lambda` (default 1.0), `period` (default 14), `threshold` (default 5). +- Output range: Varies (see docs). +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + The Poisson Distribution CDF computes the probability $P(X \le k)$ for a Poisson random variable whose rate parameter $\lambda$ is derived from the min-max normalized price. The Poisson distribution models the number of events in a fixed interval given a constant average rate, making it natural for count-based financial metrics (trade arrivals, tick counts, order flow). The implementation maps normalized price to $\lambda$ via a scale factor, then evaluates the CDF using the identity $P(X \le k) = 1 - P(k+1, \lambda)$ where $P(a, x)$ is the regularized lower incomplete gamma function. This reuses the same Lanczos log-gamma and series/continued-fraction infrastructure as GAMMADIST. ## Historical Context diff --git a/lib/numerics/relu/Relu.md b/lib/numerics/relu/Relu.md index cbae3fd5..a3b252be 100644 --- a/lib/numerics/relu/Relu.md +++ b/lib/numerics/relu/Relu.md @@ -1,5 +1,22 @@ # RELU: Rectified Linear Unit +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Numeric | +| **Inputs** | Source (close) | +| **Parameters** | None | +| **Outputs** | Single series (RELU) | +| **Output range** | Varies (see docs) | +| **Warmup** | `0` bars | + +### TL;DR + +- The Rectified Linear Unit (ReLU) activation function applies `max(0, x)` to each value, passing positive inputs unchanged while zeroing negative ones. +- No configurable parameters; computation is stateless per bar. +- Output range: Varies (see docs). +- Requires `0` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "The simplest non-linearity that works—ReLU's computational efficiency and gradient-friendly properties made deep learning practical." The Rectified Linear Unit (ReLU) activation function applies `max(0, x)` to each value, passing positive inputs unchanged while zeroing negative ones. Its simplicity belies its importance: ReLU enabled the training of deep neural networks by mitigating vanishing gradients, and its computational efficiency makes it the default activation for most architectures. diff --git a/lib/numerics/sigmoid/Sigmoid.md b/lib/numerics/sigmoid/Sigmoid.md index 0ab53fe9..a9f52c1c 100644 --- a/lib/numerics/sigmoid/Sigmoid.md +++ b/lib/numerics/sigmoid/Sigmoid.md @@ -1,5 +1,22 @@ # SIGMOID: Logistic Function +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Numeric | +| **Inputs** | Source (close) | +| **Parameters** | `k` (default 1.0), `x0` (default 0.0) | +| **Outputs** | Single series (Sigmoid) | +| **Output range** | Varies (see docs) | +| **Warmup** | `0` bars | + +### TL;DR + +- The Sigmoid (Logistic) transformer maps any real-valued input to the bounded range (0, 1) using the standard logistic function. +- Parameterized by `k` (default 1.0), `x0` (default 0.0). +- Output range: Varies (see docs). +- Requires `0` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "The sigmoid function is the S-curve that turns messy reality into neat probabilities—a mathematical diplomat that insists every answer must be between 0 and 1." The Sigmoid (Logistic) transformer maps any real-valued input to the bounded range (0, 1) using the standard logistic function. Its characteristic S-shaped curve makes it indispensable for probability estimation, neural network activations, and any scenario requiring bounded outputs from unbounded inputs. diff --git a/lib/numerics/slope/Slope.md b/lib/numerics/slope/Slope.md index d6847457..38cbf76d 100644 --- a/lib/numerics/slope/Slope.md +++ b/lib/numerics/slope/Slope.md @@ -1,5 +1,22 @@ # SLOPE: First Derivative (Velocity) +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Numeric | +| **Inputs** | Source (close) | +| **Parameters** | None | +| **Outputs** | Single series (SLOPE) | +| **Output range** | Varies (see docs) | +| **Warmup** | `2` bars | + +### TL;DR + +- SLOPE measures the instantaneous rate of change—the velocity of a time series. +- No configurable parameters; computation is stateless per bar. +- Output range: Varies (see docs). +- Requires `2` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "The simplest measure of change reveals the most: is it going up, or going down?" SLOPE measures the instantaneous rate of change—the velocity of a time series. As the first derivative, it answers the fundamental question: how fast is the value changing right now? A positive slope means ascending; negative means descending; zero means flat. This O(1) streaming implementation uses SIMD optimization for batch calculations and handles bar corrections via state rollback. diff --git a/lib/numerics/sqrttrans/Sqrttrans.md b/lib/numerics/sqrttrans/Sqrttrans.md index 40a2773a..7fdf8529 100644 --- a/lib/numerics/sqrttrans/Sqrttrans.md +++ b/lib/numerics/sqrttrans/Sqrttrans.md @@ -1,5 +1,22 @@ # SQRTTRANS: Square Root Transform +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Numeric | +| **Inputs** | Source (close) | +| **Parameters** | None | +| **Outputs** | Single series (SQRTTRANS) | +| **Output range** | Varies (see docs) | +| **Warmup** | `0` bars | + +### TL;DR + +- The Square Root (SQRT) transformer applies $\sqrt{x}$ to each value in a time series. +- No configurable parameters; computation is stateless per bar. +- Output range: Varies (see docs). +- Requires `0` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "The square root is nature's variance-stabilizing trick—halving the exponent space while preserving monotonicity. When price volatility scales with level, sqrt compresses the noise." The Square Root (SQRT) transformer applies $\sqrt{x}$ to each value in a time series. This variance-stabilizing transformation compresses ranges where volatility scales with magnitude, making it useful for heteroscedastic data where standard deviation increases with price level. @@ -193,4 +210,4 @@ var recovered = Sqrttrans.Calculate(squared); - Box, G.E.P., & Cox, D.R. (1964). "An Analysis of Transformations." *Journal of the Royal Statistical Society, Series B*, 26(2), 211-252. - Tukey, J.W. (1977). *Exploratory Data Analysis*. Addison-Wesley. (Variance-stabilizing transformations) -- IEEE 754-2019. *Standard for Floating-Point Arithmetic*. (sqrt specification) \ No newline at end of file +- IEEE 754-2019. *Standard for Floating-Point Arithmetic*. (sqrt specification) diff --git a/lib/numerics/tdist/Tdist.md b/lib/numerics/tdist/Tdist.md index f23f17b2..f0e19d11 100644 --- a/lib/numerics/tdist/Tdist.md +++ b/lib/numerics/tdist/Tdist.md @@ -1,5 +1,22 @@ # TDIST: Student's t-Distribution CDF +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Numeric | +| **Inputs** | Source (close) | +| **Parameters** | `nu` (default 10), `period` (default 14) | +| **Outputs** | Single series (Tdist) | +| **Output range** | Varies (see docs) | +| **Warmup** | `period` bars | + +### TL;DR + +- The Student's t-Distribution CDF transforms a min-max normalized price into the cumulative distribution function of Student's t-distribution, produ... +- Parameterized by `nu` (default 10), `period` (default 14). +- Output range: Varies (see docs). +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + The Student's t-Distribution CDF transforms a min-max normalized price into the cumulative distribution function of Student's t-distribution, producing an output in $[0, 1]$. The t-distribution is the normal distribution's heavier-tailed cousin: as degrees of freedom $\nu$ increase, it converges to the Gaussian; at low $\nu$ it accommodates extreme values that the normal distribution would assign negligible probability. The implementation normalizes price to $[0, 1]$, maps to a t-statistic via linear scaling to $[-3, +3]$, then evaluates the CDF through the regularized incomplete beta function. This makes TDIST a robust percentile ranking that is less sensitive to outliers than NORMDIST. ## Historical Context diff --git a/lib/numerics/weibulldist/Weibulldist.md b/lib/numerics/weibulldist/Weibulldist.md index 105019e5..b9e397d1 100644 --- a/lib/numerics/weibulldist/Weibulldist.md +++ b/lib/numerics/weibulldist/Weibulldist.md @@ -1,5 +1,22 @@ # WEIBULLDIST: Weibull Distribution CDF +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Numeric | +| **Inputs** | Source (close) | +| **Parameters** | `k` (default 1.5), `lambda` (default 1.0), `period` (default 14) | +| **Outputs** | Single series (Weibulldist) | +| **Output range** | Varies (see docs) | +| **Warmup** | `period` bars | + +### TL;DR + +- The Weibull Distribution CDF transforms a min-max normalized price into the cumulative distribution function of the Weibull distribution, producing... +- Parameterized by `k` (default 1.5), `lambda` (default 1.0), `period` (default 14). +- Output range: Varies (see docs). +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + The Weibull Distribution CDF transforms a min-max normalized price into the cumulative distribution function of the Weibull distribution, producing an output in $[0, 1]$. The Weibull distribution is a flexible two-parameter family that subsumes the exponential distribution ($k = 1$) and approximates the normal distribution ($k \approx 3.6$) as special cases. Its closed-form CDF requires only `pow` and `exp`, making it the computationally cheapest distribution indicator after EXPDIST. The shape parameter $k$ controls the CDF curvature: $k < 1$ produces a concave curve (rapid initial rise), $k = 1$ gives the exponential, $k = 2$ produces the Rayleigh distribution, and $k > 3$ creates an S-shaped curve approaching Gaussian behavior. ## Historical Context diff --git a/lib/oscillators/bbi/Bbi.md b/lib/oscillators/bbi/Bbi.md index 7bf9245c..8f54619b 100644 --- a/lib/oscillators/bbi/Bbi.md +++ b/lib/oscillators/bbi/Bbi.md @@ -1,4 +1,21 @@ -# BBI: Bulls Bears Index +# BBI: Bulls Bears Index + +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Oscillator | +| **Inputs** | Source (close) | +| **Parameters** | `p1` (default DefaultP1), `p2` (default DefaultP2), `p3` (default DefaultP3), `p4` (default DefaultP4) | +| **Outputs** | Single series (Bbi) | +| **Output range** | Varies (see docs) | +| **Warmup** | `Math.Max(Math.Max(p1, p2), Math.Max(p3, p4))` bars | + +### TL;DR + +- BBI (Bulls Bears Index) computes the arithmetic mean of four Simple Moving Averages with geometrically spaced periods (3, 6, 12, 24 by default). +- Parameterized by `p1` (default defaultp1), `p2` (default defaultp2), `p3` (default defaultp3), `p4` (default defaultp4). +- Output range: Varies (see docs). +- Requires `Math.Max(Math.Max(p1, p2), Math.Max(p3, p4))` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. > "Average four moving averages of doubling periods and you get a single line that votes on whether bulls or bears own the tape. It is a committee of trends, each watching a different time horizon, forced to agree on one number." diff --git a/lib/oscillators/brar/Brar.md b/lib/oscillators/brar/Brar.md index e2e3ff97..7a3936cc 100644 --- a/lib/oscillators/brar/Brar.md +++ b/lib/oscillators/brar/Brar.md @@ -1,5 +1,22 @@ # BRAR: Bull-Bear Power Ratio +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Oscillator | +| **Inputs** | OHLCV bar (TBar) | +| **Parameters** | `period` (default 26) | +| **Outputs** | Single series (Brar) | +| **Output range** | Varies (see docs) | +| **Warmup** | `period` bars | + +### TL;DR + +- BRAR is a dual-output sentiment oscillator from the Japanese technical analysis tradition that decomposes market pressure into two independent rati... +- Parameterized by `period` (default 26). +- Output range: Varies (see docs). +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "The open is the amateur's price. The close is the professional's price. The distance between them is where the money hides." BRAR is a dual-output sentiment oscillator from the Japanese technical analysis tradition that decomposes market pressure into two independent ratios: BR (Buying Ratio), which measures upside thrust relative to the previous close, and AR (Atmosphere Ratio), which measures intraday range asymmetry relative to the open. Both outputs oscillate around an equilibrium of 100, where values above 100 signal dominance of the measured pressure and values below 100 signal weakness. The default lookback of 26 bars (one Japanese trading month) produces stable readings with 4 additions per bar in streaming mode. diff --git a/lib/oscillators/coppock/Coppock.md b/lib/oscillators/coppock/Coppock.md index ebda29ed..eac6a7b5 100644 --- a/lib/oscillators/coppock/Coppock.md +++ b/lib/oscillators/coppock/Coppock.md @@ -1,4 +1,21 @@ -# COPPOCK: Coppock Curve +# COPPOCK: Coppock Curve + +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Oscillator | +| **Inputs** | Source (close) | +| **Parameters** | `longRoc` (default DefaultLongRoc), `shortRoc` (default DefaultShortRoc), `wmaPeriod` (default DefaultWmaPeriod) | +| **Outputs** | Single series (Coppock) | +| **Output range** | Varies (see docs) | +| **Warmup** | 1 bar | + +### TL;DR + +- The Coppock Curve is a long-term momentum oscillator that applies a Weighted Moving Average to the sum of two Rate of Change calculations at differ... +- Parameterized by `longroc` (default defaultlongroc), `shortroc` (default defaultshortroc), `wmaperiod` (default defaultwmaperiod). +- Output range: Varies (see docs). +- Requires 1 bar of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. The Coppock Curve is a long-term momentum oscillator that applies a Weighted Moving Average to the sum of two Rate of Change calculations at different lookback periods. Originally designed for monthly charts to identify major market bottoms, it produces a single oscillating line where zero-line crossovers from below signal long-term buying opportunities. The dual-ROC architecture captures both intermediate and longer-term momentum dynamics in a single smoothed output. diff --git a/lib/oscillators/crsi/Crsi.md b/lib/oscillators/crsi/Crsi.md index eeb60f96..5536f160 100644 --- a/lib/oscillators/crsi/Crsi.md +++ b/lib/oscillators/crsi/Crsi.md @@ -1,4 +1,21 @@ -# CRSI: Connors RSI +# CRSI: Connors RSI + +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Oscillator | +| **Inputs** | Source (close) | +| **Parameters** | `rsiPeriod` (default 3), `streakPeriod` (default 2), `rankPeriod` (default 100) | +| **Outputs** | Single series (Crsi) | +| **Output range** | Varies (see docs) | +| **Warmup** | 1 bar | + +### TL;DR + +- Connors RSI is a composite momentum oscillator that combines three independent measurements of price behavior into a single bounded (0-100) output:... +- Parameterized by `rsiperiod` (default 3), `streakperiod` (default 2), `rankperiod` (default 100). +- Output range: Varies (see docs). +- Requires 1 bar of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. Connors RSI is a composite momentum oscillator that combines three independent measurements of price behavior into a single bounded (0-100) output: a short-term RSI of price, an RSI of the consecutive up/down streak length, and a percentile rank of the current rate of change within its recent history. The equal-weighted average of these three components produces a mean-reverting oscillator where extreme readings (above 90 or below 10) identify statistically overbought or oversold conditions with higher reliability than single-component RSI alone. diff --git a/lib/oscillators/cti/Cti.md b/lib/oscillators/cti/Cti.md index 16636be3..e3cc9742 100644 --- a/lib/oscillators/cti/Cti.md +++ b/lib/oscillators/cti/Cti.md @@ -1,4 +1,21 @@ -# CTI: Correlation Trend Indicator +# CTI: Correlation Trend Indicator + +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Oscillator | +| **Inputs** | Source (close) | +| **Parameters** | `period` (default 20) | +| **Outputs** | Single series (Cti) | +| **Output range** | Varies (see docs) | +| **Warmup** | `period` bars | + +### TL;DR + +- The Correlation Trend Indicator computes the Pearson correlation coefficient between the price series and a linear time index over a rolling window... +- Parameterized by `period` (default 20). +- Output range: Varies (see docs). +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. The Correlation Trend Indicator computes the Pearson correlation coefficient between the price series and a linear time index over a rolling window, producing a bounded oscillator in the range $[-1, +1]$. Values near $+1$ indicate a strong linear uptrend, values near $-1$ indicate a strong linear downtrend, and values near zero indicate no linear trend relationship. The implementation achieves O(1) complexity per bar through incremental running sums that avoid recomputing the full correlation on each update. diff --git a/lib/oscillators/deco/Deco.md b/lib/oscillators/deco/Deco.md index 3abf7b28..5ae4938c 100644 --- a/lib/oscillators/deco/Deco.md +++ b/lib/oscillators/deco/Deco.md @@ -1,4 +1,21 @@ -# DECO: Ehlers Decycler Oscillator +# DECO: Ehlers Decycler Oscillator + +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Oscillator | +| **Inputs** | Source (close) | +| **Parameters** | `shortPeriod` (default 30), `longPeriod` (default 60) | +| **Outputs** | Single series (Deco) | +| **Output range** | $0$ to $1$ | +| **Warmup** | 1 bar | + +### TL;DR + +- The Decycler Oscillator (DECO) is a DSP-based oscillator developed by John F. +- Parameterized by `shortperiod` (default 30), `longperiod` (default 60). +- Output range: $0$ to $1$. +- Requires 1 bar of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. ## Overview diff --git a/lib/oscillators/dem/Dem.md b/lib/oscillators/dem/Dem.md index e502ae00..1f57a4d2 100644 --- a/lib/oscillators/dem/Dem.md +++ b/lib/oscillators/dem/Dem.md @@ -1,4 +1,21 @@ -# DEM: DeMarker Oscillator +# DEM: DeMarker Oscillator + +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Oscillator | +| **Inputs** | OHLCV bar (TBar) | +| **Parameters** | `period` (default 14) | +| **Outputs** | Single series (Dem) | +| **Output range** | Varies (see docs) | +| **Warmup** | `period + 1` bars | + +### TL;DR + +- DEM (DeMarker Oscillator) is a bounded [0, 1] momentum oscillator that measures sequential demand pressure by comparing each bar's high and low aga... +- Parameterized by `period` (default 14). +- Output range: Varies (see docs). +- Requires `period + 1` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. > "The trend is your friend — right up until DeMark starts counting against it." diff --git a/lib/oscillators/dosc/Dosc.md b/lib/oscillators/dosc/Dosc.md index cbd66a1e..d429c425 100644 --- a/lib/oscillators/dosc/Dosc.md +++ b/lib/oscillators/dosc/Dosc.md @@ -1,4 +1,21 @@ -# DOSC: Derivative Oscillator +# DOSC: Derivative Oscillator + +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Oscillator | +| **Inputs** | Source (close) | +| **Parameters** | `rsiPeriod` (default 14), `ema1Period` (default 5), `ema2Period` (default 3), `sigPeriod` (default 9) | +| **Outputs** | Single series (Dosc) | +| **Output range** | Varies (see docs) | +| **Warmup** | `rsiPeriod + sigPeriod` bars | + +### TL;DR + +- The Derivative Oscillator applies a four-stage signal processing pipeline to extract momentum inflection points: RSI via Wilder's smoothing, double... +- Parameterized by `rsiperiod` (default 14), `ema1period` (default 5), `ema2period` (default 3), `sigperiod` (default 9). +- Output range: Varies (see docs). +- Requires `rsiPeriod + sigPeriod` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. The Derivative Oscillator applies a four-stage signal processing pipeline to extract momentum inflection points: RSI via Wilder's smoothing, double EMA smoothing of the RSI, an SMA signal line of the double-smoothed result, and finally the difference between the smoothed RSI and its signal. The histogram output crosses zero at momentum turning points, offering earlier signals than raw RSI by isolating the rate of change of the smoothed momentum rather than the momentum level itself. diff --git a/lib/oscillators/dymoi/Dymoi.md b/lib/oscillators/dymoi/Dymoi.md index d9b29649..e027a65f 100644 --- a/lib/oscillators/dymoi/Dymoi.md +++ b/lib/oscillators/dymoi/Dymoi.md @@ -1,4 +1,21 @@ -# DYMOI: Dynamic Momentum Index +# DYMOI: Dynamic Momentum Index + +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Oscillator | +| **Inputs** | Source (close) | +| **Parameters** | `basePeriod` (default 14), `shortPeriod` (default 5), `longPeriod` (default 10), `minPeriod` (default 3), `maxPeriod` (default 30) | +| **Outputs** | Single series (Dymoi) | +| **Output range** | Varies (see docs) | +| **Warmup** | 1 bar | + +### TL;DR + +- DYMOI is a volatility-adaptive RSI: when recent price swings are large relative to longer-term swings, the RSI period shortens and the indicator be... +- Parameterized by `baseperiod` (default 14), `shortperiod` (default 5), `longperiod` (default 10), `minperiod` (default 3), `maxperiod` (default 30). +- Output range: Varies (see docs). +- Requires 1 bar of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. > "The market is not a fixed-frequency oscillator. Why would you analyze it with one?" — Tushar Chande & Stanley Kroll, *The New Technical Trader*, 1994 diff --git a/lib/oscillators/er/Er.md b/lib/oscillators/er/Er.md index 7ef097d2..c1061c30 100644 --- a/lib/oscillators/er/Er.md +++ b/lib/oscillators/er/Er.md @@ -8,6 +8,7 @@ | **Outputs** | Single series (Efficiency Ratio) | | **Output range** | $0$ to $1$ | | **Warmup** | `period + 1` bars | + ### TL;DR - ER measures the signal-to-noise ratio of price movement: net directional change divided by total path length. @@ -17,6 +18,7 @@ - Not available and therefore not validated against any other TA library > "The best trades move in a straight line. The worst ones wander. ER tells you which kind you're looking at." -- Perry Kaufman + ## Historical Context Perry Kaufman introduced the Efficiency Ratio in *Trading Systems and Methods* (1995) as part of his Adaptive Moving Average (KAMA) framework. The idea was straightforward: an ideal trend indicator should react quickly in trending markets and slowly in choppy ones. ER provides the adaptive signal that tells KAMA how to behave. diff --git a/lib/oscillators/gator/Gator.md b/lib/oscillators/gator/Gator.md index 375663e2..d9317c19 100644 --- a/lib/oscillators/gator/Gator.md +++ b/lib/oscillators/gator/Gator.md @@ -1,5 +1,22 @@ # GATOR: Williams Gator Oscillator +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Oscillator | +| **Inputs** | Source (close) | +| **Parameters** | `jawPeriod` (default 13), `jawShift` (default 8), `teethPeriod` (default 8), `teethShift` (default 5), `lipsPeriod` (default 5), `lipsShift` (default 3) | +| **Outputs** | Single series (Gator) | +| **Output range** | Varies (see docs) | +| **Warmup** | `Math.Max(jawPeriod + jawShift, Math.Max(teethPeriod + teethShift, lipsPeriod + lipsShift))` bars | + +### TL;DR + +- The Williams Gator Oscillator is a dual-histogram visualization of the Alligator indicator's convergence and divergence. +- Parameterized by `jawperiod` (default 13), `jawshift` (default 8), `teethperiod` (default 8), `teethshift` (default 5), `lipsperiod` (default 5), `lipsshift` (default 3). +- Output range: Varies (see docs). +- Requires `Math.Max(jawPeriod + jawShift, Math.Max(teethPeriod + teethShift, lipsPeriod + lipsShift))` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "The alligator tells you the trend exists. The gator tells you whether the alligator is hungry or full." The Williams Gator Oscillator is a dual-histogram visualization of the Alligator indicator's convergence and divergence. It strips the Alligator's three SMMA lines down to two absolute differences: upper (Jaw minus Teeth) and lower (negative of Teeth minus Lips). The result is a zero-centered oscillator where expanding bars signal trend acceleration and contracting bars signal trend exhaustion. Because it operates on pre-computed SMMA values, the Gator adds zero computational overhead beyond two subtractions, two absolute values, and one sign flip per bar. diff --git a/lib/oscillators/imi/Imi.md b/lib/oscillators/imi/Imi.md index acfd943b..1165df58 100644 --- a/lib/oscillators/imi/Imi.md +++ b/lib/oscillators/imi/Imi.md @@ -1,4 +1,21 @@ -# IMI: Intraday Momentum Index +# IMI: Intraday Momentum Index + +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Oscillator | +| **Inputs** | OHLCV bar (TBar) | +| **Parameters** | `period` (default 14) | +| **Outputs** | Single series (IMI) | +| **Output range** | Varies (see docs) | +| **Warmup** | `period` bars | + +### TL;DR + +- The Intraday Momentum Index measures buying and selling pressure using the open-to-close relationship within each bar, rather than the close-to-clo... +- Parameterized by `period` (default 14). +- Output range: Varies (see docs). +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. The Intraday Momentum Index measures buying and selling pressure using the open-to-close relationship within each bar, rather than the close-to-close changes used by RSI. Each bar is classified as a gain (close > open) or loss (close < open), with the magnitude being the absolute open-close difference. Rolling sums of gains and losses over the lookback period produce an RSI-like ratio scaled to 0-100. This bridges Japanese candlestick analysis with Western oscillator theory: bullish candles contribute to the gain sum, bearish candles contribute to the loss sum. Unlike RSI, IMI does not require a previous close and uses simple rolling sums rather than exponential smoothing, making it more responsive but noisier. Output is bounded 0-100 with conventional overbought (>70) and oversold (<30) zones. diff --git a/lib/oscillators/kst/Kst.md b/lib/oscillators/kst/Kst.md index 510b825e..5a406f04 100644 --- a/lib/oscillators/kst/Kst.md +++ b/lib/oscillators/kst/Kst.md @@ -1,4 +1,25 @@ -# KST: Know Sure Thing Oscillator +# KST: Know Sure Thing Oscillator + +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Oscillator | +| **Inputs** | Source (close) | +| **Parameters** | `r1` (default DefaultR1), `r2` (default DefaultR2), `r3` (default DefaultR3), `r4` (default DefaultR4), `s1` (default DefaultS1), `s2` (default DefaultS2), `s3` (default DefaultS3), `s4` (default DefaultS4), `sigPeriod` (default DefaultSigPeriod) | +| **Outputs** | Multiple series (KstValue, Signal) | +| **Output range** | Varies (see docs) | +| **Warmup** | `Math.Max(Math.Max(r1, r2), Math.Max(r3, r4)) + + Math.Max(Math.Max(s1, s2), Math.Max(s3, s4)) + + sigPeriod - 2` bars | + +### TL;DR + +- The Know Sure Thing is a multi-timeframe momentum oscillator that computes four Rate of Change values at progressively longer lookback periods, smo... +- Parameterized by `r1` (default defaultr1), `r2` (default defaultr2), `r3` (default defaultr3), `r4` (default defaultr4), `s1` (default defaults1), `s2` (default defaults2), `s3` (default defaults3), `s4` (default defaults4), `sigperiod` (default defaultsigperiod). +- Output range: Varies (see docs). +- Requires `Math.Max(Math.Max(r1, r2), Math.Max(r3, r4)) + + Math.Max(Math.Max(s1, s2), Math.Max(s3, s4)) + + sigPeriod - 2` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. The Know Sure Thing is a multi-timeframe momentum oscillator that computes four Rate of Change values at progressively longer lookback periods, smooths each with an independent SMA, then combines them using linearly increasing weights (1, 2, 3, 4) to produce a single composite momentum line. A signal line (SMA of the KST) provides crossover triggers. The weighted summation ensures longer-term momentum dominates the output while shorter-term components contribute responsiveness, creating a momentum indicator that reflects multiple cycle lengths simultaneously. diff --git a/lib/oscillators/lrsi/Lrsi.md b/lib/oscillators/lrsi/Lrsi.md index 5ddcd810..109c7214 100644 --- a/lib/oscillators/lrsi/Lrsi.md +++ b/lib/oscillators/lrsi/Lrsi.md @@ -1,4 +1,21 @@ -# LRSI: Laguerre RSI +# LRSI: Laguerre RSI + +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Oscillator | +| **Inputs** | Source (close) | +| **Parameters** | `gamma` (default 0.5) | +| **Outputs** | Single series (Lrsi) | +| **Output range** | Varies (see docs) | +| **Warmup** | `4` bars | + +### TL;DR + +- Laguerre RSI is an adaptive oscillator invented by John Ehlers that replaces standard RSI's Wilder-smoothed gain/loss averages with a 4-stage casca... +- Parameterized by `gamma` (default 0.5). +- Output range: Varies (see docs). +- Requires `4` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. > "The Laguerre transform lets you trade off between lag and smoothness using a single parameter." — John Ehlers diff --git a/lib/oscillators/marketfi/Marketfi.md b/lib/oscillators/marketfi/Marketfi.md index a5b0bb1a..41029b8f 100644 --- a/lib/oscillators/marketfi/Marketfi.md +++ b/lib/oscillators/marketfi/Marketfi.md @@ -1,5 +1,22 @@ # MARKETFI: Market Facilitation Index +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Oscillator | +| **Inputs** | OHLCV bar (TBar) | +| **Parameters** | None | +| **Outputs** | Single series (MARKETFI) | +| **Output range** | Varies (see docs) | +| **Warmup** | `> 1` bars | + +### TL;DR + +- The Market Facilitation Index answers a single question with arithmetic directness: how much price moved per unit of volume traded? +- No configurable parameters; computation is stateless per bar. +- Output range: Varies (see docs). +- Requires `> 1` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "Price moves in an empty room; volume tells you how many people showed up." The Market Facilitation Index answers a single question with arithmetic directness: how much price moved per unit of volume traded? One division. No lookback period. No smoothing. No parameter to debate. What you get is raw market efficiency — the price range a market delivers for each unit of liquidity consumed. diff --git a/lib/oscillators/mstoch/Mstoch.md b/lib/oscillators/mstoch/Mstoch.md index 204ebf91..9c0ac483 100644 --- a/lib/oscillators/mstoch/Mstoch.md +++ b/lib/oscillators/mstoch/Mstoch.md @@ -1,4 +1,21 @@ -# MSTOCH: Ehlers MESA Stochastic +# MSTOCH: Ehlers MESA Stochastic + +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Oscillator | +| **Inputs** | Source (close) | +| **Parameters** | `stochLength` (default 20), `hpLength` (default 48), `ssLength` (default 10) | +| **Outputs** | Single series (Mstoch) | +| **Output range** | Varies (see docs) | +| **Warmup** | 1 bar | + +### TL;DR + +- The MESA Stochastic applies John Ehlers' Roofing Filter as a preprocessing stage before computing a stochastic oscillator, then smooths the stochas... +- Parameterized by `stochlength` (default 20), `hplength` (default 48), `sslength` (default 10). +- Output range: Varies (see docs). +- Requires 1 bar of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. The MESA Stochastic applies John Ehlers' Roofing Filter as a preprocessing stage before computing a stochastic oscillator, then smooths the stochastic output with a Super Smoother. The Roofing Filter removes both low-frequency trend components (via highpass) and high-frequency noise (via Super Smoother), isolating the dominant cycle. The stochastic calculation on this filtered data produces a clean 0-to-1 oscillator that responds to cycle turning points rather than trend or noise, with substantially reduced whipsaw compared to conventional stochastic indicators. diff --git a/lib/oscillators/qqe/Qqe.md b/lib/oscillators/qqe/Qqe.md index 024c921d..0cc3b84d 100644 --- a/lib/oscillators/qqe/Qqe.md +++ b/lib/oscillators/qqe/Qqe.md @@ -1,4 +1,21 @@ -# QQE: Quantitative Qualitative Estimation +# QQE: Quantitative Qualitative Estimation + +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Oscillator | +| **Inputs** | Source (close) | +| **Parameters** | `rsiPeriod` (default DefaultRsiPeriod), `smoothFactor` (default DefaultSmoothFactor), `qqeFactor` (default DefaultQqeFactor) | +| **Outputs** | Single series (Qqe) | +| **Output range** | Varies (see docs) | +| **Warmup** | `rsiPeriod + smoothFactor + darPeriod * 2` bars | + +### TL;DR + +- Quantitative Qualitative Estimation applies a multi-stage smoothing pipeline to RSI and then constructs dynamic volatility-based trailing bands aro... +- Parameterized by `rsiperiod` (default defaultrsiperiod), `smoothfactor` (default defaultsmoothfactor), `qqefactor` (default defaultqqefactor). +- Output range: Varies (see docs). +- Requires `rsiPeriod + smoothFactor + darPeriod * 2` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. Quantitative Qualitative Estimation applies a multi-stage smoothing pipeline to RSI and then constructs dynamic volatility-based trailing bands around the smoothed result. The output is a dual-line system: the QQE line (smoothed RSI) and a trailing level that follows price directionally, similar to Parabolic SAR logic. Crossovers between the QQE line and its trailing level signal momentum shifts, while crossovers of the QQE line above and below 50 indicate trend direction. The trailing level adapts to volatility through a double-EMA of RSI absolute changes, making band width contract in quiet markets and expand during volatile conditions. diff --git a/lib/oscillators/reflex/Reflex.md b/lib/oscillators/reflex/Reflex.md index 485ac95d..6b8fdb42 100644 --- a/lib/oscillators/reflex/Reflex.md +++ b/lib/oscillators/reflex/Reflex.md @@ -1,4 +1,21 @@ -# REFLEX: Ehlers Reflex Indicator +# REFLEX: Ehlers Reflex Indicator + +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Oscillator | +| **Inputs** | Source (close) | +| **Parameters** | `period` | +| **Outputs** | Single series (Reflex) | +| **Output range** | Varies (see docs) | +| **Warmup** | `period` bars | + +### TL;DR + +- REFLEX is a zero-lag oscillator that measures the reversal tendency of price by comparing a Super-Smoother-filtered price against a linear extrapol... +- Parameterized by `period`. +- Output range: Varies (see docs). +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. > "John Ehlers measured how much a filtered price deviates from its own linear extrapolation. The result is a zero-lag oscillator that catches reversals before they happen, because the deviation is largest precisely when the trend is bending." diff --git a/lib/oscillators/reverseema/ReverseEma.md b/lib/oscillators/reverseema/ReverseEma.md index 4d123bff..41f7a808 100644 --- a/lib/oscillators/reverseema/ReverseEma.md +++ b/lib/oscillators/reverseema/ReverseEma.md @@ -1,5 +1,22 @@ # REVERSEEMA: Ehlers Reverse EMA +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Oscillator | +| **Inputs** | Source (close) | +| **Parameters** | `period` | +| **Outputs** | Single series (ReverseEma) | +| **Output range** | Varies (see docs) | +| **Warmup** | `period` bars | + +### TL;DR + +- The Reverse EMA applies an 8-stage cascaded Z-transform inversion to a compensated EMA, progressively extracting and subtracting the accumulated la... +- Parameterized by `period`. +- Output range: Varies (see docs). +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "The best way to remove lag is to understand where it comes from." — John F. Ehlers ## Introduction diff --git a/lib/oscillators/rvgi/Rvgi.md b/lib/oscillators/rvgi/Rvgi.md index 9bfb6da2..631f1337 100644 --- a/lib/oscillators/rvgi/Rvgi.md +++ b/lib/oscillators/rvgi/Rvgi.md @@ -1,4 +1,21 @@ -# RVGI: Relative Vigor Index +# RVGI: Relative Vigor Index + +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Oscillator | +| **Inputs** | OHLCV bar (TBar) | +| **Parameters** | `period` (default 10) | +| **Outputs** | Single series (Rvgi) | +| **Output range** | Varies (see docs) | +| **Warmup** | `period` bars | + +### TL;DR + +- The Relative Vigor Index measures the conviction of a price move by comparing closing strength (close minus open) to the total intrabar range (high... +- Parameterized by `period` (default 10). +- Output range: Varies (see docs). +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. The Relative Vigor Index measures the conviction of a price move by comparing closing strength (close minus open) to the total intrabar range (high minus low), smoothed through a symmetrically weighted moving average and then averaged over a lookback period. The premise is that in bullish markets, closes tend to occur near highs and opens near lows, producing positive RVGI values, while bearish markets show the opposite pattern. A 4-bar SWMA signal line provides crossover triggers. The indicator oscillates around zero with no fixed bounds. diff --git a/lib/oscillators/squeeze/Squeeze.md b/lib/oscillators/squeeze/Squeeze.md index 10552919..5ecadc6d 100644 --- a/lib/oscillators/squeeze/Squeeze.md +++ b/lib/oscillators/squeeze/Squeeze.md @@ -1,4 +1,21 @@ -# SQUEEZE: Squeeze Momentum +# SQUEEZE: Squeeze Momentum + +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Oscillator | +| **Inputs** | OHLCV bar (TBar) | +| **Parameters** | `period` (default 20), `bbMult` (default 2.0), `kcMult` (default 1.5) | +| **Outputs** | Single series (Squeeze) | +| **Output range** | Varies (see docs) | +| **Warmup** | `period` bars | + +### TL;DR + +- Squeeze Momentum combines Bollinger Band and Keltner Channel width analysis to detect low-volatility compression ("squeeze") states, while simultan... +- Parameterized by `period` (default 20), `bbmult` (default 2.0), `kcmult` (default 1.5). +- Output range: Varies (see docs). +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. Squeeze Momentum combines Bollinger Band and Keltner Channel width analysis to detect low-volatility compression ("squeeze") states, while simultaneously measuring directional momentum via linear regression of a detrended price series. The dual output consists of a momentum histogram and a binary squeeze state indicator. When Bollinger Bands contract inside the Keltner Channel, the market is in a squeeze (coiling volatility); when the squeeze releases, the momentum histogram direction signals the likely breakout direction. The implementation combines five distinct computational stages, each using O(1) streaming techniques. diff --git a/lib/oscillators/stc/stc.md b/lib/oscillators/stc/stc.md index 8cfe9e2f..b68065cc 100644 --- a/lib/oscillators/stc/stc.md +++ b/lib/oscillators/stc/stc.md @@ -1,5 +1,22 @@ # STC: Schaff Trend Cycle +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Oscillator | +| **Inputs** | Source (close) | +| **Parameters** | `kPeriod` (default 10), `dPeriod` (default 3), `fastLength` (default 23), `slowLength` (default 50), `smoothing` (default StcSmoothing.Ema) | +| **Outputs** | Single series (Stc) | +| **Output range** | $0$ to $100$ | +| **Warmup** | 1 bar | + +### TL;DR + +- The Schaff Trend Cycle is a cyclometric oscillator that applies double-Stochastic normalization to MACD, extracting the cyclical phase hidden withi... +- Parameterized by `kperiod` (default 10), `dperiod` (default 3), `fastlength` (default 23), `slowlength` (default 50), `smoothing` (default stcsmoothing.ema). +- Output range: $0$ to $100$. +- Requires 1 bar of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + The Schaff Trend Cycle is a cyclometric oscillator that applies double-Stochastic normalization to MACD, extracting the cyclical phase hidden within the trend itself. The recursive normalization produces a bounded 0–100 output that reaches extremes earlier than raw MACD while suppressing Stochastic jitter. Developed for currency markets, STC's tendency to flatline at 0 or 100 during strong trends signals continuation rather than reversal — a feature that distinguishes it from conventional momentum oscillators. Output converges toward a square wave in steady-state trending conditions. ## Historical Context diff --git a/lib/oscillators/td_seq/Td_seq.md b/lib/oscillators/td_seq/Td_seq.md index dd99735f..919c7022 100644 --- a/lib/oscillators/td_seq/Td_seq.md +++ b/lib/oscillators/td_seq/Td_seq.md @@ -1,4 +1,21 @@ -# TD_SEQ: TD Sequential +# TD_SEQ: TD Sequential + +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Oscillator | +| **Inputs** | OHLCV bar (TBar) | +| **Parameters** | None | +| **Outputs** | Single series (TdSeq) | +| **Output range** | Varies (see docs) | +| **Warmup** | `comparePeriod + 1` bars | + +### TL;DR + +- TD Sequential is Tom DeMark's exhaustion counting system that identifies potential trend reversals through two phases: a 9-count Setup phase that d... +- No configurable parameters; computation is stateless per bar. +- Output range: Varies (see docs). +- Requires `comparePeriod + 1` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. TD Sequential is Tom DeMark's exhaustion counting system that identifies potential trend reversals through two phases: a 9-count Setup phase that detects overextended trends, and a 13-count Countdown phase that pinpoints probable reversal timing. Unlike oscillators that measure momentum magnitude, TD Sequential counts consecutive qualifying bars, producing integer outputs (Setup: $\pm 1$ to $\pm 9$; Countdown: $\pm 1$ to $\pm 13$) that represent the progression toward exhaustion. A completed 9-count Setup followed by a completed 13-count Countdown signals high-probability trend exhaustion. All state is maintained in O(1) scalar variables with no buffers required. diff --git a/lib/oscillators/trendflex/Trendflex.md b/lib/oscillators/trendflex/Trendflex.md index 57a02b0d..33755645 100644 --- a/lib/oscillators/trendflex/Trendflex.md +++ b/lib/oscillators/trendflex/Trendflex.md @@ -1,5 +1,22 @@ # TRENDFLEX: Ehlers Trendflex Indicator +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Oscillator | +| **Inputs** | Source (close) | +| **Parameters** | `period` | +| **Outputs** | Single series (Trendflex) | +| **Output range** | Varies (see docs) | +| **Warmup** | `period` bars | + +### TL;DR + +- The Trendflex indicator combines a 2-pole Butterworth low-pass pre-filter (Super Smoother) with an O(1) cumulative slope measurement and exponentia... +- Parameterized by `period`. +- Output range: Varies (see docs). +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "The trend is your friend until it bends." — Ed Seykota, but Ehlers actually measures the bending. ## Introduction diff --git a/lib/reversals/chandelier/Chandelier.md b/lib/reversals/chandelier/Chandelier.md index d8387a75..813c14c5 100644 --- a/lib/reversals/chandelier/Chandelier.md +++ b/lib/reversals/chandelier/Chandelier.md @@ -1,5 +1,22 @@ # CHANDELIER: Chandelier Exit +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Reversal | +| **Inputs** | OHLCV bar (TBar) | +| **Parameters** | `period` (default DefaultPeriod), `multiplier` (default DefaultMultiplier) | +| **Outputs** | Single series (Chandelier) | +| **Output range** | Varies (see docs) | +| **Warmup** | `period + 1` bars | + +### TL;DR + +- The Chandelier Exit computes ATR-based trailing stop levels that hang from the highest high (for longs) or rise from the lowest low (for shorts) ov... +- Parameterized by `period` (default defaultperiod), `multiplier` (default defaultmultiplier). +- Output range: Varies (see docs). +- Requires `period + 1` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "The exit is more important than the entry. Everyone knows where to get in; getting out alive is the real trick." The Chandelier Exit computes ATR-based trailing stop levels that hang from the highest high (for longs) or rise from the lowest low (for shorts) over a lookback period. It produces two overlay lines: ExitLong (trailing stop for long positions) and ExitShort (trailing stop for short positions). Developed by Charles Le Beau and popularized by Alexander Elder. Default parameters: period 22, multiplier 3.0. diff --git a/lib/reversals/ckstop/Ckstop.md b/lib/reversals/ckstop/Ckstop.md index a5f7bd59..d428d67e 100644 --- a/lib/reversals/ckstop/Ckstop.md +++ b/lib/reversals/ckstop/Ckstop.md @@ -1,5 +1,22 @@ # CKSTOP: Chande Kroll Stop +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Reversal | +| **Inputs** | OHLCV bar (TBar) | +| **Parameters** | `atrPeriod` (default DefaultAtrPeriod), `multiplier` (default DefaultMultiplier), `stopPeriod` (default DefaultStopPeriod) | +| **Outputs** | Single series (Ckstop) | +| **Output range** | Varies (see docs) | +| **Warmup** | `atrPeriod + stopPeriod` bars | + +### TL;DR + +- The Chande Kroll Stop computes adaptive trailing stop levels using ATR-smoothed volatility envelopes around rolling extremes. +- Parameterized by `atrperiod` (default defaultatrperiod), `multiplier` (default defaultmultiplier), `stopperiod` (default defaultstopperiod). +- Output range: Varies (see docs). +- Requires `atrPeriod + stopPeriod` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "The best stop-loss is the one that knows where volatility ends and trend begins." The Chande Kroll Stop computes adaptive trailing stop levels using ATR-smoothed volatility envelopes around rolling extremes. It produces two lines: StopLong (support) and StopShort (resistance). When price trades above both stops, the trend is bullish. When below both, bearish. Crossovers between the two stops signal potential reversals. diff --git a/lib/reversals/fractals/Fractals.md b/lib/reversals/fractals/Fractals.md index b0d8ced6..e58693b7 100644 --- a/lib/reversals/fractals/Fractals.md +++ b/lib/reversals/fractals/Fractals.md @@ -1,5 +1,22 @@ # FRACTALS: Williams Fractals +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Reversal | +| **Inputs** | OHLCV bar (TBar) | +| **Parameters** | None | +| **Outputs** | Single series (FRACTALS) | +| **Output range** | Varies (see docs) | +| **Warmup** | 1 bar | + +### TL;DR + +- Williams Fractals detect local price extremes using a strict five-bar pattern: an Up Fractal marks a bar whose high exceeds the highs of the two ba... +- No configurable parameters; computation is stateless per bar. +- Output range: Varies (see docs). +- Requires 1 bar of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "Markets leave fingerprints at their turning points. Five bars is all it takes to read them." Williams Fractals detect local price extremes using a strict five-bar pattern: an Up Fractal marks a bar whose high exceeds the highs of the two bars before and after it; a Down Fractal marks a bar whose low undercuts the lows of the two bars before and after it. No parameters, no smoothing, no lag compensation. The pattern either exists or it does not. Developed by Bill Williams and published in *Trading Chaos* (1995). diff --git a/lib/reversals/pivot/Pivot.Validation.Tests.cs b/lib/reversals/pivot/Pivot.Validation.Tests.cs index 55f6495c..188d1a66 100644 --- a/lib/reversals/pivot/Pivot.Validation.Tests.cs +++ b/lib/reversals/pivot/Pivot.Validation.Tests.cs @@ -1,6 +1,4 @@ -using OoplesFinance.StockIndicators; -using OoplesFinance.StockIndicators.Models; // PIVOT Validation Tests - Classic Pivot Points (Floor Trader Pivots) // Self-consistency validation across all API modes. // @@ -261,23 +259,4 @@ public sealed class PivotValidationTests } } - [Fact(Skip = "Ooples pivot indicators group by calendar day — 500×1-min bars yields ~3 daily pivots. Requires daily OHLCV input; not comparable with intraday GBM data.")] - public void Pivot_MatchesOoples_Structural() - { - var gbm = new GBM(startPrice: 100.0, mu: 0.02, sigma: 0.15, seed: 42); - var bars = gbm.Fetch(500, DateTime.UtcNow.Ticks, TimeSpan.FromMinutes(1)); - var ooplesData = bars.Select(b => new TickerData - { - Date = new DateTime(b.Time, DateTimeKind.Utc), - Open = b.Open, - High = b.High, - Low = b.Low, - Close = b.Close, - Volume = b.Volume - }).ToList(); - var result = new StockData(ooplesData).CalculateStandardPivotPoints(); - var values = result.OutputValues.Values.First(); - int finiteCount = values.Count(v => double.IsFinite(v)); - Assert.True(finiteCount > 100, $"Expected >100 finite values, got {finiteCount}"); - } } \ No newline at end of file diff --git a/lib/reversals/pivot/Pivot.md b/lib/reversals/pivot/Pivot.md index af31bd18..4af92280 100644 --- a/lib/reversals/pivot/Pivot.md +++ b/lib/reversals/pivot/Pivot.md @@ -1,5 +1,22 @@ # PIVOT: Classic Pivot Points (Floor Trader Pivots) +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Reversal | +| **Inputs** | OHLCV bar (TBar) | +| **Parameters** | None | +| **Outputs** | Single series (PIVOT) | +| **Output range** | Varies (see docs) | +| **Warmup** | `2` bars | + +### TL;DR + +- Classic Pivot Points calculate seven horizontal support and resistance levels from the previous bar's high, low, and close. +- No configurable parameters; computation is stateless per bar. +- Output range: Varies (see docs). +- Requires `2` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "The floor traders had it figured out before the quants arrived. Three numbers from yesterday's bar, seven levels for today. No optimization, no curve fitting, no excuses." Classic Pivot Points calculate seven horizontal support and resistance levels from the previous bar's high, low, and close. The central pivot point (PP) is the arithmetic mean of HLC; three resistance levels (R1-R3) and three support levels (S1-S3) are derived from PP and the prior bar's range. The formula has been in continuous use since the 1930s among floor traders at commodity exchanges. Zero parameters, zero lag, zero ambiguity. diff --git a/lib/reversals/pivotcam/Pivotcam.Validation.Tests.cs b/lib/reversals/pivotcam/Pivotcam.Validation.Tests.cs index 075c5dd7..70e5cee4 100644 --- a/lib/reversals/pivotcam/Pivotcam.Validation.Tests.cs +++ b/lib/reversals/pivotcam/Pivotcam.Validation.Tests.cs @@ -1,6 +1,4 @@ -using OoplesFinance.StockIndicators; -using OoplesFinance.StockIndicators.Models; // PIVOTCAM Validation Tests - Camarilla Pivot Points // Self-consistency validation across all API modes. // @@ -275,23 +273,4 @@ public sealed class PivotcamValidationTests } } - [Fact(Skip = "Ooples pivot indicators group by calendar day — 500×1-min bars yields ~3 daily pivots. Requires daily OHLCV input; not comparable with intraday GBM data.")] - public void Pivotcam_MatchesOoples_Structural() - { - var gbm = new GBM(startPrice: 100.0, mu: 0.02, sigma: 0.15, seed: 42); - var bars = gbm.Fetch(500, DateTime.UtcNow.Ticks, TimeSpan.FromMinutes(1)); - var ooplesData = bars.Select(b => new TickerData - { - Date = new DateTime(b.Time, DateTimeKind.Utc), - Open = b.Open, - High = b.High, - Low = b.Low, - Close = b.Close, - Volume = b.Volume - }).ToList(); - var result = new StockData(ooplesData).CalculateCamarillaPivotPoints(); - var values = result.OutputValues.Values.First(); - int finiteCount = values.Count(v => double.IsFinite(v)); - Assert.True(finiteCount > 100, $"Expected >100 finite values, got {finiteCount}"); - } } \ No newline at end of file diff --git a/lib/reversals/pivotcam/Pivotcam.md b/lib/reversals/pivotcam/Pivotcam.md index 74c65e75..8fed1e8b 100644 --- a/lib/reversals/pivotcam/Pivotcam.md +++ b/lib/reversals/pivotcam/Pivotcam.md @@ -1,5 +1,22 @@ # PIVOTCAM: Camarilla Pivot Points +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Reversal | +| **Inputs** | OHLCV bar (TBar) | +| **Parameters** | None | +| **Outputs** | Single series (PIVOTCAM) | +| **Output range** | Varies (see docs) | +| **Warmup** | `2` bars | + +### TL;DR + +- Camarilla Pivot Points calculate nine horizontal support and resistance levels from the previous bar's high, low, and close. +- No configurable parameters; computation is stateless per bar. +- Output range: Varies (see docs). +- Requires `2` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "The Camarilla trader does not care where the market opens. The trader cares how far price strays from yesterday's close, and whether it returns." Camarilla Pivot Points calculate nine horizontal support and resistance levels from the previous bar's high, low, and close. Unlike classic floor trader pivots that radiate from the PP midpoint, Camarilla levels radiate symmetrically from the previous close using fixed fractions of the prior range. The R3/S3 levels serve as the primary mean-reversion zone; breakouts beyond R4/S4 signal trend continuation. Developed by Nick Scott in 1989 using bond market data, the equation was originally distributed as a shareware Excel plugin. diff --git a/lib/reversals/pivotdem/Pivotdem.Validation.Tests.cs b/lib/reversals/pivotdem/Pivotdem.Validation.Tests.cs index 03e4964e..40f267b5 100644 --- a/lib/reversals/pivotdem/Pivotdem.Validation.Tests.cs +++ b/lib/reversals/pivotdem/Pivotdem.Validation.Tests.cs @@ -1,6 +1,4 @@ -using OoplesFinance.StockIndicators; -using OoplesFinance.StockIndicators.Models; // PIVOTDEM Validation Tests - DeMark Pivot Points // Self-consistency validation across all API modes. // @@ -242,23 +240,4 @@ public sealed class PivotdemValidationTests } } - [Fact(Skip = "Ooples pivot indicators group by calendar day — 500×1-min bars yields ~3 daily pivots. Requires daily OHLCV input; not comparable with intraday GBM data.")] - public void Pivotdem_MatchesOoples_Structural() - { - var gbm = new GBM(startPrice: 100.0, mu: 0.02, sigma: 0.15, seed: 42); - var bars = gbm.Fetch(500, DateTime.UtcNow.Ticks, TimeSpan.FromMinutes(1)); - var ooplesData = bars.Select(b => new TickerData - { - Date = new DateTime(b.Time, DateTimeKind.Utc), - Open = b.Open, - High = b.High, - Low = b.Low, - Close = b.Close, - Volume = b.Volume - }).ToList(); - var result = new StockData(ooplesData).CalculateDemarkPivotPoints(); - var values = result.OutputValues.Values.First(); - int finiteCount = values.Count(v => double.IsFinite(v)); - Assert.True(finiteCount > 100, $"Expected >100 finite values, got {finiteCount}"); - } } \ No newline at end of file diff --git a/lib/reversals/pivotdem/Pivotdem.md b/lib/reversals/pivotdem/Pivotdem.md index 12326de0..3302458e 100644 --- a/lib/reversals/pivotdem/Pivotdem.md +++ b/lib/reversals/pivotdem/Pivotdem.md @@ -1,5 +1,22 @@ # PIVOTDEM: DeMark Pivot Points +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Reversal | +| **Inputs** | OHLCV bar (TBar) | +| **Parameters** | None | +| **Outputs** | Single series (PIVOTDEM) | +| **Output range** | Varies (see docs) | +| **Warmup** | `2` bars | + +### TL;DR + +- DeMark Pivot Points calculate three horizontal support and resistance levels from the previous bar's open, high, low, and close. +- No configurable parameters; computation is stateless per bar. +- Output range: Varies (see docs). +- Requires `2` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "Most pivot formulas treat every bar the same. DeMark looked at the open-close relationship and asked: why would a bearish bar predict the same levels as a bullish one?" DeMark Pivot Points calculate three horizontal support and resistance levels from the previous bar's open, high, low, and close. The defining characteristic is a conditional intermediate value X that changes its weighting depending on whether the prior bar closed below, above, or equal to its open. Bearish bars weight the low; bullish bars weight the high; doji bars weight the close. Three levels (PP, R1, S1) emerge from this single conditional calculation. The only pivot variant that uses the open price. diff --git a/lib/reversals/pivotext/Pivotext.md b/lib/reversals/pivotext/Pivotext.md index b4f70f31..16ccac4f 100644 --- a/lib/reversals/pivotext/Pivotext.md +++ b/lib/reversals/pivotext/Pivotext.md @@ -1,5 +1,22 @@ # PIVOTEXT: Extended Traditional Pivot Points +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Reversal | +| **Inputs** | OHLCV bar (TBar) | +| **Parameters** | None | +| **Outputs** | Single series (PIVOTEXT) | +| **Output range** | Varies (see docs) | +| **Warmup** | `2` bars | + +### TL;DR + +- Extended Traditional Pivot Points calculate eleven horizontal support and resistance levels from the previous bar's high, low, and close. +- No configurable parameters; computation is stateless per bar. +- Output range: Varies (see docs). +- Requires `2` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "Classic pivots tell you where the crowd expects the market to pause. Extended pivots tell you where the crowd starts to panic." Extended Traditional Pivot Points calculate eleven horizontal support and resistance levels from the previous bar's high, low, and close. The core levels (PP, R1-R3, S1-S3) are identical to classic floor trader pivots. The extension adds R4/R5 and S4/S5 levels that project further beyond the prior bar's range, covering extreme move scenarios such as gap opens, news-driven spikes, and trend continuation through multiple prior-range increments. The formula is pure arithmetic with zero parameters. diff --git a/lib/reversals/pivotfib/Pivotfib.Validation.Tests.cs b/lib/reversals/pivotfib/Pivotfib.Validation.Tests.cs index 107a8989..77f6402f 100644 --- a/lib/reversals/pivotfib/Pivotfib.Validation.Tests.cs +++ b/lib/reversals/pivotfib/Pivotfib.Validation.Tests.cs @@ -5,9 +5,6 @@ using System.Runtime.InteropServices; -using OoplesFinance.StockIndicators; -using OoplesFinance.StockIndicators.Models; - namespace QuanTAlib.Tests; public sealed class PivotfibValidationTests @@ -249,23 +246,4 @@ public sealed class PivotfibValidationTests } } - [Fact(Skip = "Ooples pivot indicators group by calendar day — 500×1-min bars yields ~3 daily pivots. Requires daily OHLCV input; not comparable with intraday GBM data.")] - public void Pivotfib_MatchesOoples_Structural() - { - var gbm = new GBM(startPrice: 100.0, mu: 0.02, sigma: 0.15, seed: 42); - var bars = gbm.Fetch(500, DateTime.UtcNow.Ticks, TimeSpan.FromMinutes(1)); - var ooplesData = bars.Select(b => new TickerData - { - Date = new DateTime(b.Time, DateTimeKind.Utc), - Open = b.Open, - High = b.High, - Low = b.Low, - Close = b.Close, - Volume = b.Volume - }).ToList(); - var result = new StockData(ooplesData).CalculateFibonacciPivotPoints(); - var values = result.OutputValues.Values.First(); - int finiteCount = values.Count(v => double.IsFinite(v)); - Assert.True(finiteCount > 100, $"Expected >100 finite values, got {finiteCount}"); - } } \ No newline at end of file diff --git a/lib/reversals/pivotfib/Pivotfib.md b/lib/reversals/pivotfib/Pivotfib.md index e921caa5..ec35637e 100644 --- a/lib/reversals/pivotfib/Pivotfib.md +++ b/lib/reversals/pivotfib/Pivotfib.md @@ -1,5 +1,22 @@ # PIVOTFIB: Fibonacci Pivot Points +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Reversal | +| **Inputs** | OHLCV bar (TBar) | +| **Parameters** | None | +| **Outputs** | Single series (PIVOTFIB) | +| **Output range** | Varies (see docs) | +| **Warmup** | `2` bars | + +### TL;DR + +- Fibonacci Pivot Points apply Fibonacci retracement ratios (38.2%, 61.8%, 100%) to the standard pivot point formula. +- No configurable parameters; computation is stateless per bar. +- Output range: Varies (see docs). +- Requires `2` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + ## Overview Fibonacci Pivot Points apply Fibonacci retracement ratios (38.2%, 61.8%, 100%) to the standard pivot point formula. The central pivot (PP) uses the classic HLC/3 calculation, while support and resistance levels are derived by adding or subtracting Fibonacci proportions of the previous bar's trading range. diff --git a/lib/reversals/pivotwood/Pivotwood.Validation.Tests.cs b/lib/reversals/pivotwood/Pivotwood.Validation.Tests.cs index b91eecc5..78495a20 100644 --- a/lib/reversals/pivotwood/Pivotwood.Validation.Tests.cs +++ b/lib/reversals/pivotwood/Pivotwood.Validation.Tests.cs @@ -5,9 +5,6 @@ using System.Runtime.InteropServices; -using OoplesFinance.StockIndicators; -using OoplesFinance.StockIndicators.Models; - namespace QuanTAlib.Tests; public sealed class PivotwoodValidationTests @@ -257,23 +254,4 @@ public sealed class PivotwoodValidationTests } } - [Fact(Skip = "Ooples pivot indicators group by calendar day — 500×1-min bars yields ~3 daily pivots. Requires daily OHLCV input; not comparable with intraday GBM data.")] - public void Pivotwood_MatchesOoples_Structural() - { - var gbm = new GBM(startPrice: 100.0, mu: 0.02, sigma: 0.15, seed: 42); - var bars = gbm.Fetch(500, DateTime.UtcNow.Ticks, TimeSpan.FromMinutes(1)); - var ooplesData = bars.Select(b => new TickerData - { - Date = new DateTime(b.Time, DateTimeKind.Utc), - Open = b.Open, - High = b.High, - Low = b.Low, - Close = b.Close, - Volume = b.Volume - }).ToList(); - var result = new StockData(ooplesData).CalculateWoodiePivotPoints(); - var values = result.OutputValues.Values.First(); - int finiteCount = values.Count(v => double.IsFinite(v)); - Assert.True(finiteCount > 100, $"Expected >100 finite values, got {finiteCount}"); - } } \ No newline at end of file diff --git a/lib/reversals/pivotwood/Pivotwood.md b/lib/reversals/pivotwood/Pivotwood.md index aa05b77c..5ef3cc13 100644 --- a/lib/reversals/pivotwood/Pivotwood.md +++ b/lib/reversals/pivotwood/Pivotwood.md @@ -1,5 +1,22 @@ # PIVOTWOOD: Woodie's Pivot Points +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Reversal | +| **Inputs** | OHLCV bar (TBar) | +| **Parameters** | None | +| **Outputs** | Single series (PIVOTWOOD) | +| **Output range** | Varies (see docs) | +| **Warmup** | `2` bars | + +### TL;DR + +- Woodie's Pivot Points weight the closing price twice in the pivot calculation, biasing the central pivot toward where the market actually settled r... +- No configurable parameters; computation is stateless per bar. +- Output range: Varies (see docs). +- Requires `2` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + ## Overview Woodie's Pivot Points weight the closing price twice in the pivot calculation, biasing the central pivot toward where the market actually settled rather than treating high, low, and close equally. This close-weighted approach gives more emphasis to recent price action, making the pivot levels more responsive to the prior bar's close. diff --git a/lib/reversals/psar/Psar.md b/lib/reversals/psar/Psar.md index 14252d67..c401bc82 100644 --- a/lib/reversals/psar/Psar.md +++ b/lib/reversals/psar/Psar.md @@ -1,5 +1,22 @@ # PSAR: Parabolic Stop And Reverse +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Reversal | +| **Inputs** | OHLCV bar (TBar) | +| **Parameters** | `afStart` (default DefaultAfStart), `afIncrement` (default DefaultAfIncrement), `afMax` (default DefaultAfMax) | +| **Outputs** | Single series (Psar) | +| **Output range** | Varies (see docs) | +| **Warmup** | `1` bars | + +### TL;DR + +- The Parabolic Stop And Reverse (PSAR) is a trend-following overlay indicator created by J. +- Parameterized by `afstart` (default defaultafstart), `afincrement` (default defaultafincrement), `afmax` (default defaultafmax). +- Output range: Varies (see docs). +- Requires `1` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "The trend is your friend until the end when it bends." — Ed Seykota ## Introduction diff --git a/lib/reversals/swings/Swings.md b/lib/reversals/swings/Swings.md index 93ad7bab..dba38ea7 100644 --- a/lib/reversals/swings/Swings.md +++ b/lib/reversals/swings/Swings.md @@ -1,5 +1,22 @@ # SWINGS: Swing High/Low Detection +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Reversal | +| **Inputs** | OHLCV bar (TBar) | +| **Parameters** | `lookback` (default DefaultLookback) | +| **Outputs** | Single series (Swings) | +| **Output range** | Varies (see docs) | +| **Warmup** | 1 bar | + +### TL;DR + +- Swing High/Low detection identifies local price extremes using a configurable lookback window. +- Parameterized by `lookback` (default defaultlookback). +- Output range: Varies (see docs). +- Requires 1 bar of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "The market tells you where it turned. You just have to listen long enough to be sure it actually meant it." Swing High/Low detection identifies local price extremes using a configurable lookback window. A Swing High marks a bar whose high strictly exceeds the highs of all bars within the lookback window on each side. A Swing Low marks a bar whose low is strictly less than all corresponding lows. The lookback parameter controls sensitivity: larger lookback windows require more confirmation and produce fewer, more significant signals. This generalizes Williams' fixed five-bar Fractals into a flexible structural analysis tool. diff --git a/lib/reversals/ttm_scalper/TtmScalper.md b/lib/reversals/ttm_scalper/TtmScalper.md index 3a8753c6..faafe971 100644 --- a/lib/reversals/ttm_scalper/TtmScalper.md +++ b/lib/reversals/ttm_scalper/TtmScalper.md @@ -1,5 +1,22 @@ # TTM_SCALPER: TTM Scalper Alert +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Reversal | +| **Inputs** | OHLCV bar (TBar) | +| **Parameters** | `useCloses` (default false) | +| **Outputs** | Single series (TtmScalper) | +| **Output range** | Varies (see docs) | +| **Warmup** | 1 bar | + +### TL;DR + +- John Carter designed TTM Scalper Alert for quick identification of potential reversal points using a simple three-bar pattern recognition. +- Parameterized by `usecloses` (default false). +- Output range: Varies (see docs). +- Requires 1 bar of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > **Pending Implementation** - Placeholder for John Carter's TTM Scalper Alert indicator ## Historical Context @@ -92,4 +109,4 @@ O(1) per bar. All state fits in two RingBuffers of size 3. Signal logic is a bra | Signal comparison | Yes | Vector conditional-select for buy/sell | | Output array fill | Yes | Branchless signal assignment | -Limited SIMD benefit due to 3-bar window size — setup cost exceeds savings. The comparison/signal phase is SIMD-friendly for batch output. \ No newline at end of file +Limited SIMD benefit due to 3-bar window size — setup cost exceeds savings. The comparison/signal phase is SIMD-friendly for batch output. diff --git a/lib/statistics/acf/Acf.Validation.Tests.cs b/lib/statistics/acf/Acf.Validation.Tests.cs index 9a3872e9..ed2daf0b 100644 --- a/lib/statistics/acf/Acf.Validation.Tests.cs +++ b/lib/statistics/acf/Acf.Validation.Tests.cs @@ -114,11 +114,11 @@ public class AcfValidationTests // For white noise, ACF at any lag > 0 should be close to zero var acf = new Acf(100, 5); - // Generate pseudo-random values with zero mean - var random = new Random(42); + // Generate pseudo-random values with zero mean via GBM log-returns + var random = new GBM(startPrice: 100.0, sigma: 1.0, seed: 42); for (int i = 0; i < 500; i++) { - double val = random.NextDouble() * 2 - 1; // Uniform [-1, 1] + double val = Math.Log(random.Next().Close / 100.0); // ~N(0, vol²*dt) centered near 0 acf.Update(new TValue(DateTime.UtcNow.AddSeconds(i), val)); } @@ -215,12 +215,12 @@ public class AcfValidationTests double[] ar1Data = new double[n]; ar1Data[0] = 0; - var random = new Random(42); + var random = new GBM(startPrice: 100.0, sigma: 1.0, seed: 42); // Generate AR(1) process for (int i = 1; i < n; i++) { - double epsilon = (random.NextDouble() * 2 - 1) * 0.1; // Small noise + double epsilon = Math.Log(random.Next().Close / 100.0) * 0.1; // Small noise ar1Data[i] = phi * ar1Data[i - 1] + epsilon; } diff --git a/lib/statistics/acf/Acf.md b/lib/statistics/acf/Acf.md index d84f45c5..05c36d52 100644 --- a/lib/statistics/acf/Acf.md +++ b/lib/statistics/acf/Acf.md @@ -1,5 +1,22 @@ # ACF: Autocorrelation Function +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Statistic | +| **Inputs** | Source (close) | +| **Parameters** | `period`, `lag` (default 1) | +| **Outputs** | Single series (Acf) | +| **Output range** | Varies (see docs) | +| **Warmup** | `period` bars | + +### TL;DR + +- The Autocorrelation Function (ACF) measures the correlation of a time series with a lagged copy of itself. +- Parameterized by `period`, `lag` (default 1). +- Output range: Varies (see docs). +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "The past doesn't predict the future, but it whispers patterns to those who listen." The Autocorrelation Function (ACF) measures the correlation of a time series with a lagged copy of itself. It is fundamental for identifying repeating patterns, seasonal effects, and determining the order of time series models like ARMA/ARIMA. @@ -159,4 +176,4 @@ A random walk should have ACF ≈ 0 at all lags. Significant ACF values indicate - Box, G.E.P., Jenkins, G.M. (1970). *Time Series Analysis: Forecasting and Control*. Holden-Day. - Hamilton, J.D. (1994). *Time Series Analysis*. Princeton University Press. -- Yule, G.U. (1927). "On a Method of Investigating Periodicities in Disturbed Series." *Philosophical Transactions of the Royal Society*. \ No newline at end of file +- Yule, G.U. (1927). "On a Method of Investigating Periodicities in Disturbed Series." *Philosophical Transactions of the Royal Society*. diff --git a/lib/statistics/beta/Beta.md b/lib/statistics/beta/Beta.md index a2cafdcc..c00c252b 100644 --- a/lib/statistics/beta/Beta.md +++ b/lib/statistics/beta/Beta.md @@ -1,5 +1,22 @@ # Beta: Beta Coefficient +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Statistic | +| **Inputs** | Source (close) | +| **Parameters** | `period` | +| **Outputs** | Single series (Beta) | +| **Output range** | Varies (see docs) | +| **Warmup** | `period + 1` bars | + +### TL;DR + +- Beta measures the volatility of an asset in relation to the overall market. +- Parameterized by `period`. +- Output range: Varies (see docs). +- Requires `period + 1` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "Volatility is not risk. It's the price of admission." Beta measures the volatility of an asset in relation to the overall market. It's the slope of the regression line between the asset's returns and the market's returns. A beta of 1.0 means the asset moves in lockstep with the market. A beta of 2.0 means the asset is twice as volatile as the market. diff --git a/lib/statistics/cma/Cma.md b/lib/statistics/cma/Cma.md index ded42fa5..e1285234 100644 --- a/lib/statistics/cma/Cma.md +++ b/lib/statistics/cma/Cma.md @@ -1,5 +1,22 @@ # CMA: Cumulative Moving Average +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Statistic | +| **Inputs** | Source (close) | +| **Parameters** | `source` | +| **Outputs** | Single series (CMA) | +| **Output range** | Varies (see docs) | +| **Warmup** | `1` bars | + +### TL;DR + +- The Cumulative Moving Average (CMA) calculates the arithmetic mean of ALL data points seen so far, not just a fixed window. +- Parameterized by `source`. +- Output range: Varies (see docs). +- Requires `1` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "The running average that never forgets. Every single tick you've ever fed it? Still in there, affecting the result. It's like the elephant of technical indicators." The Cumulative Moving Average (CMA) calculates the arithmetic mean of ALL data points seen so far, not just a fixed window. Unlike SMA or EMA which use a sliding window, CMA treats every historical value with equal weight. As the sample size grows, each new value has diminishing impact on the average. diff --git a/lib/statistics/cointegration/Cointegration.Tests.cs b/lib/statistics/cointegration/Cointegration.Tests.cs index 70885faf..63ac5508 100644 --- a/lib/statistics/cointegration/Cointegration.Tests.cs +++ b/lib/statistics/cointegration/Cointegration.Tests.cs @@ -581,12 +581,12 @@ public class CointegrationTests { // Create two cointegrated series: B = A + noise var indicator = new Cointegration(20); - var random = new Random(42); + var random = new GBM(startPrice: 100.0, sigma: 1.0, seed: 42); for (int i = 0; i < 100; i++) { double a = 100.0 + i * 0.1; - double b = a + random.NextDouble() * 0.1 - 0.05; // Highly correlated + double b = a + Math.Log(random.Next().Close / 100.0) * 0.1; // Highly correlated indicator.Update(a, b); } @@ -601,7 +601,7 @@ public class CointegrationTests // Create two non-cointegrated series (random walks) var indicatorCointegrated = new Cointegration(20); var indicatorRandom = new Cointegration(20); - var random = new Random(42); + var random = new GBM(startPrice: 100.0, sigma: 1.0, seed: 42); double walkA = 100.0; double walkB = 100.0; @@ -610,12 +610,13 @@ public class CointegrationTests { // Cointegrated pair double a1 = 100.0 + i * 0.1; - double b1 = a1 + random.NextDouble() * 0.1; + double noise1 = Math.Log(random.Next().Close / 100.0); + double b1 = a1 + noise1 * 0.1; indicatorCointegrated.Update(a1, b1); // Random walks - walkA += random.NextDouble() - 0.5; - walkB += random.NextDouble() - 0.5; + walkA += Math.Log(random.Next().Close / 100.0); + walkB += Math.Log(random.Next().Close / 100.0); indicatorRandom.Update(walkA, walkB); } diff --git a/lib/statistics/cointegration/Cointegration.Validation.Tests.cs b/lib/statistics/cointegration/Cointegration.Validation.Tests.cs index c87286fa..bfc917b5 100644 --- a/lib/statistics/cointegration/Cointegration.Validation.Tests.cs +++ b/lib/statistics/cointegration/Cointegration.Validation.Tests.cs @@ -10,6 +10,9 @@ public class CointegrationValidationTests { private const double Tolerance = 1e-6; + // GBM-based noise helper: log-return from seeded GBM price stream as centered noise. + private static double GbmNoise(GBM gbm) => Math.Log(gbm.Next().Close / 100.0); + #region Statistical Property Validation [Fact] @@ -18,12 +21,12 @@ public class CointegrationValidationTests // Two series with near-perfect linear relationship should show strong cointegration // Adding small noise to avoid zero-variance residuals var indicator = new Cointegration(20); - var random = new Random(42); + var random = new GBM(startPrice: 100.0, sigma: 1.0, seed: 42); for (int i = 0; i < 100; i++) { - double a = 100.0 + i * 0.5 + (random.NextDouble() - 0.5) * 0.1; - double b = 2.0 * a + 10.0 + (random.NextDouble() - 0.5) * 0.1; + double a = 100.0 + i * 0.5 + GbmNoise(random) * 0.1; + double b = 2.0 * a + 10.0 + GbmNoise(random) * 0.1; indicator.Update(a, b); } @@ -55,12 +58,12 @@ public class CointegrationValidationTests { // B = k * A + small noise (near-proportional relationship) var indicator = new Cointegration(20); - var random = new Random(42); + var random = new GBM(startPrice: 100.0, sigma: 1.0, seed: 43); for (int i = 0; i < 100; i++) { double a = 50.0 + i * 0.3 + Math.Sin(i * 0.2) * 5.0; - double noise = (random.NextDouble() - 0.5) * 0.5; + double noise = GbmNoise(random) * 0.5; double b = 1.5 * a + noise; indicator.Update(a, b); } @@ -73,12 +76,12 @@ public class CointegrationValidationTests { // B = α + β*A + small_noise var indicator = new Cointegration(20); - var random = new Random(42); + var random = new GBM(startPrice: 100.0, sigma: 1.0, seed: 44); for (int i = 0; i < 100; i++) { double a = 100.0 + i * 0.2; - double noise = (random.NextDouble() - 0.5) * 0.5; // Small noise + double noise = GbmNoise(random) * 0.5; // Small noise double b = 25.0 + 0.8 * a + noise; indicator.Update(a, b); } @@ -245,12 +248,12 @@ public class CointegrationValidationTests public void Cointegration_SmallPeriod_WorksCorrectly() { var indicator = new Cointegration(3); // Minimum practical period - var random = new Random(42); + var random = new GBM(startPrice: 100.0, sigma: 1.0, seed: 45); for (int i = 0; i < 20; i++) { - double a = 100.0 + i + (random.NextDouble() - 0.5) * 0.1; - double b = 50.0 + 0.5 * a + (random.NextDouble() - 0.5) * 0.1; + double a = 100.0 + i + GbmNoise(random) * 0.1; + double b = 50.0 + 0.5 * a + GbmNoise(random) * 0.1; indicator.Update(a, b); } @@ -263,12 +266,12 @@ public class CointegrationValidationTests public void Cointegration_LargePeriod_WorksCorrectly() { var indicator = new Cointegration(100); - var random = new Random(42); + var random = new GBM(startPrice: 100.0, sigma: 1.0, seed: 46); for (int i = 0; i < 150; i++) { - double a = 100.0 + i * 0.1 + (random.NextDouble() - 0.5) * 0.1; - double b = 30.0 + 0.8 * a + (random.NextDouble() - 0.5) * 0.1; + double a = 100.0 + i * 0.1 + GbmNoise(random) * 0.1; + double b = 30.0 + 0.8 * a + GbmNoise(random) * 0.1; indicator.Update(a, b); } diff --git a/lib/statistics/cointegration/Cointegration.md b/lib/statistics/cointegration/Cointegration.md index 540fde89..7abb9bf0 100644 --- a/lib/statistics/cointegration/Cointegration.md +++ b/lib/statistics/cointegration/Cointegration.md @@ -1,5 +1,22 @@ # Cointegration: Engle-Granger Two-Step Cointegration Test +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Statistic | +| **Inputs** | Source (close) | +| **Parameters** | `period` (default 20) | +| **Outputs** | Single series (Cointegration) | +| **Output range** | Varies (see docs) | +| **Warmup** | `period + 1` bars | + +### TL;DR + +- The Cointegration indicator measures the long-run equilibrium relationship between two price series using the Engle-Granger two-step method with an... +- Parameterized by `period` (default 20). +- Output range: Varies (see docs). +- Requires `period + 1` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "Correlation tells you they move together. Cointegration tells you they're bound together. Two stocks can be uncorrelated yet cointegrated, or perfectly correlated yet destined to drift apart forever. The difference between 'similar direction' and 'shared destiny' is the difference between a tourist attraction and a gravitational orbit." The Cointegration indicator measures the long-run equilibrium relationship between two price series using the Engle-Granger two-step method with an Augmented Dickey-Fuller (ADF) test. Unlike correlation, which measures short-term co-movement, cointegration tests whether two non-stationary series share a common stochastic trend—meaning they may diverge temporarily but are statistically bound to revert to their equilibrium relationship. @@ -270,4 +287,4 @@ coint.Update(101.0, 51.0, isNew: false); // Recalculates without advancing state - Engle, R.F. and Granger, C.W.J. (1987). "Co-integration and Error Correction: Representation, Estimation, and Testing." *Econometrica*, 55(2), 251-276. - Dickey, D.A. and Fuller, W.A. (1979). "Distribution of the Estimators for Autoregressive Time Series with a Unit Root." *Journal of the American Statistical Association*, 74(366), 427-431. - TradingView. "Cointegration Indicator (PineScript)." *TradingView Community Scripts*. -- Vidyamurthy, G. (2004). "Pairs Trading: Quantitative Methods and Analysis." *Wiley Finance*. \ No newline at end of file +- Vidyamurthy, G. (2004). "Pairs Trading: Quantitative Methods and Analysis." *Wiley Finance*. diff --git a/lib/statistics/correlation/Correlation.Validation.Tests.cs b/lib/statistics/correlation/Correlation.Validation.Tests.cs index bacd5294..c70bc149 100644 --- a/lib/statistics/correlation/Correlation.Validation.Tests.cs +++ b/lib/statistics/correlation/Correlation.Validation.Tests.cs @@ -594,12 +594,12 @@ public sealed class CorrelationValidationTests : IDisposable { // Create two series with negative correlation var indicator = new Correlation(20); - var random = new Random(42); + var random = new GBM(startPrice: 100.0, sigma: 1.0, seed: 42); for (int i = 0; i < 100; i++) { - double x = 100.0 + i + (random.NextDouble() - 0.5) * 2; - double y = 200.0 - 0.8 * i + (random.NextDouble() - 0.5) * 2; // Negative relationship + double x = 100.0 + i + Math.Log(random.Next().Close / 100.0) * 2; + double y = 200.0 - 0.8 * i + Math.Log(random.Next().Close / 100.0) * 2; // Negative relationship indicator.Update(x, y); } @@ -611,12 +611,12 @@ public sealed class CorrelationValidationTests : IDisposable { // Create two series with weak correlation (lots of noise) var indicator = new Correlation(20); - var random = new Random(42); + var random = new GBM(startPrice: 100.0, sigma: 1.0, seed: 43); for (int i = 0; i < 100; i++) { - double x = 100.0 + i + (random.NextDouble() - 0.5) * 50; - double y = 100.0 + 0.1 * i + (random.NextDouble() - 0.5) * 50; // Weak relationship + double x = 100.0 + i + Math.Log(random.Next().Close / 100.0) * 50; + double y = 100.0 + 0.1 * i + Math.Log(random.Next().Close / 100.0) * 50; // Weak relationship indicator.Update(x, y); } diff --git a/lib/statistics/correlation/Correlation.md b/lib/statistics/correlation/Correlation.md index eba18846..57678065 100644 --- a/lib/statistics/correlation/Correlation.md +++ b/lib/statistics/correlation/Correlation.md @@ -1,5 +1,22 @@ # CORR: Pearson Correlation Coefficient +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Statistic | +| **Inputs** | Source (close) | +| **Parameters** | `period` (default 20) | +| **Outputs** | Single series (Correlation) | +| **Output range** | Varies (see docs) | +| **Warmup** | `period` bars | + +### TL;DR + +- The Pearson Correlation Coefficient measures the linear relationship between two variables, returning a value from -1 (perfect negative correlation... +- Parameterized by `period` (default 20). +- Output range: Varies (see docs). +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "Correlation is not causation, but it sure is a hint. The market doesn't care why two instruments move together—only that they do, and whether that relationship will persist long enough for you to profit from it." The Pearson Correlation Coefficient measures the linear relationship between two variables, returning a value from -1 (perfect negative correlation) to +1 (perfect positive correlation). Zero indicates no linear relationship. This implementation uses running sums for O(1) streaming updates, making it suitable for real-time analysis of price relationships. @@ -265,4 +282,4 @@ corr.Update(101.0, 51.0, isNew: false); // Recalculates without advancing state - Pearson, K. (1895). "Notes on regression and inheritance in the case of two parents." *Proceedings of the Royal Society of London*, 58, 240-242. - TradingView. "ta.correlation() function." *Pine Script Language Reference Manual*. - Vidyamurthy, G. (2004). "Pairs Trading: Quantitative Methods and Analysis." *Wiley Finance*. Chapter on correlation analysis. -- Embrechts, P., McNeil, A., & Straumann, D. (2002). "Correlation and dependence in risk management: properties and pitfalls." *Risk Management: Value at Risk and Beyond*, Cambridge University Press. \ No newline at end of file +- Embrechts, P., McNeil, A., & Straumann, D. (2002). "Correlation and dependence in risk management: properties and pitfalls." *Risk Management: Value at Risk and Beyond*, Cambridge University Press. diff --git a/lib/statistics/covariance/Covariance.md b/lib/statistics/covariance/Covariance.md index e04461a4..13ec3ef6 100644 --- a/lib/statistics/covariance/Covariance.md +++ b/lib/statistics/covariance/Covariance.md @@ -1,5 +1,22 @@ # Covariance: Covariance +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Statistic | +| **Inputs** | Source (close) | +| **Parameters** | `period`, `isPopulation` (default false) | +| **Outputs** | Single series (Cov) | +| **Output range** | Varies (see docs) | +| **Warmup** | `period` bars | + +### TL;DR + +- Covariance measures the joint variability of two random variables. +- Parameterized by `period`, `ispopulation` (default false). +- Output range: Varies (see docs). +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "Correlation is just covariance normalized by standard deviation. But sometimes you want the raw, unadulterated relationship." Covariance measures the joint variability of two random variables. It indicates the direction of the linear relationship between variables. diff --git a/lib/statistics/entropy/Entropy.md b/lib/statistics/entropy/Entropy.md index 4ddccdbc..ed494592 100644 --- a/lib/statistics/entropy/Entropy.md +++ b/lib/statistics/entropy/Entropy.md @@ -1,5 +1,22 @@ # ENTROPY: Shannon Entropy +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Statistic | +| **Inputs** | Source (close) | +| **Parameters** | `period` | +| **Outputs** | Single series (Entropy) | +| **Output range** | Varies (see docs) | +| **Warmup** | `period` bars | + +### TL;DR + +- Shannon Entropy measures the unpredictability or randomness of a time series over a sliding window. +- Parameterized by `period`. +- Output range: Varies (see docs). +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "Information is the resolution of uncertainty." — Claude Shannon Shannon Entropy measures the unpredictability or randomness of a time series over a sliding window. A low entropy value indicates the series is highly predictable (clustered values), while a high entropy value indicates the data is spread uniformly across its range — maximum randomness. diff --git a/lib/statistics/geomean/Geomean.md b/lib/statistics/geomean/Geomean.md index 839a0f47..6b6e5852 100644 --- a/lib/statistics/geomean/Geomean.md +++ b/lib/statistics/geomean/Geomean.md @@ -1,5 +1,22 @@ # GEOMEAN: Geometric Mean +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Statistic | +| **Inputs** | Source (close) | +| **Parameters** | `period` | +| **Outputs** | Single series (Geomean) | +| **Output range** | Varies (see docs) | +| **Warmup** | `period` bars | + +### TL;DR + +- The Geometric Mean computes the nth root of the product of n positive values over a sliding window. +- Parameterized by `period`. +- Output range: Varies (see docs). +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "The geometric mean is never greater than the arithmetic mean." - Mathematical inequality since antiquity The Geometric Mean computes the nth root of the product of n positive values over a sliding window. Unlike the arithmetic mean, it captures multiplicative relationships and is the correct average for growth rates, ratios, and log-normally distributed data. For financial time series, this means it properly accounts for compounding. diff --git a/lib/statistics/granger/Granger.Validation.Tests.cs b/lib/statistics/granger/Granger.Validation.Tests.cs index 3954aa5e..3f670204 100644 --- a/lib/statistics/granger/Granger.Validation.Tests.cs +++ b/lib/statistics/granger/Granger.Validation.Tests.cs @@ -7,13 +7,17 @@ namespace QuanTAlib.Tests; /// public class GrangerValidationTests { + // GBM-based noise helper: extracts log-return from a seeded GBM price stream as centered noise. + // Using sigma=1.0 gives log-returns ~N(0, vol²*dt); scale to required magnitude. + private static double GbmNoise(GBM gbm) => Math.Log(gbm.Next().Close / 100.0); + [Fact] public void Granger_CausalRelationship_ProducesHighFStatistic() { // X causes Y: Y_t = 0.5*Y_{t-1} + 0.3*X_{t-1} + noise // Adding X_lag should significantly improve prediction var indicator = new Granger(20); - var rng = new Random(42); + var rng = new GBM(startPrice: 100.0, sigma: 1.0, seed: 42); double y = 100.0; double x = 100.0; @@ -22,8 +26,8 @@ public class GrangerValidationTests for (int i = 0; i < 200; i++) { - x = 100.0 + Math.Sin(i * 0.1) * 10.0 + (rng.NextDouble() - 0.5) * 2.0; - y = 50.0 + 0.5 * prevY + 0.3 * prevX + (rng.NextDouble() - 0.5) * 0.5; + x = 100.0 + Math.Sin(i * 0.1) * 10.0 + GbmNoise(rng) * 2.0; + y = 50.0 + 0.5 * prevY + 0.3 * prevX + GbmNoise(rng) * 0.5; indicator.Update(y, x, isNew: true); @@ -68,7 +72,7 @@ public class GrangerValidationTests // Compare strong causal vs weak causal relationship var strongIndicator = new Granger(20); var weakIndicator = new Granger(20); - var rng = new Random(42); + var rng = new GBM(startPrice: 100.0, sigma: 1.0, seed: 42); double yStrong = 100.0, yWeak = 100.0; double x = 100.0; @@ -76,12 +80,12 @@ public class GrangerValidationTests for (int i = 0; i < 200; i++) { - x = 100.0 + Math.Sin(i * 0.1) * 10.0 + (rng.NextDouble() - 0.5) * 2.0; + x = 100.0 + Math.Sin(i * 0.1) * 10.0 + GbmNoise(rng) * 2.0; // Strong: Y depends heavily on X_lag - yStrong = 50.0 + 0.3 * prevYStrong + 0.6 * prevX + (rng.NextDouble() - 0.5) * 0.5; + yStrong = 50.0 + 0.3 * prevYStrong + 0.6 * prevX + GbmNoise(rng) * 0.5; // Weak: Y barely depends on X_lag - yWeak = 50.0 + 0.8 * prevYWeak + 0.05 * prevX + (rng.NextDouble() - 0.5) * 5.0; + yWeak = 50.0 + 0.8 * prevYWeak + 0.05 * prevX + GbmNoise(rng) * 5.0; strongIndicator.Update(yStrong, x, isNew: true); weakIndicator.Update(yWeak, x, isNew: true); @@ -199,7 +203,7 @@ public class GrangerValidationTests // when causality is asymmetric var indicatorYX = new Granger(15); var indicatorXY = new Granger(15); - var rng = new Random(42); + var rng = new GBM(startPrice: 100.0, sigma: 1.0, seed: 42); double y = 100.0, x = 100.0; double prevY = y, prevX = x; @@ -207,9 +211,9 @@ public class GrangerValidationTests for (int i = 0; i < 200; i++) { // X is exogenous (just random walk with drift) - x = prevX + (rng.NextDouble() - 0.5) * 2.0; + x = prevX + GbmNoise(rng) * 2.0; // Y depends on X_lag (X Granger-causes Y, but Y does NOT Granger-cause X) - y = 50.0 + 0.3 * prevY + 0.4 * prevX + (rng.NextDouble() - 0.5) * 0.5; + y = 50.0 + 0.3 * prevY + 0.4 * prevX + GbmNoise(rng) * 0.5; indicatorYX.Update(y, x, isNew: true); // Testing: does X cause Y? indicatorXY.Update(x, y, isNew: true); // Testing: does Y cause X? diff --git a/lib/statistics/granger/Granger.md b/lib/statistics/granger/Granger.md index abea6aeb..c02a2757 100644 --- a/lib/statistics/granger/Granger.md +++ b/lib/statistics/granger/Granger.md @@ -1,5 +1,22 @@ # GRANGER: Granger Causality F-Statistic +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Statistic | +| **Inputs** | Source (close) | +| **Parameters** | `period` (default 20) | +| **Outputs** | Single series (Granger) | +| **Output range** | Varies (see docs) | +| **Warmup** | `period + 1` bars | + +### TL;DR + +- The Granger Causality test asks a precise, falsifiable question: does knowing the history of series X improve your ability to predict series Y, bey... +- Parameterized by `period` (default 20). +- Output range: Varies (see docs). +- Requires `period + 1` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "Correlation is not causation, but Granger causality is not causation either. It is prediction." -- Clive Granger ## Introduction diff --git a/lib/statistics/harmean/Harmean.md b/lib/statistics/harmean/Harmean.md index b287e4bf..8db2efa8 100644 --- a/lib/statistics/harmean/Harmean.md +++ b/lib/statistics/harmean/Harmean.md @@ -1,5 +1,22 @@ # HARMEAN: Harmonic Mean +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Statistic | +| **Inputs** | Source (close) | +| **Parameters** | `period` | +| **Outputs** | Single series (Harmean) | +| **Output range** | Varies (see docs) | +| **Warmup** | `period` bars | + +### TL;DR + +- The Harmonic Mean computes the reciprocal of the arithmetic mean of reciprocals over a sliding window. +- Parameterized by `period`. +- Output range: Varies (see docs). +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "The harmonic mean is never greater than the geometric mean, which is never greater than the arithmetic mean." - The Mean Inequality, a mathematical fact older than calculus The Harmonic Mean computes the reciprocal of the arithmetic mean of reciprocals over a sliding window. It is the correct average for quantities defined in terms of rates or ratios (speed, P/E ratios, yield). For financial time series, the harmonic mean gives the largest discount to outliers, making it the most conservative of the three Pythagorean means. diff --git a/lib/statistics/hurst/Hurst.Validation.Tests.cs b/lib/statistics/hurst/Hurst.Validation.Tests.cs index 17c90e44..aad9adb9 100644 --- a/lib/statistics/hurst/Hurst.Validation.Tests.cs +++ b/lib/statistics/hurst/Hurst.Validation.Tests.cs @@ -1,6 +1,4 @@ -using OoplesFinance.StockIndicators; -using OoplesFinance.StockIndicators.Models; // HURST Validation Tests - Hurst Exponent via Rescaled Range (R/S) Analysis // Validated against self-consistency and known mathematical properties // No external library provides a direct R/S-based Hurst exponent equivalent @@ -183,23 +181,4 @@ public sealed class HurstValidationTests Assert.Equal(h1.Last.Value, h2.Last.Value, 1e-15); } - [Fact(Skip = "CalculateEhlersHurstCoefficient produces 0 finite values on 500-bar dataset — requires an extremely long warmup (1000+ bars). Not comparable with synthetic GBM input.")] - public void Hurst_MatchesOoples_Structural() - { - var gbm = new GBM(startPrice: 100.0, mu: 0.02, sigma: 0.15, seed: 42); - var bars = gbm.Fetch(500, DateTime.UtcNow.Ticks, TimeSpan.FromMinutes(1)); - var ooplesData = bars.Select(b => new TickerData - { - Date = new DateTime(b.Time, DateTimeKind.Utc), - Open = b.Open, - High = b.High, - Low = b.Low, - Close = b.Close, - Volume = b.Volume - }).ToList(); - var result = new StockData(ooplesData).CalculateEhlersHurstCoefficient(); - var values = result.OutputValues.Values.First(); - int finiteCount = values.Count(v => double.IsFinite(v)); - Assert.True(finiteCount > 100, $"Expected >100 finite values, got {finiteCount}"); - } } \ No newline at end of file diff --git a/lib/statistics/hurst/Hurst.md b/lib/statistics/hurst/Hurst.md index 19a042d7..3c470dad 100644 --- a/lib/statistics/hurst/Hurst.md +++ b/lib/statistics/hurst/Hurst.md @@ -1,5 +1,22 @@ # HURST: Hurst Exponent +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Statistic | +| **Inputs** | Source (close) | +| **Parameters** | `period` | +| **Outputs** | Single series (Hurst) | +| **Output range** | Varies (see docs) | +| **Warmup** | `period + 1` bars | + +### TL;DR + +- The Hurst Exponent ($H$) quantifies long-range dependence in a time series through Rescaled Range (R/S) analysis. +- Parameterized by `period`. +- Output range: Varies (see docs). +- Requires `period + 1` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "The past is not dead. In fact, it's not even past." — William Faulkner, and also every mean-reverting time series that refuses to forget. ## Introduction diff --git a/lib/statistics/iqr/Iqr.md b/lib/statistics/iqr/Iqr.md index 65f833d1..03d9fbc2 100644 --- a/lib/statistics/iqr/Iqr.md +++ b/lib/statistics/iqr/Iqr.md @@ -1,5 +1,22 @@ # IQR: Interquartile Range +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Statistic | +| **Inputs** | Source (close) | +| **Parameters** | `period` | +| **Outputs** | Single series (Iqr) | +| **Output range** | Varies (see docs) | +| **Warmup** | `period` bars | + +### TL;DR + +- The Interquartile Range measures the spread of the middle 50% of a sorted dataset within a rolling window. +- Parameterized by `period`. +- Output range: Varies (see docs). +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "The median is the most important statistic, and the interquartile range is the second most important." — John Tukey ## Introduction diff --git a/lib/statistics/jb/Jb.md b/lib/statistics/jb/Jb.md index 2e20fb3f..7b62f373 100644 --- a/lib/statistics/jb/Jb.md +++ b/lib/statistics/jb/Jb.md @@ -1,5 +1,22 @@ # JB: Jarque-Bera Test +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Statistic | +| **Inputs** | Source (close) | +| **Parameters** | `period` | +| **Outputs** | Single series (Jb) | +| **Output range** | Varies (see docs) | +| **Warmup** | `period` bars | + +### TL;DR + +- The Jarque-Bera test quantifies departure from normality by combining skewness and excess kurtosis into a single chi-squared statistic. +- Parameterized by `period`. +- Output range: Varies (see docs). +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "The assumption of normality is the most dangerous assumption in all of statistics." — George Box (paraphrased) The Jarque-Bera test quantifies departure from normality by combining skewness and excess kurtosis into a single chi-squared statistic. A rolling JB value near zero means the window looks Gaussian. Values exceeding 5.991 (5% significance) reject normality. Financial returns almost always fail this test, which is precisely why the test matters. diff --git a/lib/statistics/kurtosis/Kurtosis.md b/lib/statistics/kurtosis/Kurtosis.md index 501a059f..4fedc5fd 100644 --- a/lib/statistics/kurtosis/Kurtosis.md +++ b/lib/statistics/kurtosis/Kurtosis.md @@ -1,5 +1,22 @@ # KURTOSIS: Excess Kurtosis +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Statistic | +| **Inputs** | Source (close) | +| **Parameters** | `period`, `isPopulation` (default false) | +| **Outputs** | Single series (Kurtosis) | +| **Output range** | Varies (see docs) | +| **Warmup** | `period` bars | + +### TL;DR + +- Kurtosis measures the **tailedness** of a probability distribution. +- Parameterized by `period`, `ispopulation` (default false). +- Output range: Varies (see docs). +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "Normal is getting dressed in clothes that you buy for work and driving through traffic in a car that you are still paying for, in order to get to the job you need to pay for the clothes and the car." The fourth moment measures how far your returns deviate from that comforting fiction. ## Introduction diff --git a/lib/statistics/linreg/LinReg.md b/lib/statistics/linreg/LinReg.md index bdb0d20b..ee2e0f71 100644 --- a/lib/statistics/linreg/LinReg.md +++ b/lib/statistics/linreg/LinReg.md @@ -1,5 +1,22 @@ # LinReg: Linear Regression Curve +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Statistic | +| **Inputs** | Source (close) | +| **Parameters** | `period`, `offset` (default 0) | +| **Outputs** | Single series (LinReg) | +| **Output range** | Varies (see docs) | +| **Warmup** | `period` bars | + +### TL;DR + +- The Linear Regression Curve plots the end point of the linear regression line for each bar. +- Parameterized by `period`, `offset` (default 0). +- Output range: Varies (see docs). +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "The trend is your friend, until it bends." The Linear Regression Curve plots the end point of the linear regression line for each bar. It fits a straight line $y = mx + b$ to the data points using the least squares method, providing a smoothed representation of the price trend that is more responsive than a Simple Moving Average (SMA). diff --git a/lib/statistics/meandev/MeanDev.md b/lib/statistics/meandev/MeanDev.md index 02e1f1f5..d2bd5f1b 100644 --- a/lib/statistics/meandev/MeanDev.md +++ b/lib/statistics/meandev/MeanDev.md @@ -1,6 +1,22 @@ -````markdown # MeanDev: Mean Deviation (Average Absolute Deviation) +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Statistic | +| **Inputs** | Source (close) | +| **Parameters** | `period` | +| **Outputs** | Single series (MeanDev) | +| **Output range** | Varies (see docs) | +| **Warmup** | `period` bars | + +### TL;DR + +- ````markdown +- Parameterized by `period`. +- Output range: Varies (see docs). +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "Not all dispersion is created equal — some prefer robustness over elegance." Mean Deviation (also known as Mean Absolute Deviation or Average Absolute Deviation) measures the average of the absolute deviations from the mean. Unlike Standard Deviation, it does not square the deviations, making it more robust to outliers and more intuitive to interpret. diff --git a/lib/statistics/median/Median.md b/lib/statistics/median/Median.md index a4f0d123..cd0f7c07 100644 --- a/lib/statistics/median/Median.md +++ b/lib/statistics/median/Median.md @@ -1,5 +1,22 @@ # MEDIAN: Rolling Median +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Statistic | +| **Inputs** | Source (close) | +| **Parameters** | `period` | +| **Outputs** | Single series (Median) | +| **Output range** | Varies (see docs) | +| **Warmup** | `period` bars | + +### TL;DR + +- The Rolling Median is a robust statistic that represents the middle value of a dataset within a moving window. +- Parameterized by `period`. +- Output range: Varies (see docs). +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "The average is easily influenced by outliers; the median stands its ground." The Rolling Median is a robust statistic that represents the middle value of a dataset within a moving window. Unlike the Simple Moving Average (SMA), which can be skewed by extreme values, the Median provides a more stable measure of central tendency, making it particularly useful for filtering noise in volatile markets. diff --git a/lib/statistics/mode/Mode.md b/lib/statistics/mode/Mode.md index 584eab9b..ba06248a 100644 --- a/lib/statistics/mode/Mode.md +++ b/lib/statistics/mode/Mode.md @@ -1,5 +1,22 @@ # MODE: Statistical Mode (Most Frequent Value) +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Statistic | +| **Inputs** | Source (close) | +| **Parameters** | `period` | +| **Outputs** | Single series (Mode) | +| **Output range** | Varies (see docs) | +| **Warmup** | `period` bars | + +### TL;DR + +- The **Mode** is a rolling statistical indicator that identifies the most frequently occurring value within a sliding window of recent observations. +- Parameterized by `period`. +- Output range: Varies (see docs). +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "The mode is the value that appears most frequently in a data set — the only measure of central tendency that tells you what's actually popular, not what's average." ## Introduction diff --git a/lib/statistics/pacf/Pacf.Validation.Tests.cs b/lib/statistics/pacf/Pacf.Validation.Tests.cs index 80811844..96005cc6 100644 --- a/lib/statistics/pacf/Pacf.Validation.Tests.cs +++ b/lib/statistics/pacf/Pacf.Validation.Tests.cs @@ -105,13 +105,13 @@ public class PacfValidationTests // For AR(1) process: x_t = φ*x_{t-1} + ε_t // PACF should be significant at lag 1 and cut off (near zero) after double phi = 0.7; // AR(1) coefficient - var random = new Random(42); + var random = new GBM(startPrice: 100.0, sigma: 1.0, seed: 42); var arProcess = new List { 100.0 }; // Generate AR(1) process for (int i = 1; i < 500; i++) { - double noise = random.NextDouble() * 2 - 1; // Small noise + double noise = Math.Log(random.Next().Close / 100.0); // ~N(0, vol²*dt) noise double newValue = phi * arProcess[^1] + noise; arProcess.Add(newValue); } diff --git a/lib/statistics/pacf/Pacf.md b/lib/statistics/pacf/Pacf.md index 8dd862c3..8b7f9ab0 100644 --- a/lib/statistics/pacf/Pacf.md +++ b/lib/statistics/pacf/Pacf.md @@ -1,5 +1,22 @@ # PACF: Partial Autocorrelation Function +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Statistic | +| **Inputs** | Source (close) | +| **Parameters** | `period`, `lag` (default 1) | +| **Outputs** | Single series (Pacf) | +| **Output range** | Varies (see docs) | +| **Warmup** | `period` bars | + +### TL;DR + +- The Partial Autocorrelation Function (PACF) measures the correlation between a time series and its lagged values, after removing the effects of all... +- Parameterized by `period`, `lag` (default 1). +- Output range: Varies (see docs). +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "Strip away the intermediaries, and you'll see the true direct relationship." The Partial Autocorrelation Function (PACF) measures the correlation between a time series and its lagged values, after removing the effects of all intermediate lags. While ACF shows total correlation at each lag, PACF isolates the direct correlation, making it essential for AR model identification. @@ -194,4 +211,4 @@ PACF is used in linear prediction and filter design, where the partial correlati - Box, G.E.P., Jenkins, G.M. (1970). *Time Series Analysis: Forecasting and Control*. Holden-Day. - Durbin, J. (1960). "The fitting of time series models." *Review of the International Statistical Institute*, 28, 233-243. - Levinson, N. (1946). "The Wiener RMS error criterion in filter design and prediction." *Journal of Mathematics and Physics*, 25, 261-278. -- Hamilton, J.D. (1994). *Time Series Analysis*. Princeton University Press. \ No newline at end of file +- Hamilton, J.D. (1994). *Time Series Analysis*. Princeton University Press. diff --git a/lib/statistics/percentile/Percentile.md b/lib/statistics/percentile/Percentile.md index 9a3e5e52..c7ae43ff 100644 --- a/lib/statistics/percentile/Percentile.md +++ b/lib/statistics/percentile/Percentile.md @@ -1,6 +1,24 @@ # PERCENTILE: Rolling Percentile +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Statistic | +| **Inputs** | Source (close) | +| **Parameters** | `period`, `percent` (default 50.0) | +| **Outputs** | Single series (Percentile) | +| **Output range** | Varies (see docs) | +| **Warmup** | `period` bars | + +### TL;DR + +- The Rolling Percentile computes the value below which a given percentage of observations fall within a sliding window. +- Parameterized by `period`, `percent` (default 50.0). +- Output range: Varies (see docs). +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "There are three kinds of lies: lies, damned lies, and statistics." — Mark Twain. + > But percentiles, at least, tell you exactly where you stand. ## Introduction diff --git a/lib/statistics/polyfit/Polyfit.md b/lib/statistics/polyfit/Polyfit.md index 346be6f7..5161dffb 100644 --- a/lib/statistics/polyfit/Polyfit.md +++ b/lib/statistics/polyfit/Polyfit.md @@ -1,5 +1,22 @@ # POLYFIT: Polynomial Fitting +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Statistic | +| **Inputs** | Source (close) | +| **Parameters** | `period`, `degree` (default 2) | +| **Outputs** | Single series (Polyfit) | +| **Output range** | Varies (see docs) | +| **Warmup** | `period` bars | + +### TL;DR + +- Polynomial Fitting computes a rolling polynomial regression of configurable degree over a lookback window, returning the fitted value at the curren... +- Parameterized by `period`, `degree` (default 2). +- Output range: Varies (see docs). +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + Polynomial Fitting computes a rolling polynomial regression of configurable degree over a lookback window, returning the fitted value at the current bar. Degree 1 produces a linear regression endpoint (identical to LSQR), degree 2 produces a quadratic fit that captures curvature, and degree 3 produces a cubic fit that captures inflection points. The implementation solves the normal equations $\mathbf{X}^T\mathbf{X}\mathbf{a} = \mathbf{X}^T\mathbf{y}$ via Gauss-Jordan elimination with partial pivoting, evaluating the resulting polynomial at $x = 1$ (the current bar position). With $O(Nd + d^3)$ complexity per bar where $N$ is the period and $d$ is the degree, POLYFIT provides a general-purpose curve-fitting tool that subsumes linear regression and extends it to arbitrary polynomial order. ## Historical Context diff --git a/lib/statistics/quantile/Quantile.md b/lib/statistics/quantile/Quantile.md index a364b046..daaa1fa0 100644 --- a/lib/statistics/quantile/Quantile.md +++ b/lib/statistics/quantile/Quantile.md @@ -1,5 +1,22 @@ # QUANTILE: Rolling Quantile +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Statistic | +| **Inputs** | Source (close) | +| **Parameters** | `period`, `quantileLevel` (default 0.25) | +| **Outputs** | Single series (Quantile) | +| **Output range** | Varies (see docs) | +| **Warmup** | `period` bars | + +### TL;DR + +- The Rolling Quantile computes the value below which a given fraction of observations fall within a sliding window. +- Parameterized by `period`, `quantilelevel` (default 0.25). +- Output range: Varies (see docs). +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "The quantile function is the inverse of the distribution function." — Every probability textbook ever written, and yet somehow it still surprises people. ## Introduction diff --git a/lib/statistics/skew/Skew.md b/lib/statistics/skew/Skew.md index ea6093ee..047f9175 100644 --- a/lib/statistics/skew/Skew.md +++ b/lib/statistics/skew/Skew.md @@ -1,5 +1,22 @@ # SKEW: Skewness +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Statistic | +| **Inputs** | Source (close) | +| **Parameters** | `period`, `isPopulation` (default false) | +| **Outputs** | Single series (Skew) | +| **Output range** | Varies (see docs) | +| **Warmup** | `period` bars | + +### TL;DR + +- Skewness measures the asymmetry of the probability distribution of a real-valued random variable about its mean. +- Parameterized by `period`, `ispopulation` (default false). +- Output range: Varies (see docs). +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "In the land of the blind, the one-eyed man is king. In the land of the normal distribution, the skewed man is profitable." Skewness measures the asymmetry of the probability distribution of a real-valued random variable about its mean. It tells you where the "tail" of the distribution is. diff --git a/lib/statistics/spearman/Spearman.md b/lib/statistics/spearman/Spearman.md index cf509694..1c61eae5 100644 --- a/lib/statistics/spearman/Spearman.md +++ b/lib/statistics/spearman/Spearman.md @@ -1,5 +1,22 @@ # SPEARMAN: Spearman Rank Correlation Coefficient +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Statistic | +| **Inputs** | Source (close) | +| **Parameters** | `period` (default 20) | +| **Outputs** | Single series (Spearman) | +| **Output range** | Varies (see docs) | +| **Warmup** | `period` bars | + +### TL;DR + +- Spearman's ρ (rho) measures the strength and direction of monotonic association between two variables. +- Parameterized by `period` (default 20). +- Output range: Varies (see docs). +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "The person who asks whether rank correlation exists is not asking a wholly foolish question." — Maurice Kendall (1970) Spearman's ρ (rho) measures the strength and direction of monotonic association between two variables. Unlike Pearson's correlation, which measures linear relationship, Spearman captures any monotonic relationship. A portfolio of stocks whose returns move monotonically together has different risk than one whose components merely share a linear trend. Spearman detects both. diff --git a/lib/statistics/stddev/StdDev.md b/lib/statistics/stddev/StdDev.md index 2ad4ac75..e5b158ae 100644 --- a/lib/statistics/stddev/StdDev.md +++ b/lib/statistics/stddev/StdDev.md @@ -1,5 +1,22 @@ # STDDEV: Standard Deviation +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Statistic | +| **Inputs** | Source (close) | +| **Parameters** | `period`, `isPopulation` (default false) | +| **Outputs** | Single series (StdDev) | +| **Output range** | Varies (see docs) | +| **Warmup** | `period` bars | + +### TL;DR + +- Standard Deviation measures the amount of variation or dispersion of a set of values. +- Parameterized by `period`, `ispopulation` (default false). +- Output range: Varies (see docs). +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "Volatility is not risk, but it's the only thing we can measure." Standard Deviation measures the amount of variation or dispersion of a set of values. A low standard deviation indicates that the values tend to be close to the mean (also called the expected value) of the set, while a high standard deviation indicates that the values are spread out over a wider range. diff --git a/lib/statistics/stderr/Stderr.Validation.Tests.cs b/lib/statistics/stderr/Stderr.Validation.Tests.cs index cfc3b6bb..a43e6f3b 100644 --- a/lib/statistics/stderr/Stderr.Validation.Tests.cs +++ b/lib/statistics/stderr/Stderr.Validation.Tests.cs @@ -196,18 +196,9 @@ public class StderrValidationTests } } - // ── Tulip Structural Note ───────────────────────────────────────────────── - // - // Tulip `stderr` is NOT the standard error of linear regression. + // Note: Tulip `stderr` is NOT the standard error of linear regression. // Tulip formula: stddev(x, n) / sqrt(n) = standard error of the mean. // QuanTAlib Stderr: sqrt(SSR / (n-2)) = standard error of OLS regression. // These are different statistics — no cross-validation is possible. // QuanTAlib is validated against its own brute-force OLS reference above. - - [Fact(Skip = "Tulip stderr = StdDev/sqrt(n) (SE of mean); QuanTAlib Stderr = sqrt(SSR/(n-2)) (SE of OLS regression). Different statistics — intentional divergence.")] - public void Stderr_Structural_Note_TulipFormulaDiffers() - { - // Intentionally empty: test is always skipped via [Fact(Skip=...)]. - // The Skip message documents the formula incompatibility with Tulip. - } } diff --git a/lib/statistics/stderr/Stderr.md b/lib/statistics/stderr/Stderr.md index 8cedc87b..e52180f5 100644 --- a/lib/statistics/stderr/Stderr.md +++ b/lib/statistics/stderr/Stderr.md @@ -1,6 +1,22 @@ -````markdown # Stderr: Standard Error of Regression +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Statistic | +| **Inputs** | Source (close) | +| **Parameters** | `period` | +| **Outputs** | Single series (Stderr) | +| **Output range** | Varies (see docs) | +| **Warmup** | `period` bars | + +### TL;DR + +- ````markdown +- Parameterized by `period`. +- Output range: Varies (see docs). +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "How confident are you in your line of best fit?" Standard Error of Regression (also called the Standard Error of the Estimate) measures the average distance that the observed values fall from the regression line. It quantifies the typical size of the residuals, providing a direct measure of how well a linear regression model fits the data. diff --git a/lib/statistics/sum/Sum.md b/lib/statistics/sum/Sum.md index 35fab9de..0630dbfb 100644 --- a/lib/statistics/sum/Sum.md +++ b/lib/statistics/sum/Sum.md @@ -1,5 +1,22 @@ # Sum: Summation with Kahan-Babuška Algorithm +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Statistic | +| **Inputs** | Source (close) | +| **Parameters** | `period` | +| **Outputs** | Single series (Sum) | +| **Output range** | Varies (see docs) | +| **Warmup** | `period` bars | + +### TL;DR + +- The Sum indicator calculates a rolling window summation using the Kahan-Babuška algorithm (also known as "improved Kahan" or "second-order compensa... +- Parameterized by `period`. +- Output range: Varies (see docs). +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "The naive approach to summation assumes all digits matter equally. They don't. When you add 1e-10 to 1e10, that small value vanishes into the rounding noise. Kahan-Babuška tracks what got lost and adds it back later. It's bookkeeping for bits that would otherwise slip through the cracks." The Sum indicator calculates a rolling window summation using the Kahan-Babuška algorithm (also known as "improved Kahan" or "second-order compensated summation") for maximum numerical precision. This approach captures rounding errors that even classic Kahan summation misses, making it suitable for numerical libraries, statistics, and trading applications where precision matters. diff --git a/lib/statistics/theil/Theil.md b/lib/statistics/theil/Theil.md index 8b266d51..3c89a339 100644 --- a/lib/statistics/theil/Theil.md +++ b/lib/statistics/theil/Theil.md @@ -1,5 +1,22 @@ # THEIL: Theil's T Index +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Statistic | +| **Inputs** | Source (close) | +| **Parameters** | `period` | +| **Outputs** | Single series (Theil) | +| **Output range** | Varies (see docs) | +| **Warmup** | `period` bars | + +### TL;DR + +- The Theil T Index is an information-theoretic measure of inequality (or concentration) within a distribution of positive values. +- Parameterized by `period`. +- Output range: Varies (see docs). +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "The only useful measure of inequality is one that tells you how much redistribution would make everyone equally well off." — Henri Theil ## Introduction diff --git a/lib/statistics/trim/Trim.md b/lib/statistics/trim/Trim.md index a817dc3d..3a176fe8 100644 --- a/lib/statistics/trim/Trim.md +++ b/lib/statistics/trim/Trim.md @@ -1,5 +1,22 @@ # TRIM: Trimmed Mean Moving Average +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Statistic | +| **Inputs** | Source (close) | +| **Parameters** | `period`, `trimPct` (default 10.0) | +| **Outputs** | Single series (Trim) | +| **Output range** | Varies (see docs) | +| **Warmup** | `period` bars | + +### TL;DR + +- The Trimmed Mean Moving Average computes a rolling average after discarding a configurable percentage of the most extreme values from each tail of ... +- Parameterized by `period`, `trimpct` (default 10.0). +- Output range: Varies (see docs). +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + The Trimmed Mean Moving Average computes a rolling average after discarding a configurable percentage of the most extreme values from each tail of the sorted lookback window. By removing the lowest and highest `trimPct%` of observations, TRIM eliminates the influence of outliers while retaining more information than a pure median. At `trimPct = 0` it degenerates to the SMA; at `trimPct = 50` it becomes the median. The default 10% trim provides a robust central tendency estimator that resists spike contamination with minimal loss of responsiveness, requiring $O(N \log N)$ for the sort plus $O(N)$ for the summation per bar. ## Historical Context diff --git a/lib/statistics/variance/Variance.md b/lib/statistics/variance/Variance.md index 3ee1a1e7..19aac746 100644 --- a/lib/statistics/variance/Variance.md +++ b/lib/statistics/variance/Variance.md @@ -1,5 +1,22 @@ # Variance (VAR) +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Statistic | +| **Inputs** | Source (close) | +| **Parameters** | `period`, `isPopulation` (default false) | +| **Outputs** | Single series (Variance) | +| **Output range** | Varies (see docs) | +| **Warmup** | `period` bars | + +### TL;DR + +- Variance measures how far a set of numbers is spread out from their average value. +- Parameterized by `period`, `ispopulation` (default false). +- Output range: Varies (see docs). +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "Volatility is the price of admission for high returns." Variance measures how far a set of numbers is spread out from their average value. In finance, it is a key measure of volatility and risk. diff --git a/lib/statistics/wavg/Wavg.md b/lib/statistics/wavg/Wavg.md index 550647d6..0080781b 100644 --- a/lib/statistics/wavg/Wavg.md +++ b/lib/statistics/wavg/Wavg.md @@ -1,5 +1,22 @@ # WAVG: Weighted Average +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Statistic | +| **Inputs** | Source (close) | +| **Parameters** | `period` | +| **Outputs** | Single series (Wavg) | +| **Output range** | $0$ to $1$ | +| **Warmup** | `period` bars | + +### TL;DR + +- The Weighted Average computes a rolling linearly-weighted mean where the most recent observation receives weight $N$ and the oldest receives weight... +- Parameterized by `period`. +- Output range: $0$ to $1$. +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + The Weighted Average computes a rolling linearly-weighted mean where the most recent observation receives weight $N$ and the oldest receives weight 1, making it mathematically identical to the Weighted Moving Average (WMA) but categorized as a statistical measure. The implementation uses a circular buffer with an $O(1)$ incremental update scheme: rather than recomputing the full weighted sum each bar, it maintains running sums and adjusts them through add/subtract operations as values enter and exit the window. This makes WAVG one of the most efficient weighted estimators available, with constant per-bar cost regardless of the lookback period. ## Historical Context diff --git a/lib/statistics/wins/Wins.md b/lib/statistics/wins/Wins.md index 6391e0d8..967e8416 100644 --- a/lib/statistics/wins/Wins.md +++ b/lib/statistics/wins/Wins.md @@ -1,5 +1,22 @@ # WINS: Winsorized Mean Moving Average +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Statistic | +| **Inputs** | Source (close) | +| **Parameters** | `period`, `winPct` (default 10.0) | +| **Outputs** | Single series (Wins) | +| **Output range** | Varies (see docs) | +| **Warmup** | `period` bars | + +### TL;DR + +- The Winsorized Mean Moving Average computes a rolling average after replacing (not discarding) the most extreme values in each tail with the bounda... +- Parameterized by `period`, `winpct` (default 10.0). +- Output range: Varies (see docs). +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + The Winsorized Mean Moving Average computes a rolling average after replacing (not discarding) the most extreme values in each tail with the boundary values at the trim point. Unlike the trimmed mean (TRIM) which removes outliers entirely, Winsorization preserves the full sample size by clamping extreme values to the nearest non-extreme observation. At `winPct = 0` it degenerates to the SMA; at `winPct = 50` all values equal the median pair. The default 10% Winsorization provides a robust central tendency estimator that dampens outlier impact while maintaining the statistical efficiency advantages of the full sample size. ## Historical Context diff --git a/lib/statistics/zscore/Zscore.md b/lib/statistics/zscore/Zscore.md index 55df3ba7..6699aa97 100644 --- a/lib/statistics/zscore/Zscore.md +++ b/lib/statistics/zscore/Zscore.md @@ -1,5 +1,22 @@ # ZSCORE: Z-Score (Population Standard Score, also known as STANDARDIZE) +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Statistic | +| **Inputs** | Source (close) | +| **Parameters** | `period` (default 14) | +| **Outputs** | Single series (Zscore) | +| **Output range** | Unbounded | +| **Warmup** | `period` bars | + +### TL;DR + +- The Z-Score measures how many population standard deviations a value lies from the rolling mean over a lookback window. +- Parameterized by `period` (default 14). +- Output range: Unbounded. +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "How far from normal is this?" — Every risk manager, every day. ## Introduction diff --git a/lib/statistics/ztest/Ztest.md b/lib/statistics/ztest/Ztest.md index 1a15b563..7ccfed18 100644 --- a/lib/statistics/ztest/Ztest.md +++ b/lib/statistics/ztest/Ztest.md @@ -1,5 +1,22 @@ # ZTEST: One-Sample t-Test Statistic +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Statistic | +| **Inputs** | Source (close) | +| **Parameters** | `period` (default 30), `mu0` (default 0.0) | +| **Outputs** | Single series (Ztest) | +| **Output range** | Unbounded | +| **Warmup** | `period` bars | + +### TL;DR + +- ZTEST computes the **one-sample t-statistic**, measuring how many standard errors the rolling sample mean deviates from a hypothesized population m... +- Parameterized by `period` (default 30), `mu0` (default 0.0). +- Output range: Unbounded. +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "The purpose of hypothesis testing is not to prove what we believe, but to measure what we observe." — Adapted from R.A. Fisher ## Introduction diff --git a/lib/trends_FIR/alma/Alma.md b/lib/trends_FIR/alma/Alma.md index 7c497375..cfa18fcf 100644 --- a/lib/trends_FIR/alma/Alma.md +++ b/lib/trends_FIR/alma/Alma.md @@ -1,5 +1,22 @@ # ALMA: Arnaud Legoux Moving Average +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Trend (FIR MA) | +| **Inputs** | Source (close) | +| **Parameters** | `period`, `offset` (default 0.85), `sigma` (default 6.0) | +| **Outputs** | Single series (Alma) | +| **Output range** | Tracks input | +| **Warmup** | `period` bars | + +### TL;DR + +- ALMA is a Finite Impulse Response (FIR) filter that applies a Gaussian window to price data. +- Parameterized by `period`, `offset` (default 0.85), `sigma` (default 6.0). +- Output range: Tracks input. +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "Gaussian distributions govern everything from particle diffusion to the distribution of shoe sizes. Applying them to price action isn't 'technical analysis'; it's just physics with a profit motive." ALMA is a Finite Impulse Response (FIR) filter that applies a Gaussian window to price data. Unlike the Simple Moving Average (which treats 10-minute-old data with the same reverence as 1-minute-old data) or the Exponential Moving Average (which holds onto history like a hoarder), ALMA allows you to shape the weight distribution precisely. It lets you define the trade-off between smoothness and lag using standard deviation ($\sigma$) and offset, rather than arbitrary periods. @@ -279,4 +296,4 @@ For ALMA(50), total memory is approximately 900 bytes per instance. * $\sigma = 1$: The curve is flat. You have reinvented the Simple Moving Average (badly). * $\sigma = 10$: The curve is a needle. You are sampling one specific bar in history. -3. **Cold Start**: ALMA requires a full window ($L$) to be mathematically valid. First $L-1$ bars are convergence noise. Ignore them. \ No newline at end of file +3. **Cold Start**: ALMA requires a full window ($L$) to be mathematically valid. First $L-1$ bars are convergence noise. Ignore them. diff --git a/lib/trends_FIR/blma/Blma.md b/lib/trends_FIR/blma/Blma.md index e34b95fc..7d3003ef 100644 --- a/lib/trends_FIR/blma/Blma.md +++ b/lib/trends_FIR/blma/Blma.md @@ -1,5 +1,22 @@ # BLMA: Blackman Window Moving Average +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Trend (FIR MA) | +| **Inputs** | Source (close) | +| **Parameters** | `period` | +| **Outputs** | Single series (Blma) | +| **Output range** | Tracks input | +| **Warmup** | `period` bars | + +### TL;DR + +- The Blackman Window Moving Average (BLMA) applies a triple-cosine window function from digital signal processing to financial time series. +- Parameterized by `period`. +- Output range: Tracks input. +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "If you want to filter noise, don't just average it - window it." The Blackman Window Moving Average (BLMA) applies a triple-cosine window function from digital signal processing to financial time series. Originally developed by **Ralph Beebe Blackman** at Bell Labs in the 1950s for spectral analysis, this filter provides superior noise suppression compared to standard moving averages by minimizing spectral leakage. @@ -241,4 +258,4 @@ private static double ComputeWeightedAverage(double weightSum, double weightedSu ### Common Pitfalls * **Lag**: BLMA has more lag than EMA or WMA because it suppresses the most recent data. It is a smoothing filter, not a leading indicator. -* **Warmup**: During the first $N$ bars, the window expands dynamically. The full noise-suppression characteristics are only achieved after $N$ bars. \ No newline at end of file +* **Warmup**: During the first $N$ bars, the window expands dynamically. The full noise-suppression characteristics are only achieved after $N$ bars. diff --git a/lib/trends_FIR/bwma/Bwma.md b/lib/trends_FIR/bwma/Bwma.md index 857399da..c2001199 100644 --- a/lib/trends_FIR/bwma/Bwma.md +++ b/lib/trends_FIR/bwma/Bwma.md @@ -1,5 +1,22 @@ # BWMA: Bessel-Weighted Moving Average +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Trend (FIR MA) | +| **Inputs** | Source (close) | +| **Parameters** | `period`, `order` (default 0) | +| **Outputs** | Single series (Bwma) | +| **Output range** | Tracks input | +| **Warmup** | `period` bars | + +### TL;DR + +- BWMA is a Finite Impulse Response (FIR) filter that applies a Bessel-derived window function to weight price data. +- Parameterized by `period`, `order` (default 0). +- Output range: Tracks input. +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "The Bessel function appears in problems involving cylindrical symmetry—heat flow in pipes, vibration of drumheads, and apparently, the smoothing of financial time series. Mathematics doesn't care about your asset class." BWMA is a Finite Impulse Response (FIR) filter that applies a Bessel-derived window function to weight price data. The weighting follows a parabolic (or higher-order polynomial) profile that emphasizes the center of the lookback window while smoothly tapering to zero at the edges. Unlike rectangular (SMA) or exponential (EMA) weighting, BWMA provides a mathematically smooth transition that reduces spectral leakage and Gibbs phenomenon artifacts. @@ -344,4 +361,4 @@ else * [ALMA](../alma/Alma.md) - Gaussian window with adjustable offset * [WMA](../wma/Wma.md) - Linear weighting (triangular window) -* [SINEMA](../sinema/Sinema.md) - Sine-weighted moving average \ No newline at end of file +* [SINEMA](../sinema/Sinema.md) - Sine-weighted moving average diff --git a/lib/trends_FIR/conv/Conv.md b/lib/trends_FIR/conv/Conv.md index b1e8d1d9..d81d450e 100644 --- a/lib/trends_FIR/conv/Conv.md +++ b/lib/trends_FIR/conv/Conv.md @@ -1,5 +1,22 @@ # CONV: Convolution Moving Average +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Trend (FIR MA) | +| **Inputs** | Source (close) | +| **Parameters** | double[] kernel | +| **Outputs** | Single series (Conv) | +| **Output range** | Tracks input | +| **Warmup** | `period` bars | + +### TL;DR + +- CONV (Convolution Moving Average) is the ultimate tool for the signal processing purist. +- Parameterized by double[] kernel. +- Output range: Tracks input. +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "If you want a moving average that behaves exactly how you want it to, build it yourself. CONV is the 'Bring Your Own Kernel' of indicators." CONV (Convolution Moving Average) is the ultimate tool for the signal processing purist. It doesn't presume to know what kind of smoothing you need; it simply asks for a kernel (a set of weights) and applies it to the data. Want a Gaussian filter? A Sinc filter? A custom edge-detection filter? CONV runs them all. @@ -151,4 +168,4 @@ For a typical 14-period kernel: ~68 + 224 ≈ **292 bytes** per instance. 1. **Kernel Direction**: Our implementation applies the kernel such that the last element of the kernel multiplies the most recent data point. If you import kernels from other DSP libraries, you might need to reverse them. 2. **Normalization**: Kernel weights are *not* automatically normalized. If the sum of the weights is not 1.0, the output scale will be different from the input scale. This is a feature, not a bug (allows for differential filters). -3. **Performance**: A kernel size of 1000 will be 100x slower than a kernel size of 10. Use FFT-based convolution for massive kernels (not implemented here; this is for trading, not searching for extraterrestrial life). \ No newline at end of file +3. **Performance**: A kernel size of 1000 will be 100x slower than a kernel size of 10. Use FFT-based convolution for massive kernels (not implemented here; this is for trading, not searching for extraterrestrial life). diff --git a/lib/trends_FIR/crma/Crma.md b/lib/trends_FIR/crma/Crma.md index 70f3317b..fcb0b293 100644 --- a/lib/trends_FIR/crma/Crma.md +++ b/lib/trends_FIR/crma/Crma.md @@ -1,4 +1,21 @@ -# CRMA: Cubic Regression Moving Average +# CRMA: Cubic Regression Moving Average + +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Trend (FIR MA) | +| **Inputs** | Source (close) | +| **Parameters** | `period` | +| **Outputs** | Single series (Crma) | +| **Output range** | Tracks input | +| **Warmup** | `period` bars | + +### TL;DR + +- CRMA fits a degree-3 polynomial $y = a_0 + a_1 x + a_2 x^2 + a_3 x^3$ to the most recent $N$ bars via ordinary least squares, then returns the fitt... +- Parameterized by `period`. +- Output range: Tracks input. +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. > "Linear regression tells you where the trend is going. Quadratic regression tells you it's curving. Cubic regression tells you the curve is changing its mind." diff --git a/lib/trends_FIR/dwma/Dwma.md b/lib/trends_FIR/dwma/Dwma.md index cd686ef7..cbba1e5f 100644 --- a/lib/trends_FIR/dwma/Dwma.md +++ b/lib/trends_FIR/dwma/Dwma.md @@ -1,5 +1,22 @@ # DWMA: Double Weighted Moving Average +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Trend (FIR MA) | +| **Inputs** | Source (close) | +| **Parameters** | `period` | +| **Outputs** | Single series (Dwma) | +| **Output range** | Tracks input | +| **Warmup** | `(period * 2) - 1` bars | + +### TL;DR + +- DWMA (Double Weighted Moving Average) is exactly what it says on the tin: a Weighted Moving Average of a Weighted Moving Average. +- Parameterized by `period`. +- Output range: Tracks input. +- Requires `(period * 2) - 1` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "If one WMA is good, two must be better. DWMA is for when you want your signal so smooth it looks like it's been sanded, polished, and waxed." DWMA (Double Weighted Moving Average) is exactly what it says on the tin: a Weighted Moving Average of a Weighted Moving Average. Unlike DEMA, which tries to *remove* lag, DWMA accepts lag as the price of admission for superior noise reduction. It produces a curve that is incredibly smooth, ideal for identifying long-term trends without getting faked out by market chop. @@ -209,4 +226,4 @@ protected override void Dispose(bool disposing) 1. **Lag**: This indicator lags. A lot. Do not use it for entry signals on tight timeframes. Use it for trend filtering (e.g., "only buy if price > DWMA"). 2. **Warmup**: It takes roughly $2 \times N$ bars to produce valid data. -3. **Confusion with DEMA**: DEMA = Fast, DWMA = Smooth. Do not mix them up. \ No newline at end of file +3. **Confusion with DEMA**: DEMA = Fast, DWMA = Smooth. Do not mix them up. diff --git a/lib/trends_FIR/fwma/Fwma.md b/lib/trends_FIR/fwma/Fwma.md index 7bfeaf45..97c16670 100644 --- a/lib/trends_FIR/fwma/Fwma.md +++ b/lib/trends_FIR/fwma/Fwma.md @@ -1,5 +1,22 @@ # FWMA: Fibonacci Weighted Moving Average +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Trend (FIR MA) | +| **Inputs** | Source (close) | +| **Parameters** | `period` (default 10) | +| **Outputs** | Single series (Fwma) | +| **Output range** | Tracks input | +| **Warmup** | `period` bars | + +### TL;DR + +- The Fibonacci Weighted Moving Average applies the Fibonacci sequence as FIR filter weights, assigning exponentially growing importance to recent bars. +- Parameterized by `period` (default 10). +- Output range: Tracks input. +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "Nature uses Fibonacci for sunflower seeds and nautilus shells. Using it for price weighting is either profound biological insight or the most expensive numerology in finance. The math doesn't care which." The Fibonacci Weighted Moving Average applies the Fibonacci sequence as FIR filter weights, assigning exponentially growing importance to recent bars. Where WMA uses linear weights (1, 2, 3, ..., N) and PWMA uses parabolic weights ($1^2, 2^2, ..., N^2$), FWMA uses F(1), F(2), ..., F(N). The Fibonacci growth rate ($\phi \approx 1.618$) produces a weighting profile between exponential and parabolic, giving FWMA a distinctive "golden ratio decay" that concentrates roughly 61.8% of total weight in the most recent third of the window. diff --git a/lib/trends_FIR/gwma/Gwma.md b/lib/trends_FIR/gwma/Gwma.md index cc953919..ec4d03a2 100644 --- a/lib/trends_FIR/gwma/Gwma.md +++ b/lib/trends_FIR/gwma/Gwma.md @@ -1,5 +1,22 @@ # GWMA: Gaussian-Weighted Moving Average +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Trend (FIR MA) | +| **Inputs** | Source (close) | +| **Parameters** | `period`, `sigma` (default 0.4) | +| **Outputs** | Single series (Gwma) | +| **Output range** | Tracks input | +| **Warmup** | `period` bars | + +### TL;DR + +- GWMA is a Finite Impulse Response (FIR) filter that applies a centered Gaussian window to price data. +- Parameterized by `period`, `sigma` (default 0.4). +- Output range: Tracks input. +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "The Gaussian distribution shows up everywhere from thermal noise to the central limit theorem. Using it to weight price data isn't magic; it's just applied statistics with a trading account." GWMA is a Finite Impulse Response (FIR) filter that applies a centered Gaussian window to price data. Unlike ALMA (which allows shifting the Gaussian peak via an offset parameter), GWMA centers the bell curve at the middle of the lookback window. The sigma parameter controls the width of the Gaussian, determining how sharply the weights decay from the center. @@ -357,4 +374,4 @@ public override TSeries Update(TSeries source) 3. **Cold Start**: GWMA requires a full window ($L$) to be mathematically valid. First $L-1$ bars are convergence noise. -4. **Centered vs Offset**: Don't confuse GWMA with ALMA. GWMA always centers the Gaussian; ALMA lets you shift it. If you find yourself wanting offset control, use ALMA instead. \ No newline at end of file +4. **Centered vs Offset**: Don't confuse GWMA with ALMA. GWMA always centers the Gaussian; ALMA lets you shift it. If you find yourself wanting offset control, use ALMA instead. diff --git a/lib/trends_FIR/hamma/Hamma.md b/lib/trends_FIR/hamma/Hamma.md index 57cbc6c6..251952cb 100644 --- a/lib/trends_FIR/hamma/Hamma.md +++ b/lib/trends_FIR/hamma/Hamma.md @@ -1,5 +1,22 @@ # HAMMA: Hamming-Weighted Moving Average +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Trend (FIR MA) | +| **Inputs** | Source (close) | +| **Parameters** | `period` (default 10) | +| **Outputs** | Single series (Hamma) | +| **Output range** | Tracks input | +| **Warmup** | `period` bars | + +### TL;DR + +- HAMMA is a Finite Impulse Response (FIR) filter that applies a Hamming window to price data. +- Parameterized by `period` (default 10). +- Output range: Tracks input. +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "Julius von Hann picked his window function to suppress spectral leakage; we're just using it to smooth price data. Same math, different trading floor." HAMMA is a Finite Impulse Response (FIR) filter that applies a Hamming window to price data. The Hamming window is a raised cosine with specific coefficients (0.54 and 0.46) chosen to minimize the amplitude of the first side lobe in the frequency domain. This makes it particularly effective at separating the signal (trend) from nearby noise frequencies. @@ -247,4 +264,4 @@ For a typical 14-period: ~92 + 224 ≈ **316 bytes** per instance. 4. **Small Periods**: With very small periods (e.g., 3), the window shape degenerates. The edge-center-edge pattern becomes less meaningful. Consider period >= 5 for meaningful Hamming characteristics. -5. **Side Lobe Trade-off**: The -43 dB first side lobe comes at the cost of slightly wider main lobe than Hanning. If frequency resolution matters more than side lobe suppression, consider other windows. \ No newline at end of file +5. **Side Lobe Trade-off**: The -43 dB first side lobe comes at the cost of slightly wider main lobe than Hanning. If frequency resolution matters more than side lobe suppression, consider other windows. diff --git a/lib/trends_FIR/hanma/Hanma.md b/lib/trends_FIR/hanma/Hanma.md index 729d1b91..34ef52a2 100644 --- a/lib/trends_FIR/hanma/Hanma.md +++ b/lib/trends_FIR/hanma/Hanma.md @@ -1,5 +1,22 @@ # HANMA: Hanning-Weighted Moving Average +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Trend (FIR MA) | +| **Inputs** | Source (close) | +| **Parameters** | `period` (default 10) | +| **Outputs** | Single series (Hanma) | +| **Output range** | Tracks input | +| **Warmup** | `period` bars | + +### TL;DR + +- HANMA is a Finite Impulse Response (FIR) filter that applies a Hanning (Hann) window to price data. +- Parameterized by `period` (default 10). +- Output range: Tracks input. +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "Julius von Hann deserves credit for the window that bears his name—even if autocomplete keeps trying to change it to 'Hamming.' The zero-edge weights aren't a bug; they're the whole point." HANMA is a Finite Impulse Response (FIR) filter that applies a Hanning (Hann) window to price data. The Hanning window is a pure raised cosine with edge weights of exactly zero, which provides excellent side lobe suppression while maintaining a narrower main lobe than Hamming. It's particularly effective when you want to eliminate boundary discontinuities entirely. @@ -252,4 +269,4 @@ For a typical 14-period: ~92 + 224 ≈ **316 bytes** per instance. 5. **Small Periods**: With very small periods (e.g., 3), the window shape degenerates. A period of 3 produces weights [0, 1, 0]—essentially just the middle value. Consider period >= 5 for meaningful Hanning characteristics. -6. **Side Lobe Trade-off**: The -32 dB first side lobe is worse than Hamming's -43 dB, but the narrower main lobe provides better frequency resolution. Choose based on whether you prioritize frequency resolution or side lobe suppression. \ No newline at end of file +6. **Side Lobe Trade-off**: The -32 dB first side lobe is worse than Hamming's -43 dB, but the narrower main lobe provides better frequency resolution. Choose based on whether you prioritize frequency resolution or side lobe suppression. diff --git a/lib/trends_FIR/hend/Hend.md b/lib/trends_FIR/hend/Hend.md index 7a6d96d6..4af8ddb6 100644 --- a/lib/trends_FIR/hend/Hend.md +++ b/lib/trends_FIR/hend/Hend.md @@ -1,4 +1,21 @@ -# HEND: Henderson Moving Average +# HEND: Henderson Moving Average + +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Trend (FIR MA) | +| **Inputs** | Source (close) | +| **Parameters** | `period` (default 7) | +| **Outputs** | Single series (Hend) | +| **Output range** | Tracks input | +| **Warmup** | `period` bars | + +### TL;DR + +- HEND is a symmetric FIR filter derived from the Henderson (1916) closed-form weight formula, designed to pass cubic polynomial trends without disto... +- Parameterized by `period` (default 7). +- Output range: Tracks input. +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. > "Robert Henderson designed a filter so good that the Australian Bureau of Statistics still uses it a century later. When your smoothing algorithm outlasts empires, you did something right." diff --git a/lib/trends_FIR/hma/Hma.md b/lib/trends_FIR/hma/Hma.md index 7916f601..05a4cc71 100644 --- a/lib/trends_FIR/hma/Hma.md +++ b/lib/trends_FIR/hma/Hma.md @@ -1,5 +1,22 @@ # HMA: Hull Moving Average +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Trend (FIR MA) | +| **Inputs** | Source (close) | +| **Parameters** | `period` | +| **Outputs** | Single series (Hma) | +| **Output range** | Tracks input | +| **Warmup** | `period + sqrtPeriod - 1` bars | + +### TL;DR + +- HMA (Hull Moving Average) is a solution to the eternal struggle between smoothness and lag. +- Parameterized by `period`. +- Output range: Tracks input. +- Requires `period + sqrtPeriod - 1` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "Alan Hull looked at the lag in moving averages and said, 'I can fix that.' And he did, by making the math do gymnastics." HMA (Hull Moving Average) is a solution to the eternal struggle between smoothness and lag. Most indicators force you to choose one; HMA gives you both. It achieves this by using weighted moving averages (WMAs) in a clever configuration that cancels out lag while maintaining the smoothing properties of the WMA. @@ -220,4 +237,4 @@ For HMA(100), total memory is approximately 1.7 KB per instance (three WMA insta 1. **Overshoot**: Like DEMA, HMA can overshoot price turns because of the lag correction. 2. **Period Sensitivity**: The $\sqrt{N}$ smoothing is hardcoded into the definition. You can't easily tweak the smoothing independently of the lag correction without breaking the "Hull" definition. -3. **Integer Math**: The periods $N/2$ and $\sqrt{N}$ are rounded to integers. This can cause slight discrepancies between implementations depending on rounding rules. Standard integer truncation is used in QuanTAlib. \ No newline at end of file +3. **Integer Math**: The periods $N/2$ and $\sqrt{N}$ are rounded to integers. This can cause slight discrepancies between implementations depending on rounding rules. Standard integer truncation is used in QuanTAlib. diff --git a/lib/trends_FIR/ilrs/Ilrs.md b/lib/trends_FIR/ilrs/Ilrs.md index aad08e6a..c7a53151 100644 --- a/lib/trends_FIR/ilrs/Ilrs.md +++ b/lib/trends_FIR/ilrs/Ilrs.md @@ -1,4 +1,21 @@ -# ILRS: Integral of Linear Regression Slope +# ILRS: Integral of Linear Regression Slope + +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Trend (FIR MA) | +| **Inputs** | Source (close) | +| **Parameters** | `period` (default 14) | +| **Outputs** | Single series (Ilrs) | +| **Output range** | Tracks input | +| **Warmup** | `period` bars | + +### TL;DR + +- ILRS computes the linear regression slope over a rolling window, then accumulates it via discrete integration (running sum) to reconstruct a smooth... +- Parameterized by `period` (default 14). +- Output range: Tracks input. +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. > "John Ehlers took the slope of a regression line, integrated it, and got a smoother trend follower. Differentiate to find direction, integrate to find position. Calculus: still useful after 300 years." diff --git a/lib/trends_FIR/kaiser/Kaiser.md b/lib/trends_FIR/kaiser/Kaiser.md index c2a039d0..ce4485bd 100644 --- a/lib/trends_FIR/kaiser/Kaiser.md +++ b/lib/trends_FIR/kaiser/Kaiser.md @@ -1,4 +1,21 @@ -# KAISER: Kaiser Window Moving Average +# KAISER: Kaiser Window Moving Average + +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Trend (FIR MA) | +| **Inputs** | Source (close) | +| **Parameters** | `period` (default 14), `beta` (default 3.0) | +| **Outputs** | Single series (Kaiser) | +| **Output range** | Tracks input | +| **Warmup** | `period` bars | + +### TL;DR + +- KAISER applies the Kaiser-Bessel window function as FIR filter weights, providing a single parameter ($\beta$) that continuously controls the trade... +- Parameterized by `period` (default 14), `beta` (default 3.0). +- Output range: Tracks input. +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. > "James Kaiser gave signal processing a knob. Turn beta up, sidelobes go down, transition band widens. Turn it down, you get an SMA. One parameter to rule them all." diff --git a/lib/trends_FIR/lanczos/Lanczos.md b/lib/trends_FIR/lanczos/Lanczos.md index 9f1985bd..ee9d1478 100644 --- a/lib/trends_FIR/lanczos/Lanczos.md +++ b/lib/trends_FIR/lanczos/Lanczos.md @@ -1,4 +1,21 @@ -# LANCZOS: Lanczos (Sinc) Window Moving Average +# LANCZOS: Lanczos (Sinc) Window Moving Average + +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Trend (FIR MA) | +| **Inputs** | Source (close) | +| **Parameters** | `period` (default 14) | +| **Outputs** | Single series (Lanczos) | +| **Output range** | Tracks input | +| **Warmup** | `period` bars | + +### TL;DR + +- LANCZOS applies the normalized sinc function $\text{sinc}(x) = \sin(\pi x)/(\pi x)$ as a symmetric FIR window, producing a moving average with near... +- Parameterized by `period` (default 14). +- Output range: Tracks input. +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. > "Cornelius Lanczos used the sinc function to reconstruct band-limited signals from discrete samples. Apply it to price data and you get a moving average that respects the Nyquist limit while your competitors are still using SMAs." diff --git a/lib/trends_FIR/lsma/Lsma.md b/lib/trends_FIR/lsma/Lsma.md index e13b6d11..6393da5e 100644 --- a/lib/trends_FIR/lsma/Lsma.md +++ b/lib/trends_FIR/lsma/Lsma.md @@ -1,5 +1,22 @@ # LSMA: Least Squares Moving Average +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Trend (FIR MA) | +| **Inputs** | Source (close) | +| **Parameters** | `period`, `offset` (default 0) | +| **Outputs** | Single series (Lsma) | +| **Output range** | Tracks input | +| **Warmup** | `period` bars | + +### TL;DR + +- LSMA (Least Squares Moving Average), also known as the Moving Linear Regression or Endpoint Moving Average, calculates the least squares regression... +- Parameterized by `period`, `offset` (default 0). +- Output range: Tracks input. +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "If you want to know where the price is going, draw a line through where it's been. LSMA does this for every single bar, tirelessly fitting linear regressions while you sleep." LSMA (Least Squares Moving Average), also known as the Moving Linear Regression or Endpoint Moving Average, calculates the least squares regression line for the preceding time periods. In plain English: it finds the "best fit" line for the data window and tells you where that line ends. @@ -227,4 +244,4 @@ private double GetValidValue(double input) 1. **Overshoot**: Because it projects a trend, LSMA will overshoot significantly when the trend reverses. It assumes the trend continues. 2. **Offset**: You can use a positive offset to extrapolate into the future (forecasting), or a negative offset to center the average. -3. **Noise**: It is very sensitive to outliers because it tries to fit a line to them. \ No newline at end of file +3. **Noise**: It is very sensitive to outliers because it tries to fit a line to them. diff --git a/lib/trends_FIR/nlma/Nlma.md b/lib/trends_FIR/nlma/Nlma.md index 88b73656..1cb6ebbc 100644 --- a/lib/trends_FIR/nlma/Nlma.md +++ b/lib/trends_FIR/nlma/Nlma.md @@ -1,4 +1,21 @@ -# NLMA: Non-Lag Moving Average +# NLMA: Non-Lag Moving Average + +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Trend (FIR MA) | +| **Inputs** | Source (close) | +| **Parameters** | `period` (default 14) | +| **Outputs** | Single series (Nlma) | +| **Output range** | Tracks input | +| **Warmup** | 1 bar | + +### TL;DR + +- NLMA uses a two-phase damped cosine kernel with $5P - 1$ taps (where $P$ is the user period). +- Parameterized by `period` (default 14). +- Output range: Tracks input. +- Requires 1 bar of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. > "Igorad at TrendLaboratory built a two-phase FIR kernel that uses five times more taps than the period parameter suggests. The extra taps carry negative weights that actively cancel group delay. Most 'non-lag' indicators are marketing. This one is signal processing." diff --git a/lib/trends_FIR/nyqma/Nyqma.md b/lib/trends_FIR/nyqma/Nyqma.md index b4fbe0e1..78b8cbe5 100644 --- a/lib/trends_FIR/nyqma/Nyqma.md +++ b/lib/trends_FIR/nyqma/Nyqma.md @@ -1,5 +1,22 @@ # NYQMA: Nyquist Moving Average +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Trend (FIR MA) | +| **Inputs** | Source (close) | +| **Parameters** | `period` (default 89), `nyquistPeriod` (default 21) | +| **Outputs** | Single series (Nyqma) | +| **Output range** | Tracks input | +| **Warmup** | 1 bar | + +### TL;DR + +- NYQMA combines a primary LWMA (Linear Weighted Moving Average) with a secondary LWMA applied to the first, using lag-compensating extrapolation: $\... +- Parameterized by `period` (default 89), `nyquistperiod` (default 21). +- Output range: Tracks input. +- Requires 1 bar of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "Manfred Dürschner applied the Nyquist-Shannon sampling theorem to cascaded moving averages: the second smoothing period must not exceed half the first, or you get aliasing artifacts. Respect the theorem and the ghost signals disappear." NYQMA combines a primary LWMA (Linear Weighted Moving Average) with a secondary LWMA applied to the first, using lag-compensating extrapolation: $\text{NYQMA} = (1+\alpha) \cdot \text{MA}_1 - \alpha \cdot \text{MA}_2$, where $\alpha = N_2 / (N_1 - N_2)$. The Nyquist constraint $N_2 \leq \lfloor N_1/2 \rfloor$ ensures the second smoothing does not introduce aliasing artifacts into the output. This produces a lag-reduced moving average grounded in sampling theory rather than ad-hoc coefficient tuning. Streaming update is O(1) per bar via composed Wma instances; batch mode uses stackalloc/ArrayPool with FMA in the extrapolation loop. diff --git a/lib/trends_FIR/parzen/Parzen.md b/lib/trends_FIR/parzen/Parzen.md index ecfc18dd..726cfbb5 100644 --- a/lib/trends_FIR/parzen/Parzen.md +++ b/lib/trends_FIR/parzen/Parzen.md @@ -1,4 +1,21 @@ -# PARZEN: Parzen (de la Vallée-Poussin) Window Moving Average +# PARZEN: Parzen (de la Vallée-Poussin) Window Moving Average + +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Trend (FIR MA) | +| **Inputs** | Source (close) | +| **Parameters** | `period` (default 14) | +| **Outputs** | Single series (Parzen) | +| **Output range** | Tracks input | +| **Warmup** | `period` bars | + +### TL;DR + +- PARZEN applies the Parzen (de la Vallée-Poussin) window function as FIR filter weights, producing a moving average with exceptional sidelobe suppre... +- Parameterized by `period` (default 14). +- Output range: Tracks input. +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. > "Emanuel Parzen convolved two triangular windows and got a piecewise cubic with zero sidelobe discontinuity. When your window function is its own proof of smoothness, the spectral leakage has nowhere to hide." diff --git a/lib/trends_FIR/pma/Pma.md b/lib/trends_FIR/pma/Pma.md index c887008c..fe4e74cf 100644 --- a/lib/trends_FIR/pma/Pma.md +++ b/lib/trends_FIR/pma/Pma.md @@ -1,4 +1,21 @@ -# PMA: Predictive Moving Average +# PMA: Predictive Moving Average + +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Trend (FIR MA) | +| **Inputs** | Source (close) | +| **Parameters** | `period` | +| **Outputs** | Single series (Pma) | +| **Output range** | Tracks input | +| **Warmup** | `(period * 2) - 1` bars | + +### TL;DR + +- PMA (Predictive Moving Average) is a lag-cancellation filter that uses linear extrapolation of dual WMA (Weighted Moving Average) cascades to predi... +- Parameterized by `period`. +- Output range: Tracks input. +- Requires `(period * 2) - 1` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. > "John Ehlers looked at WMA's lag and said: 'What if we just extrapolated it away?' The result is a moving average that actually tries to predict where price is going, not where it has been." diff --git a/lib/trends_FIR/pwma/Pwma.md b/lib/trends_FIR/pwma/Pwma.md index 7f920a42..01251326 100644 --- a/lib/trends_FIR/pwma/Pwma.md +++ b/lib/trends_FIR/pwma/Pwma.md @@ -1,5 +1,22 @@ # PWMA: Parabolic Weighted Moving Average +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Trend (FIR MA) | +| **Inputs** | Source (close) | +| **Parameters** | `period` | +| **Outputs** | Single series (Pwma) | +| **Output range** | Tracks input | +| **Warmup** | `period` bars | + +### TL;DR + +- PWMA (Parabolic Weighted Moving Average) applies a parabolic ($i^2$) weighting scheme to the data window. +- Parameterized by `period`. +- Output range: Tracks input. +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "Linear weighting is for people who think the world is flat. PWMA squares the weights, because recent data isn't just more important—it's exponentially more important." PWMA (Parabolic Weighted Moving Average) applies a parabolic ($i^2$) weighting scheme to the data window. This assigns massive importance to the most recent data points while still technically including the older data. It's like a WMA on steroids. @@ -171,4 +188,4 @@ if (_state.TickCount >= 1000) ### Common Pitfalls 1. **Resync**: Because triple running sums are used, floating-point errors can accumulate faster than in a simple SMA. The implementation automatically resyncs every 1000 ticks to maintain precision. -2. **Sensitivity**: This indicator is very sensitive to the most recent bar. It can "repaint" visually if used on an open bar (though the math is consistent). \ No newline at end of file +2. **Sensitivity**: This indicator is very sensitive to the most recent bar. It can "repaint" visually if used on an open bar (though the math is consistent). diff --git a/lib/trends_FIR/qrma/Qrma.md b/lib/trends_FIR/qrma/Qrma.md index 4dd4cfdb..f3b26860 100644 --- a/lib/trends_FIR/qrma/Qrma.md +++ b/lib/trends_FIR/qrma/Qrma.md @@ -1,4 +1,21 @@ -# QRMA: Quadratic Regression Moving Average +# QRMA: Quadratic Regression Moving Average + +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Trend (FIR MA) | +| **Inputs** | Source (close) | +| **Parameters** | `period` | +| **Outputs** | Single series (Qrma) | +| **Output range** | Tracks input | +| **Warmup** | `period` bars | + +### TL;DR + +- QRMA fits a second-degree polynomial $y = a + bx + cx^2$ to the most recent $N$ bars via ordinary least squares, then returns the fitted value at t... +- Parameterized by `period`. +- Output range: Tracks input. +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. > "Linear regression assumes the world is a straight line. Quadratic regression admits it might curve. For parabolic price moves, that admission turns out to be worth 40% less endpoint error." diff --git a/lib/trends_FIR/rain/Rain.md b/lib/trends_FIR/rain/Rain.md index 35af18a8..fd7c796c 100644 --- a/lib/trends_FIR/rain/Rain.md +++ b/lib/trends_FIR/rain/Rain.md @@ -1,4 +1,21 @@ -# RAIN: Rainbow Moving Average +# RAIN: Rainbow Moving Average + +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Trend (FIR MA) | +| **Inputs** | Source (close) | +| **Parameters** | `period` | +| **Outputs** | Single series (Rain) | +| **Output range** | Tracks input | +| **Warmup** | 1 bar | + +### TL;DR + +- RAIN recursively applies SMA 10 times, producing 10 layers of progressively smoother price representation, then computes a weighted average across ... +- Parameterized by `period`. +- Output range: Tracks input. +- Requires 1 bar of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. > "Mel Widner applied SMA ten times recursively, then weighted the layers like a rainbow: brightest at the top, fading toward the base. Ten colors of smoothing, one composite average that sees both fast and slow structure simultaneously." diff --git a/lib/trends_FIR/rwma/Rwma.md b/lib/trends_FIR/rwma/Rwma.md index 35e54856..c0b5b157 100644 --- a/lib/trends_FIR/rwma/Rwma.md +++ b/lib/trends_FIR/rwma/Rwma.md @@ -1,4 +1,21 @@ -# RWMA: Range Weighted Moving Average +# RWMA: Range Weighted Moving Average + +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Trend (FIR MA) | +| **Inputs** | OHLCV bar (TBar) | +| **Parameters** | `period` (default 14) | +| **Outputs** | Single series (Rwma) | +| **Output range** | Tracks input | +| **Warmup** | `> period` bars | + +### TL;DR + +- RWMA weights each bar's contribution to the average by its price range (high minus low), giving greater influence to volatile bars and less to narr... +- Parameterized by `period` (default 14). +- Output range: Tracks input. +- Requires `> period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. > "Most averages weight by position: recent bars matter more. RWMA weights by volatility: volatile bars matter more. The market spoke loudest when the range was widest, so listen to those bars." diff --git a/lib/trends_FIR/sgma/Sgma.md b/lib/trends_FIR/sgma/Sgma.md index da66ed76..fca12899 100644 --- a/lib/trends_FIR/sgma/Sgma.md +++ b/lib/trends_FIR/sgma/Sgma.md @@ -1,5 +1,22 @@ # SGMA: Savitzky-Golay Moving Average +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Trend (FIR MA) | +| **Inputs** | Source (close) | +| **Parameters** | `period` (default 9), `degree` (default 2) | +| **Outputs** | Single series (Sgma) | +| **Output range** | Tracks input | +| **Warmup** | `period` bars | + +### TL;DR + +- SGMA is a Finite Impulse Response (FIR) filter that uses polynomial fitting to smooth data while preserving higher moments (peaks, valleys, and inf... +- Parameterized by `period` (default 9), `degree` (default 2). +- Output range: Tracks input. +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "Least-squares polynomial fitting has been solving signal processing problems since 1964. That most traders still use medieval averaging techniques says more about the industry than the math." SGMA is a Finite Impulse Response (FIR) filter that uses polynomial fitting to smooth data while preserving higher moments (peaks, valleys, and inflection points). Unlike the Simple Moving Average (which flattens everything) or the Exponential Moving Average (which introduces phase lag), SGMA uses polynomial weighting to maintain the original signal's shape characteristics. @@ -287,4 +304,4 @@ else 4. **Cold Start**: SGMA requires a full window ($L$) to produce mathematically valid output. The first $L-1$ bars are warmup noise. Check `IsHot` before trading on the signal. -5. **High Degree Instability**: Degrees 3-4 concentrate weight heavily in the center. While this preserves shape, it also means a small number of bars dominate the output—approaching the behavior of a very short moving average with extra smoothing on the tails. \ No newline at end of file +5. **High Degree Instability**: Degrees 3-4 concentrate weight heavily in the center. While this preserves shape, it also means a small number of bars dominate the output—approaching the behavior of a very short moving average with extra smoothing on the tails. diff --git a/lib/trends_FIR/sinema/Sinema.md b/lib/trends_FIR/sinema/Sinema.md index 87d89ad0..f341c415 100644 --- a/lib/trends_FIR/sinema/Sinema.md +++ b/lib/trends_FIR/sinema/Sinema.md @@ -1,5 +1,22 @@ # SINEMA: Sine-Weighted Moving Average +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Trend (FIR MA) | +| **Inputs** | Source (close) | +| **Parameters** | `period` | +| **Outputs** | Single series (Sinema) | +| **Output range** | Tracks input | +| **Warmup** | `period` bars | + +### TL;DR + +- The Sine-Weighted Moving Average (SINEMA) applies sine-wave weighting to data points within the lookback window. +- Parameterized by `period`. +- Output range: Tracks input. +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "Nature doesn't do straight lines, and neither should your weights." The Sine-Weighted Moving Average (SINEMA) applies sine-wave weighting to data points within the lookback window. Weights follow the formula $w_i = \sin(\pi \cdot (i+1) / N)$, creating a smooth bell-shaped distribution that emphasizes middle values while gracefully tapering at the edges. Unlike SMA's uniform weighting or WMA's linear ramp, sine weighting provides a natural transition that reduces high-frequency noise while preserving mid-frequency trends. @@ -220,4 +237,4 @@ This produces valid, smooth output from bar 1 without waiting for a full window. ## References - Harris, F. J. (1978). "On the use of windows for harmonic analysis with the discrete Fourier transform." *Proceedings of the IEEE*, 66(1), 51-83. -- Oppenheim, A. V., & Schafer, R. W. (2010). *Discrete-Time Signal Processing* (3rd ed.). Pearson. \ No newline at end of file +- Oppenheim, A. V., & Schafer, R. W. (2010). *Discrete-Time Signal Processing* (3rd ed.). Pearson. diff --git a/lib/trends_FIR/sma/Sma.md b/lib/trends_FIR/sma/Sma.md index b0396dad..69dacfb9 100644 --- a/lib/trends_FIR/sma/Sma.md +++ b/lib/trends_FIR/sma/Sma.md @@ -1,5 +1,22 @@ # SMA: Simple Moving Average +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Trend (FIR MA) | +| **Inputs** | Source (close) | +| **Parameters** | `period` | +| **Outputs** | Single series (Sma) | +| **Output range** | Tracks input | +| **Warmup** | `period` bars | + +### TL;DR + +- The Simple Moving Average (SMA) is the unweighted arithmetic mean of the last $N$ data points. +- Parameterized by `period`. +- Output range: Tracks input. +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "The vanilla ice cream of technical analysis. Boring, ubiquitous, and the only thing your grandfather and your high-frequency trading bot agree on." The Simple Moving Average (SMA) is the unweighted arithmetic mean of the last $N$ data points. It acts as a low-pass filter, smoothing out high-frequency noise to reveal the underlying trend. While conceptually simple, efficient implementation on modern hardware requires careful attention to memory access patterns and vectorization. @@ -186,4 +203,4 @@ For SMA(200), total memory is approximately 1.7 KB per instance. 1. **Lag**: SMA has the most lag of all moving averages (Lag $\approx N/2$). 2. **Drop-off Effect**: An old, large outlier dropping out of the window causes the SMA to jump, even if the current price is flat. This "Barker effect" is why EMAs are often preferred. -3. **NaN Handling**: A single `NaN` in the history window corrupts the entire SMA. QuanTAlib handles this by substituting the last valid value. \ No newline at end of file +3. **NaN Handling**: A single `NaN` in the history window corrupts the entire SMA. QuanTAlib handles this by substituting the last valid value. diff --git a/lib/trends_FIR/sp15/Sp15.md b/lib/trends_FIR/sp15/Sp15.md index e4571157..88255119 100644 --- a/lib/trends_FIR/sp15/Sp15.md +++ b/lib/trends_FIR/sp15/Sp15.md @@ -1,4 +1,21 @@ -# SP15: Spencer 15-Point Moving Average +# SP15: Spencer 15-Point Moving Average + +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Trend (FIR MA) | +| **Inputs** | Source (close) | +| **Parameters** | None | +| **Outputs** | Single series (SP15) | +| **Output range** | Tracks input | +| **Warmup** | `Period` bars | + +### TL;DR + +- SP15 is a fixed-coefficient symmetric FIR filter with 15 weights: $[-3, -6, -5, 3, 21, 46, 67, 74, 67, 46, 21, 3, -5, -6, -3]$ divided by 320. +- No configurable parameters; computation is stateless per bar. +- Output range: Tracks input. +- Requires `Period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. > "John Spencer designed 15 weights that zero out quarterly and quintile seasonality from economic data. Eighty years later, statisticians still reach for them when they need a quick seasonal adjustment that does not require the German engineering of X-13ARIMA." diff --git a/lib/trends_FIR/swma/Swma.md b/lib/trends_FIR/swma/Swma.md index 61086422..2cbc71fb 100644 --- a/lib/trends_FIR/swma/Swma.md +++ b/lib/trends_FIR/swma/Swma.md @@ -1,4 +1,21 @@ -# SWMA: Symmetric Weighted Moving Average +# SWMA: Symmetric Weighted Moving Average + +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Trend (FIR MA) | +| **Inputs** | Source (close) | +| **Parameters** | `period` (default 4) | +| **Outputs** | Single series (Swma) | +| **Output range** | Tracks input | +| **Warmup** | `period` bars | + +### TL;DR + +- SWMA applies triangular (symmetric) weights that peak at the center of the window and taper linearly to the edges. +- Parameterized by `period` (default 4). +- Output range: Tracks input. +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. > "Take the SMA of an SMA and you get a triangular filter. It is the simplest possible smoothing kernel that has zero phase distortion and no frequency-domain discontinuities. Sometimes simple is exactly what you need." diff --git a/lib/trends_FIR/trima/Trima.md b/lib/trends_FIR/trima/Trima.md index 40aff5f4..8e043905 100644 --- a/lib/trends_FIR/trima/Trima.md +++ b/lib/trends_FIR/trima/Trima.md @@ -1,5 +1,22 @@ # TRIMA: Triangular Moving Average +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Trend (FIR MA) | +| **Inputs** | Source (close) | +| **Parameters** | `period` | +| **Outputs** | Single series (Trima) | +| **Output range** | Tracks input | +| **Warmup** | `p1 + p2 - 1` bars | + +### TL;DR + +- The Triangular Moving Average (TRIMA) places the majority of its weight on the middle of the data window, tapering off linearly towards the ends. +- Parameterized by `period`. +- Output range: Tracks input. +- Requires `p1 + p2 - 1` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "The weighted blanket of moving averages. It doesn't care where the price is going right now; it cares where the price feels most comfortable." The Triangular Moving Average (TRIMA) places the majority of its weight on the middle of the data window, tapering off linearly towards the ends. This creates a triangular weight distribution (hence the name). It is mathematically equivalent to a double-smoothed SMA. @@ -181,4 +198,4 @@ This ensures consistent bar correction across the entire cascade. 1. **Lag**: TRIMA has more lag than SMA, EMA, or WMA. It is a lagging indicator, not a leading one. 2. **Signal Generation**: Due to its lag, TRIMA is poor for crossover signals. It is best used for visual trend identification or as a baseline for envelopes (e.g., TMA Bands). -3. **Even/Odd Periods**: The exact calculation of $P_1$ and $P_2$ differs slightly between implementations for even periods. QuanTAlib matches the standard definition used by TA-Lib. \ No newline at end of file +3. **Even/Odd Periods**: The exact calculation of $P_1$ and $P_2$ differs slightly between implementations for even periods. QuanTAlib matches the standard definition used by TA-Lib. diff --git a/lib/trends_FIR/tsf/Tsf.md b/lib/trends_FIR/tsf/Tsf.md index 0e963d4c..2e2b43f1 100644 --- a/lib/trends_FIR/tsf/Tsf.md +++ b/lib/trends_FIR/tsf/Tsf.md @@ -1,5 +1,22 @@ # TSF: Time Series Forecast +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Trend (FIR MA) | +| **Inputs** | Source (close) | +| **Parameters** | `period` (default 14) | +| **Outputs** | Single series (Tsf) | +| **Output range** | Tracks input | +| **Warmup** | `period` bars | + +### TL;DR + +- TSF projects the least-squares regression line one bar forward, providing a statistically grounded forecast of the next bar's value. +- Parameterized by `period` (default 14). +- Output range: Tracks input. +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "The best prediction of the future is the trend that's already in motion — extended by exactly one step." TSF projects the least-squares regression line one bar forward, providing a statistically grounded forecast of the next bar's value. Unlike simple moving averages that smooth past data, TSF answers the question: "If the current trend continues, where will price be next?" This makes it inherently leading rather than lagging, though the forecast degrades quickly beyond one step. diff --git a/lib/trends_FIR/tukey_w/Tukey_w.md b/lib/trends_FIR/tukey_w/Tukey_w.md index 5a29884f..240cd2e5 100644 --- a/lib/trends_FIR/tukey_w/Tukey_w.md +++ b/lib/trends_FIR/tukey_w/Tukey_w.md @@ -1,4 +1,21 @@ -# TUKEY_W: Tukey (Tapered Cosine) Window Moving Average +# TUKEY_W: Tukey (Tapered Cosine) Window Moving Average + +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Trend (FIR MA) | +| **Inputs** | Source (close) | +| **Parameters** | `period` (default 20), `alpha` (default 0.5) | +| **Outputs** | Single series (Tukey_w) | +| **Output range** | Tracks input | +| **Warmup** | `period` bars | + +### TL;DR + +- TUKEY_W applies the Tukey (tapered cosine) window as FIR filter weights, offering a single parameter $\alpha$ that controls the fraction of the win... +- Parameterized by `period` (default 20), `alpha` (default 0.5). +- Output range: Tracks input. +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. > "John Tukey designed a window with a knob that goes from 'do nothing' to 'full Hann' in one parameter. Set alpha to 0.5 and you get the pragmatist's compromise: flat where it matters, tapered where it would otherwise ring." diff --git a/lib/trends_FIR/wma/Wma.md b/lib/trends_FIR/wma/Wma.md index be3d7407..b1fde96d 100644 --- a/lib/trends_FIR/wma/Wma.md +++ b/lib/trends_FIR/wma/Wma.md @@ -1,5 +1,22 @@ # WMA: Weighted Moving Average +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Trend (FIR MA) | +| **Inputs** | Source (close) | +| **Parameters** | `period` | +| **Outputs** | Single series (Wma) | +| **Output range** | Tracks input | +| **Warmup** | `period` bars | + +### TL;DR + +- The Weighted Moving Average (WMA) assigns a linearly decreasing weight to data points. +- Parameterized by `period`. +- Output range: Tracks input. +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "Because yesterday matters more than last Tuesday. WMA is the linear answer to the question: 'What have you done for me lately?'" The Weighted Moving Average (WMA) assigns a linearly decreasing weight to data points. The most recent price gets weight $N$, the one before it $N-1$, down to 1. This makes it more responsive to recent price changes than an SMA, but without the infinite tail of an EMA. @@ -237,4 +254,4 @@ For WMA(200), total memory is approximately 1.75 KB per instance. 1. **Drift**: Like SMA, the O(1) algorithm is susceptible to floating-point drift. QuanTAlib resets the sums every 10,000 ticks to guarantee accuracy. 2. **Aggressiveness**: WMA reacts faster than SMA but can be "twitchy." It is often used as a component in other indicators (e.g., HMA) rather than a standalone trend filter. -3. **Weights**: Users sometimes confuse WMA (linear weights) with EMA (exponential weights) or VWAP (volume weights). \ No newline at end of file +3. **Weights**: Users sometimes confuse WMA (linear weights) with EMA (exponential weights) or VWAP (volume weights). diff --git a/lib/trends_IIR/adxvma/Adxvma.md b/lib/trends_IIR/adxvma/Adxvma.md index f15dd4e0..230bf6d1 100644 --- a/lib/trends_IIR/adxvma/Adxvma.md +++ b/lib/trends_IIR/adxvma/Adxvma.md @@ -1,4 +1,21 @@ -# ADXVMA: ADX Variable Moving Average +# ADXVMA: ADX Variable Moving Average + +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Trend (IIR MA) | +| **Inputs** | OHLCV bar (TBar) | +| **Parameters** | `period` (default 14) | +| **Outputs** | Single series (Adxvma) | +| **Output range** | Tracks input | +| **Warmup** | `period * 2` bars | + +### TL;DR + +- ADXVMA is an adaptive IIR filter that uses the Average Directional Index (ADX) as its smoothing constant. +- Parameterized by `period` (default 14). +- Output range: Tracks input. +- Requires `period * 2` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. > "Use ADX to measure trend strength, then feed that measurement back as the smoothing constant. When the trend is strong, track fast. When it is not, stand still. The market tells you how much to listen." diff --git a/lib/trends_IIR/ahrens/Ahrens.md b/lib/trends_IIR/ahrens/Ahrens.md index f03067ea..75f10b2c 100644 --- a/lib/trends_IIR/ahrens/Ahrens.md +++ b/lib/trends_IIR/ahrens/Ahrens.md @@ -1,4 +1,21 @@ -# AHRENS: Ahrens Moving Average +# AHRENS: Ahrens Moving Average + +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Trend (IIR MA) | +| **Inputs** | Source (close) | +| **Parameters** | `period` (default 9) | +| **Outputs** | Single series (Ahrens) | +| **Output range** | Tracks input | +| **Warmup** | `period` bars | + +### TL;DR + +- AHRENS is a recursive IIR filter that adjusts toward the source price minus the midpoint of its current and lagged (by one period) states. +- Parameterized by `period` (default 9). +- Output range: Tracks input. +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. > "Richard Ahrens looked at the EMA and thought: what if the correction term accounted for where the average was, not just where it is? The result is a self-referencing IIR filter that uses its own history as a stabilizer." diff --git a/lib/trends_IIR/coral/Coral.md b/lib/trends_IIR/coral/Coral.md index 81153c3d..90748536 100644 --- a/lib/trends_IIR/coral/Coral.md +++ b/lib/trends_IIR/coral/Coral.md @@ -1,4 +1,21 @@ -# CORAL — Coral Trend Filter +# CORAL — Coral Trend Filter + +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Trend (IIR MA) | +| **Inputs** | Source (close) | +| **Parameters** | `period`, `cd` (default 0.4) | +| **Outputs** | Single series (Coral) | +| **Output range** | Tracks input | +| **Warmup** | `period` bars | + +### TL;DR + +- The **Coral** filter is a smooth, low-lag trend indicator that chains six cascaded EMA passes and combines stages 3–6 using polynomial coefficients... +- Parameterized by `period`, `cd` (default 0.4). +- Output range: Tracks input. +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. ## Overview diff --git a/lib/trends_IIR/decycler/Decycler.md b/lib/trends_IIR/decycler/Decycler.md index 46c49d03..30ba0ead 100644 --- a/lib/trends_IIR/decycler/Decycler.md +++ b/lib/trends_IIR/decycler/Decycler.md @@ -1,5 +1,22 @@ # DECYCLER: Ehlers Decycler +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Trend (IIR MA) | +| **Inputs** | Source (close) | +| **Parameters** | `period` (default 60) | +| **Outputs** | Single series (Decycler) | +| **Output range** | Tracks input | +| **Warmup** | `period` bars | + +### TL;DR + +- The Ehlers Decycler extracts the trend component from a price series by subtracting a 2-pole Butterworth high-pass filter from the source signal. +- Parameterized by `period` (default 60). +- Output range: Tracks input. +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "The trend is what remains when you stop looking for cycles." The Ehlers Decycler extracts the trend component from a price series by subtracting a 2-pole Butterworth high-pass filter from the source signal. Where most moving averages blur the boundary between trend and cycle, the Decycler defines it with a frequency-domain cutoff: cycles shorter than the specified period are removed, everything longer stays. The result is an overlay that hugs price with near-zero lag during trends and rejects short-term oscillations without the smoothing artifacts of convolution-based averages. diff --git a/lib/trends_IIR/dema/Dema.md b/lib/trends_IIR/dema/Dema.md index 3ed0ea65..85ff22ff 100644 --- a/lib/trends_IIR/dema/Dema.md +++ b/lib/trends_IIR/dema/Dema.md @@ -1,5 +1,22 @@ # DEMA: Double Exponential Moving Average +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Trend (IIR MA) | +| **Inputs** | Source (close) | +| **Parameters** | `period` | +| **Outputs** | Single series (Dema) | +| **Output range** | Tracks input | +| **Warmup** | `period` bars | + +### TL;DR + +- DEMA (Double Exponential Moving Average) is not just "two EMAs." It's a clever mathematical hack to cancel out the lag inherent in a standard EMA. +- Parameterized by `period`. +- Output range: Tracks input. +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "EMA is good. DEMA is better. It's like an EMA that drank a double espresso and stopped lagging behind the conversation." DEMA (Double Exponential Moving Average) is not just "two EMAs." It's a clever mathematical hack to cancel out the lag inherent in a standard EMA. By subtracting the "error" (the difference between a single EMA and a double EMA) from the original EMA, DEMA produces a curve that hugs the price action much tighter. The extrapolation formula $2 \times \text{EMA}_1 - \text{EMA}_2$ effectively predicts where EMA "should be" based on its current trajectory. @@ -235,4 +252,4 @@ Both EMA states are rolled back atomically for consistent correction. ## References -- Mulloy, P. (1994). "Smoothing Data with Faster Moving Averages." *Technical Analysis of Stocks & Commodities*, 12(1), 11-19. \ No newline at end of file +- Mulloy, P. (1994). "Smoothing Data with Faster Moving Averages." *Technical Analysis of Stocks & Commodities*, 12(1), 11-19. diff --git a/lib/trends_IIR/dsma/Dsma.md b/lib/trends_IIR/dsma/Dsma.md index 7b1bdf9a..aefd9cea 100644 --- a/lib/trends_IIR/dsma/Dsma.md +++ b/lib/trends_IIR/dsma/Dsma.md @@ -1,5 +1,22 @@ # DSMA: Deviation-Scaled Moving Average +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Trend (IIR MA) | +| **Inputs** | Source (close) | +| **Parameters** | `period`, `scaleFactor` (default 0.5) | +| **Outputs** | Single series (Dsma) | +| **Output range** | Tracks input | +| **Warmup** | `period` bars | + +### TL;DR + +- DSMA (Deviation-Scaled Moving Average) is a volatility-adaptive trend filter that combines a Super Smoother (2-pole Butterworth IIR filter) with RM... +- Parameterized by `period`, `scalefactor` (default 0.5). +- Output range: Tracks input. +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "When the market screams, DSMA sprints. When it whispers, DSMA crawls. An adaptive moving average that lets volatility dictate the pace." DSMA (Deviation-Scaled Moving Average) is a volatility-adaptive trend filter that combines a Super Smoother (2-pole Butterworth IIR filter) with RMS-based deviation scaling. Unlike fixed-period moving averages that treat all market conditions identically, DSMA adjusts its responsiveness based on measured volatility—accelerating when trends are strong and decelerating when prices consolidate. @@ -238,4 +255,4 @@ The 2-pole IIR recursion and adaptive alpha dependency on running RMS preclude S 6. **Bar Correction**: Like all QuanTAlib indicators, DSMA supports bar correction via the `isNew` parameter. When `isNew = false`, it rolls back to the previous state before recalculating. Ensure your data feed correctly signals bar updates versus corrections. -7. **SIMD Limitation**: The recursive nature of the Super Smoother filter and adaptive alpha calculation precludes efficient SIMD vectorization. The `Calculate(Span)` method uses a scalar loop. For bulk backtesting, consider parallelizing across multiple series rather than within a single series. \ No newline at end of file +7. **SIMD Limitation**: The recursive nature of the Super Smoother filter and adaptive alpha calculation precludes efficient SIMD vectorization. The `Calculate(Span)` method uses a scalar loop. For bulk backtesting, consider parallelizing across multiple series rather than within a single series. diff --git a/lib/trends_IIR/ema/Ema.md b/lib/trends_IIR/ema/Ema.md index 6f3c5658..f9cb42ca 100644 --- a/lib/trends_IIR/ema/Ema.md +++ b/lib/trends_IIR/ema/Ema.md @@ -1,5 +1,22 @@ # EMA: Exponential Moving Average +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Trend (IIR MA) | +| **Inputs** | Source (close) | +| **Parameters** | `period` | +| **Outputs** | Single series (Ema) | +| **Output range** | Tracks input | +| **Warmup** | `period` bars | + +### TL;DR + +- The Exponential Moving Average is the reference standard for trend-following indicators. +- Parameterized by `period`. +- Output range: Tracks input. +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "The SMA drops an old price, the average jumps, the signal fires, the market does something unhelpful. The EMA exists because someone finally asked: what if old data just... mattered less?" The Exponential Moving Average is the reference standard for trend-following indicators. Unlike the SMA, which treats data from 10 days ago with the same reverence as data from 10 seconds ago (a touching but mathematically questionable form of loyalty), the EMA applies exponentially decaying weights to older prices. The result: faster reaction to new information without the "drop-off effect" that makes SMA users twitch nervously around window boundaries. Simple, well-understood, computationally cheap. The indicator equivalent of a reliable sedan: not glamorous, but it starts every morning. @@ -286,4 +303,4 @@ else - Hunter, J. S. (1986). "The Exponentially Weighted Moving Average." *Journal of Quality Technology*, 18(4), 203-210. - Roberts, S. W. (1959). "Control Chart Tests Based on Geometric Moving Averages." *Technometrics*, 1(3), 239-250. -- Ehlers, J. F. (2001). *Rocket Science for Traders*. John Wiley & Sons. Chapter 3: Smoothing. (The title oversells it slightly, but the content is solid.) \ No newline at end of file +- Ehlers, J. F. (2001). *Rocket Science for Traders*. John Wiley & Sons. Chapter 3: Smoothing. (The title oversells it slightly, but the content is solid.) diff --git a/lib/trends_IIR/frama/Frama.md b/lib/trends_IIR/frama/Frama.md index c7ce0865..102bfcb8 100644 --- a/lib/trends_IIR/frama/Frama.md +++ b/lib/trends_IIR/frama/Frama.md @@ -1,5 +1,22 @@ # FRAMA: Ehlers Fractal Adaptive Moving Average +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Trend (IIR MA) | +| **Inputs** | OHLCV bar (TBar) | +| **Parameters** | `period` | +| **Outputs** | Single series (Frama) | +| **Output range** | Tracks input | +| **Warmup** | `pe` bars | + +### TL;DR + +- FRAMA is John Ehlers' fractal adaptive moving average. +- Parameterized by `period`. +- Output range: Tracks input. +- Requires `pe` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "Markets do not move at one speed. FRAMA listens to the roughness and adjusts the filter." FRAMA is John Ehlers' fractal adaptive moving average. It estimates a fractal dimension from high and low ranges, then converts that dimension into a dynamic EMA alpha. The result is a moving average that tightens in trends and relaxes in noise. @@ -207,4 +224,4 @@ This approach is simple and cache-friendly for typical periods (10-50). Monotoni 1. **Period parity**: The algorithm requires even `N`. Odd values are rounded up. 2. **Warmup**: Outputs are `NaN` until `N` bars are available. 3. **Range source**: FRAMA uses High and Low ranges. Feeding Close-only data collapses the ranges. -4. **Bar correction**: Use `isNew=false` for corrections so the last bar is recomputed safely. \ No newline at end of file +4. **Bar correction**: Use `isNew=false` for corrections so the last bar is recomputed safely. diff --git a/lib/trends_IIR/gdema/Gdema.md b/lib/trends_IIR/gdema/Gdema.md index 53914d4c..0d354e1e 100644 --- a/lib/trends_IIR/gdema/Gdema.md +++ b/lib/trends_IIR/gdema/Gdema.md @@ -1,4 +1,21 @@ -# GDEMA: Generalized Double Exponential Moving Average +# GDEMA: Generalized Double Exponential Moving Average + +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Trend (IIR MA) | +| **Inputs** | Source (close) | +| **Parameters** | `period` (default 10), `vfactor` (default 1.0) | +| **Outputs** | Single series (Gdema) | +| **Output range** | Tracks input | +| **Warmup** | `period` bars | + +### TL;DR + +- GDEMA extends the standard DEMA (Double Exponential Moving Average) with a tunable gain factor $v$ that controls the aggressiveness of lag compensa... +- Parameterized by `period` (default 10), `vfactor` (default 1.0). +- Output range: Tracks input. +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. > "Patrick Mulloy created DEMA to cancel first-order lag. GDEMA adds a volume knob: turn it past 1 and you cancel more lag than Mulloy thought possible. Turn it to 0 and you are back to a plain EMA. The generalization is the point." diff --git a/lib/trends_IIR/hema/Hema.md b/lib/trends_IIR/hema/Hema.md index 1c86cdf9..44ff0df0 100644 --- a/lib/trends_IIR/hema/Hema.md +++ b/lib/trends_IIR/hema/Hema.md @@ -1,8 +1,26 @@ # HEMA: Hull Exponential Moving Average +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Trend (IIR MA) | +| **Inputs** | Source (close) | +| **Parameters** | `period` | +| **Outputs** | Single series (Hema) | +| **Output range** | Tracks input | +| **Warmup** | `EstimateWarmupPeriod()` bars | + +### TL;DR + +- HEMA is a Hull-style moving average built entirely from **exponential smoothers**. +- Parameterized by `period`. +- Output range: Tracks input. +- Requires `EstimateWarmupPeriod()` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + +> "HMA is a topology. HEMA keeps the topology and swaps the physics: windows to decay, with identical lag." + ## An EMA-domain analog of HMA with WMA-lag-matched alphas -> "HMA is a topology. HEMA keeps the topology and swaps the physics: windows to decay, with identical lag." HEMA is a Hull-style moving average built entirely from **exponential smoothers**. It preserves the classic HMA pipeline (fast minus slow, then smooth) but replaces WMA sub-filters with EMAs whose alphas are tuned to produce **identical lag** to the WMA stages they replace. At period $N$: HEMA($N$) and HMA($N$) have the same theoretical group delay, but HEMA has infinite memory and smoother transient behavior. diff --git a/lib/trends_IIR/holt/Holt.md b/lib/trends_IIR/holt/Holt.md index 0e180422..f3160052 100644 --- a/lib/trends_IIR/holt/Holt.md +++ b/lib/trends_IIR/holt/Holt.md @@ -1,4 +1,21 @@ -# HOLT: Holt Exponential Moving Average +# HOLT: Holt Exponential Moving Average + +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Trend (IIR MA) | +| **Inputs** | Source (close) | +| **Parameters** | `period`, `gamma` (default 0) | +| **Outputs** | Single series (HOLT) | +| **Output range** | Tracks input | +| **Warmup** | `period` bars | + +### TL;DR + +- Holt's exponential smoothing extends simple exponential smoothing (EMA) by adding a second equation that explicitly tracks the local trend. +- Parameterized by `period`, `gamma` (default 0). +- Output range: Tracks input. +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. > "Single smoothing tracks level. Double smoothing tracks trend. The elegance is not in complexity but in the admission that yesterday's direction matters." — Charles C. Holt (1957) diff --git a/lib/trends_IIR/htit/Htit.md b/lib/trends_IIR/htit/Htit.md index 4442b67b..80bfbbe9 100644 --- a/lib/trends_IIR/htit/Htit.md +++ b/lib/trends_IIR/htit/Htit.md @@ -1,5 +1,22 @@ # HTIT: Ehlers Hilbert Transform Instantaneous Trend (also known as HT_TRENDLINE) +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Trend (IIR MA) | +| **Inputs** | Source (close) | +| **Parameters** | None | +| **Outputs** | Single series (HTIT) | +| **Output range** | Tracks input | +| **Warmup** | `12` bars | + +### TL;DR + +- HTIT (Hilbert Transform Instantaneous Trend) is a trend-following indicator that doesn't rely on simple averaging. +- No configurable parameters; computation is stateless per bar. +- Output range: Tracks input. +- Requires `12` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "John Ehlers brought rocket science to trading. Literally. HTIT uses signal processing to find the trend by removing the cycle. It's not smoothing; it's extraction." HTIT (Hilbert Transform Instantaneous Trend) is a trend-following indicator that doesn't rely on simple averaging. Instead, it uses the Hilbert Transform to measure the dominant cycle period of the market and then computes a trendline that filters out that specific cycle. It adapts to the market's rhythm rather than imposing a fixed period. @@ -257,4 +274,4 @@ Uses `Math.Atan2` for proper quadrant handling in phase calculation, avoiding di 1. **Warmup**: This indicator needs significant warmup (at least 12 bars, ideally 50+) for the feedback loops (period smoothing) to stabilize. Don't trust the first 50 bars. 2. **Lag**: While it adapts, the trendline still lags because it's essentially a dynamic SMA. The advantage is that the period is optimal for the current market condition, not that it has zero lag. 3. **Complexity**: Debugging this is a nightmare. Trust the math. -4. **Ranging Markets**: In a pure range, the "trend" should be flat. HTIT handles this well because the cycle cancellation works best when the cycle is clear. \ No newline at end of file +4. **Ranging Markets**: In a pure range, the "trend" should be flat. HTIT handles this well because the cycle cancellation works best when the cycle is clear. diff --git a/lib/trends_IIR/hwma/Hwma.md b/lib/trends_IIR/hwma/Hwma.md index a4397a91..687de89d 100644 --- a/lib/trends_IIR/hwma/Hwma.md +++ b/lib/trends_IIR/hwma/Hwma.md @@ -1,5 +1,22 @@ # HWMA: Holt-Winters Moving Average +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Trend (IIR MA) | +| **Inputs** | Source (close) | +| **Parameters** | `period` (default 10) | +| **Outputs** | Single series (Hwma) | +| **Output range** | Tracks input | +| **Warmup** | `period` bars | + +### TL;DR + +- HWMA is an Infinite Impulse Response (IIR) filter that applies triple exponential smoothing with level (F), velocity (V), and acceleration (A) comp... +- Parameterized by `period` (default 10). +- Output range: Tracks input. +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "Triple exponential smoothing: because sometimes tracking level, velocity, and acceleration is exactly what a price series needs—and sometimes it's overkill. Holt and Winters figured this out for inventory forecasting in the 1950s. Traders rediscovered it decades later." HWMA is an Infinite Impulse Response (IIR) filter that applies triple exponential smoothing with level (F), velocity (V), and acceleration (A) components. Unlike simple exponential smoothing which only tracks the current level, HWMA anticipates future values by extrapolating trend and trend changes. @@ -236,4 +253,4 @@ HWMA has constant memory regardless of period—approximately **142 bytes** per 5. **Seasonal Confusion**: "Holt-Winters" often implies seasonal decomposition. This implementation is the non-seasonal variant focusing on level-trend-acceleration only. -6. **Parameter Sensitivity**: Small changes in β and γ significantly affect behavior. Start with the default period-based derivation before experimenting with custom values. \ No newline at end of file +6. **Parameter Sensitivity**: Small changes in β and γ significantly affect behavior. Start with the default period-based derivation before experimenting with custom values. diff --git a/lib/trends_IIR/jma/Jma.md b/lib/trends_IIR/jma/Jma.md index 9eb91d4f..c939cc2c 100644 --- a/lib/trends_IIR/jma/Jma.md +++ b/lib/trends_IIR/jma/Jma.md @@ -1,5 +1,22 @@ # JMA: Jurik Moving Average +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Trend (IIR MA) | +| **Inputs** | Source (close) | +| **Parameters** | `period`, `phase` (default 0), `power` (default 0.45) | +| **Outputs** | Single series (Jma) | +| **Output range** | $-100$ to $+100$ | +| **Warmup** | 1 bar | + +### TL;DR + +- JMA (Jurik Moving Average) is Mark Jurik's flagship adaptive smoother, recovered through decompilation of his proprietary AmiBroker/MetaTrader bina... +- Parameterized by `period`, `phase` (default 0), `power` (default 0.45). +- Output range: $-100$ to $+100$. +- Requires 1 bar of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "The spectral approach isn't marketing. It's the difference between guessing at volatility and measuring it." JMA (Jurik Moving Average) is Mark Jurik's flagship adaptive smoother, recovered through decompilation of his proprietary AmiBroker/MetaTrader binaries. Unlike forum-sourced approximations that use exponential volatility smoothing, this implementation maintains a 128-bar volatility distribution and applies percentile trimming to derive a robust reference. The result: identical behavior to Jurik's commercial software within floating-point tolerance, including spike rejection during 3-sigma events where approximations diverge by 3-4%. @@ -356,4 +373,4 @@ All hot-path methods are decorated with `[MethodImpl(MethodImplOptions.Aggressiv ## References - Jurik Research. (1998-2005). "JMA White Papers." *jurikres.com* (archived). -- Kositsin, Nikolay. (2007). "Digital Indicators for MetaTrader 4." *Alpari Forum Archives*. \ No newline at end of file +- Kositsin, Nikolay. (2007). "Digital Indicators for MetaTrader 4." *Alpari Forum Archives*. diff --git a/lib/trends_IIR/kama/Kama.md b/lib/trends_IIR/kama/Kama.md index e2ce318e..49cab7c1 100644 --- a/lib/trends_IIR/kama/Kama.md +++ b/lib/trends_IIR/kama/Kama.md @@ -1,5 +1,22 @@ # KAMA: Kaufman's Adaptive Moving Average +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Trend (IIR MA) | +| **Inputs** | Source (close) | +| **Parameters** | `period` (default 10), `fastPeriod` (default 2), `slowPeriod` (default 30) | +| **Outputs** | Single series (Kama) | +| **Output range** | Tracks input | +| **Warmup** | `period + 1` bars | + +### TL;DR + +- KAMA (Kaufman's Adaptive Moving Average) is an intelligent moving average that adjusts its smoothing speed based on market noise. +- Parameterized by `period` (default 10), `fastperiod` (default 2), `slowperiod` (default 30). +- Output range: Tracks input. +- Requires `period + 1` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "Perry Kaufman asked a simple question: 'Why should I use the same smoothing in a trending market as in a chopping market?' KAMA is the answer." KAMA (Kaufman's Adaptive Moving Average) is an intelligent moving average that adjusts its smoothing speed based on market noise. When the price is moving steadily (high signal-to-noise ratio), KAMA speeds up to capture the trend. When the price is chopping sideways (low signal-to-noise ratio), KAMA slows down to filter out the noise. @@ -199,4 +216,4 @@ The epsilon guard (1e-10) prevents division by zero in flat markets, while the E 1. **Flatlining**: In very choppy markets, KAMA can become almost horizontal. This is a feature, not a bug—it's telling you to stay out. 2. **Parameters**: The standard settings are (10, 2, 30). 10 is the ER period, 2 is the fast EMA, 30 is the slow EMA. Tweaking the ER period changes the sensitivity to noise. -3. **Trend Following**: KAMA is excellent for trailing stops because it flattens out when momentum stalls. \ No newline at end of file +3. **Trend Following**: KAMA is excellent for trailing stops because it flattens out when momentum stalls. diff --git a/lib/trends_IIR/lema/Lema.md b/lib/trends_IIR/lema/Lema.md index 1da70d4a..bd209a97 100644 --- a/lib/trends_IIR/lema/Lema.md +++ b/lib/trends_IIR/lema/Lema.md @@ -1,4 +1,21 @@ -# LEMA: Leader Exponential Moving Average +# LEMA: Leader Exponential Moving Average + +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Trend (IIR MA) | +| **Inputs** | Source (close) | +| **Parameters** | `period` | +| **Outputs** | Single series (Lema) | +| **Output range** | Tracks input | +| **Warmup** | `period` bars | + +### TL;DR + +- LEMA (Leader EMA) adds a smoothed error correction to the standard EMA, creating a moving average that anticipates price movement. +- Parameterized by `period`. +- Output range: Tracks input. +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. > "George Siligardos asked a simple question: what if you smoothed the EMA's own error and added it back? The answer is a moving average that leads price changes instead of lagging behind them. The error becomes the signal." diff --git a/lib/trends_IIR/mama/Mama.md b/lib/trends_IIR/mama/Mama.md index 60099fa7..e7655e34 100644 --- a/lib/trends_IIR/mama/Mama.md +++ b/lib/trends_IIR/mama/Mama.md @@ -1,5 +1,22 @@ # MAMA: Ehlers MESA Adaptive Moving Average +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Trend (IIR MA) | +| **Inputs** | Source (close) | +| **Parameters** | `fastLimit` (default 0.5), `slowLimit` (default 0.05) | +| **Outputs** | Single series (Mama) | +| **Output range** | Tracks input | +| **Warmup** | `50` bars | + +### TL;DR + +- MAMA (MESA Adaptive Moving Average) is a unique adaptive moving average that uses the Hilbert Transform to determine the phase rate of change of th... +- Parameterized by `fastlimit` (default 0.5), `slowlimit` (default 0.05). +- Output range: Tracks input. +- Requires `50` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "John Ehlers again. This time, he built a moving average that doesn't just adapt to volatility—it adapts to the phase of the market cycle. It's like having a GPS for your trend." MAMA (MESA Adaptive Moving Average) is a unique adaptive moving average that uses the Hilbert Transform to determine the phase rate of change of the market cycle. It produces two outputs: MAMA (the adaptive average) and FAMA (Following Adaptive Moving Average), which acts as a slower, confirming signal. @@ -341,4 +358,4 @@ MAMA works best when combined with indicators that cover its blind spots: 5. **Precision Expectations**: Don't expect your MAMA to match TradingView or TA-Lib to the sixth decimal. It won't. Those implementations have accumulated rounding errors from 20 years of cargo-cult porting. Your values will be more accurate but numerically different. If this breaks your backtests, the backtests were fragile. -6. **Ignoring the Alpha Output**: Many traders only look at MAMA and FAMA values. The adaptive alpha itself is valuable information—it tells you how confident MAMA is in its cycle estimate. High alpha (near FastLimit) means rapid phase change and uncertainty. Low alpha (near SlowLimit) means stable, established trend. \ No newline at end of file +6. **Ignoring the Alpha Output**: Many traders only look at MAMA and FAMA values. The adaptive alpha itself is valuable information—it tells you how confident MAMA is in its cycle estimate. High alpha (near FastLimit) means rapid phase change and uncertainty. Low alpha (near SlowLimit) means stable, established trend. diff --git a/lib/trends_IIR/mavp/Mavp.md b/lib/trends_IIR/mavp/Mavp.md index 2f640432..68de1a97 100644 --- a/lib/trends_IIR/mavp/Mavp.md +++ b/lib/trends_IIR/mavp/Mavp.md @@ -1,5 +1,22 @@ # MAVP: Moving Average Variable Period +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Trend (IIR MA) | +| **Inputs** | Source (close) | +| **Parameters** | `minPeriod` (default 2), `maxPeriod` (default 30) | +| **Outputs** | Single series (Mavp) | +| **Output range** | Tracks input | +| **Warmup** | `maxPeriod` bars | + +### TL;DR + +- MAVP applies an EMA-style exponential smoothing where the period -- and therefore the smoothing constant alpha -- changes on every bar. +- Parameterized by `minperiod` (default 2), `maxperiod` (default 30). +- Output range: Tracks input. +- Requires `maxPeriod` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "You can't fix your moving average period because the market doesn't run at a fixed frequency. MAVP stops pretending it does." ## Introduction diff --git a/lib/trends_IIR/mcnma/Mcnma.md b/lib/trends_IIR/mcnma/Mcnma.md index af974832..50f8732d 100644 --- a/lib/trends_IIR/mcnma/Mcnma.md +++ b/lib/trends_IIR/mcnma/Mcnma.md @@ -1,4 +1,21 @@ -# MCNMA: McNicholl EMA (Zero-Lag TEMA) +# MCNMA: McNicholl EMA (Zero-Lag TEMA) + +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Trend (IIR MA) | +| **Inputs** | Source (close) | +| **Parameters** | `period` | +| **Outputs** | Single series (Mcnma) | +| **Output range** | Tracks input | +| **Warmup** | `period` bars | + +### TL;DR + +- MCNMA computes $2 \times \text{TEMA}(x, N) - \text{TEMA}(\text{TEMA}(x, N), N)$, applying the DEMA lag-cancellation technique to TEMA itself. +- Parameterized by `period`. +- Output range: Tracks input. +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. > "Dennis McNicholl applied TEMA to itself and subtracted the result, producing six cascaded EMA stages that cancel lag through three layers of triple-smoothing. When single TEMA is not enough, double it." diff --git a/lib/trends_IIR/mgdi/Mgdi.md b/lib/trends_IIR/mgdi/Mgdi.md index 83bf1ed2..40b9453d 100644 --- a/lib/trends_IIR/mgdi/Mgdi.md +++ b/lib/trends_IIR/mgdi/Mgdi.md @@ -1,5 +1,22 @@ # MGDI: McGinley Dynamic Indicator +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Trend (IIR MA) | +| **Inputs** | Source (close) | +| **Parameters** | `period` (default 14), `k` (default 0.6) | +| **Outputs** | Single series (Mgdi) | +| **Output range** | Tracks input | +| **Warmup** | `period` bars | + +### TL;DR + +- MGDI (McGinley Dynamic Indicator) looks like a moving average but operates on a fundamentally different principle. +- Parameterized by `period` (default 14), `k` (default 0.6). +- Output range: Tracks input. +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "John McGinley saw moving averages failing in fast markets and said, 'It's not the market's fault, it's the math's fault.' MGDI is the apology." MGDI (McGinley Dynamic Indicator) looks like a moving average but operates on a fundamentally different principle. Rather than using a fixed smoothing factor, it dynamically adjusts based on the ratio between price and the indicator's current value. The result is a filter that accelerates to catch breakouts while decelerating to avoid overshooting reversals—a behavior that fixed-alpha filters cannot achieve. @@ -148,4 +165,4 @@ MGDI is inherently recursive (each value depends on the previous), limiting SIMD ## References -- McGinley, J.R. (1991). "The McGinley Dynamic." *Market Technicians Association Journal*, Fall 1991. \ No newline at end of file +- McGinley, J.R. (1991). "The McGinley Dynamic." *Market Technicians Association Journal*, Fall 1991. diff --git a/lib/trends_IIR/mma/Mma.md b/lib/trends_IIR/mma/Mma.md index e67e0ffb..bd2da2e5 100644 --- a/lib/trends_IIR/mma/Mma.md +++ b/lib/trends_IIR/mma/Mma.md @@ -1,5 +1,22 @@ # MMA: Modified Moving Average +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Trend (IIR MA) | +| **Inputs** | Source (close) | +| **Parameters** | `period` | +| **Outputs** | Single series (Mma) | +| **Output range** | Tracks input | +| **Warmup** | `period` bars | + +### TL;DR + +- MMA (Modified Moving Average) uses a **simple mean** as a baseline, then adds a **weighted correction** based on the position of values within the ... +- Parameterized by `period`. +- Output range: Tracks input. +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "MMA is a compromise: less lag than SMA, less overshoot than fully weighted filters. It's what you get when an SMA and a WMA have a carefully engineered offspring." MMA (Modified Moving Average) uses a **simple mean** as a baseline, then adds a **weighted correction** based on the position of values within the buffer. The weighting tilts toward newer bars without fully discarding older ones, creating a filter that sits between SMA (equal weights) and WMA (linear weights) in both lag and smoothness characteristics. @@ -158,4 +175,4 @@ The weighted sum computation is vectorizable: ## References -- PineScript reference implementation: `lib/trends_IIR/mma/mma.pine` \ No newline at end of file +- PineScript reference implementation: `lib/trends_IIR/mma/mma.pine` diff --git a/lib/trends_IIR/nma/Nma.md b/lib/trends_IIR/nma/Nma.md index 5ce92c44..b87f70f0 100644 --- a/lib/trends_IIR/nma/Nma.md +++ b/lib/trends_IIR/nma/Nma.md @@ -1,5 +1,22 @@ # NMA: Natural Moving Average +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Trend (IIR MA) | +| **Inputs** | Source (close) | +| **Parameters** | `period` | +| **Outputs** | Single series (Nma) | +| **Output range** | Tracks input | +| **Warmup** | `period` bars | + +### TL;DR + +- NMA is an adaptive IIR filter whose smoothing ratio is derived from a volatility-weighted square-root kernel analysis of log-price movements over a... +- Parameterized by `period`. +- Output range: Tracks input. +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "Jim Sloman looked at how volatility distributes across a window and asked: if the most volatile bars are recent, should the filter not respond faster? NMA derives its smoothing constant from the volatility profile itself, weighted by a square-root kernel that emphasizes recent action." NMA is an adaptive IIR filter whose smoothing ratio is derived from a volatility-weighted square-root kernel analysis of log-price movements over a lookback window. When volatility concentrates in recent bars, the ratio approaches 1.0 (fast tracking). When volatility is spread uniformly, the ratio approaches $1/\sqrt{N}$ (heavy smoothing). The square-root kernel $(\sqrt{i+1} - \sqrt{i})$ gives a concave-down weighting that gently emphasizes recency, while the log-price transformation normalizes for price level, making the adaptation scale-invariant. diff --git a/lib/trends_IIR/qema/Qema.md b/lib/trends_IIR/qema/Qema.md index 00ea0212..d930ed65 100644 --- a/lib/trends_IIR/qema/Qema.md +++ b/lib/trends_IIR/qema/Qema.md @@ -1,4 +1,21 @@ -# QEMA: Quad Exponential Moving Average +# QEMA: Quad Exponential Moving Average + +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Trend (IIR MA) | +| **Inputs** | Source (close) | +| **Parameters** | `period` | +| **Outputs** | Single series (Qema) | +| **Output range** | Tracks input | +| **Warmup** | `period` bars | + +### TL;DR + +- QEMA (Quad Exponential Moving Average) is a zero-lag smoothing filter that cascades four EMAs with geometrically ramped alphas and combines them us... +- Parameterized by `period`. +- Output range: Tracks input. +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. > "Four EMAs walk into a bar. The first one's slow and thoughtful. The fourth one's practically twitching. Together, they somehow produce a signal that's both smooth and responsive. The bartender asks, 'How did you achieve zero lag?' They reply, 'Constrained quadratic optimization.' The bartender pours them a free drink." diff --git a/lib/trends_IIR/rema/Rema.md b/lib/trends_IIR/rema/Rema.md index f41e80c9..9466d530 100644 --- a/lib/trends_IIR/rema/Rema.md +++ b/lib/trends_IIR/rema/Rema.md @@ -1,5 +1,22 @@ # REMA: Regularized Exponential Moving Average +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Trend (IIR MA) | +| **Inputs** | Source (close) | +| **Parameters** | `period`, `lambda` (default 0.5) | +| **Outputs** | Single series (Rema) | +| **Output range** | Tracks input | +| **Warmup** | `period` bars | + +### TL;DR + +- REMA (Regularized Exponential Moving Average) combines exponential smoothing with a regularization term that penalizes deviations from the previous... +- Parameterized by `period`, `lambda` (default 0.5). +- Output range: Tracks input. +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "Someone looked at the EMA and thought: 'What if we punished it for changing its mind?' The result is REMA—an EMA with a conscience that remembers where it was going and resists the temptation to chase every price wiggle." REMA (Regularized Exponential Moving Average) combines exponential smoothing with a regularization term that penalizes deviations from the previous trend direction. The result is a filter that responds to genuine price movements while suppressing noise-induced oscillations. Think of it as an EMA with momentum awareness: it knows where it was heading and applies a penalty for sudden course corrections. @@ -194,4 +211,4 @@ REMA is ideal when: REMA is less suitable when: - You need maximum responsiveness (use EMA instead) - You're comparing against external libraries that don't implement REMA -- You need predictable, standardized behavior across platforms \ No newline at end of file +- You need predictable, standardized behavior across platforms diff --git a/lib/trends_IIR/rgma/Rgma.md b/lib/trends_IIR/rgma/Rgma.md index f7ff5a7e..0de3a520 100644 --- a/lib/trends_IIR/rgma/Rgma.md +++ b/lib/trends_IIR/rgma/Rgma.md @@ -1,5 +1,22 @@ # RGMA: Recursive Gaussian Moving Average +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Trend (IIR MA) | +| **Inputs** | Source (close) | +| **Parameters** | `period`, `passes` (default 3) | +| **Outputs** | Single series (Rgma) | +| **Output range** | Tracks input | +| **Warmup** | `period` bars | + +### TL;DR + +- RGMA (Recursive Gaussian Moving Average) approximates Gaussian smoothing by cascading multiple identical exponential moving averages. +- Parameterized by `period`, `passes` (default 3). +- Output range: Tracks input. +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "The statisticians wanted Gaussian smoothing. The HFT folks wanted O(1) updates. RGMA splits the difference: chain enough cheap EMAs together and the impulse response starts looking suspiciously bell-shaped. It's not real Gaussian—but the market doesn't know that." RGMA (Recursive Gaussian Moving Average) approximates Gaussian smoothing by cascading multiple identical exponential moving averages. Each pass through an EMA filter smooths the signal further, and the mathematical magic is that cascaded low-pass filters push the impulse response toward a Gaussian-like shape. You get the desirable properties of Gaussian smoothing—smooth frequency roll-off, minimal ringing, symmetric lag—without the computational cost of a true FIR convolution. @@ -214,4 +231,4 @@ RGMA is less suitable when: ## References - TradingView reference implementation: `lib/trends_IIR/rgma/rgma.pine` -- Central Limit Theorem and cascaded filter theory: Smith, S.W. *The Scientist and Engineer's Guide to Digital Signal Processing*, Chapter 15 \ No newline at end of file +- Central Limit Theorem and cascaded filter theory: Smith, S.W. *The Scientist and Engineer's Guide to Digital Signal Processing*, Chapter 15 diff --git a/lib/trends_IIR/rma/Rma.md b/lib/trends_IIR/rma/Rma.md index 1c44dab7..c7145b67 100644 --- a/lib/trends_IIR/rma/Rma.md +++ b/lib/trends_IIR/rma/Rma.md @@ -1,5 +1,22 @@ # RMA: Running Moving Average +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Trend (IIR MA) | +| **Inputs** | Source (close) | +| **Parameters** | `period` | +| **Outputs** | Single series (Rma) | +| **Output range** | Tracks input | +| **Warmup** | `ema.WarmupPeriod` bars | + +### TL;DR + +- The Running Moving Average (RMA), also known as the Smoothed Moving Average (SMMA) or Wilder's Moving Average, is the backbone of J. +- Parameterized by `period`. +- Output range: Tracks input. +- Requires `ema.WarmupPeriod` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "Wilder didn't like standard EMA weighting. He wanted history to decay slower. So he invented RMA, which is just EMA with a different alpha, confusing traders for 40 years." The Running Moving Average (RMA), also known as the Smoothed Moving Average (SMMA) or Wilder's Moving Average, is the backbone of J. Welles Wilder's most famous indicators: RSI, ATR, and ADX. It is functionally identical to an Exponential Moving Average (EMA), but with a smoothing factor ($\alpha$) of $1/N$ instead of $2/(N+1)$. This results in a longer "memory" and slower decay than a standard EMA of the same period. @@ -94,4 +111,4 @@ Validated against Skender and Ooples. 1. **Initialization**: Like EMA, RMA requires a "warmup" period to converge. Wilder often initialized with a Simple Moving Average (SMA) of the first $N$ bars. QuanTAlib follows this convention. 2. **Naming**: Often called SMMA (Smoothed Moving Average) in other libraries. -3. **Period Mismatch**: Using an EMA(14) where an RMA(14) is expected will result in a much faster-moving line (equivalent to RMA(7.5)). \ No newline at end of file +3. **Period Mismatch**: Using an EMA(14) where an RMA(14) is expected will result in a much faster-moving line (equivalent to RMA(7.5)). diff --git a/lib/trends_IIR/t3/T3.md b/lib/trends_IIR/t3/T3.md index fb565f94..d94d8fc6 100644 --- a/lib/trends_IIR/t3/T3.md +++ b/lib/trends_IIR/t3/T3.md @@ -1,5 +1,22 @@ # T3: Tillson T3 Moving Average +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Trend (IIR MA) | +| **Inputs** | Source (close) | +| **Parameters** | `period`, `vfactor` (default 0.7) | +| **Outputs** | Single series (T3) | +| **Output range** | Tracks input | +| **Warmup** | `period * 6` bars | + +### TL;DR + +- The T3 Moving Average is a hyper-smooth, low-lag filter that cascades six Exponential Moving Averages (EMAs). +- Parameterized by `period`, `vfactor` (default 0.7). +- Output range: Tracks input. +- Requires `period * 6` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "If one EMA is good, six must be better. Tim Tillson's logic is impeccable, provided you hate noise more than you love latency." The T3 Moving Average is a hyper-smooth, low-lag filter that cascades six Exponential Moving Averages (EMAs). Unlike standard cascading (which increases lag), T3 uses a "Volume Factor" ($v$) to weight the EMAs in a way that partially cancels out the lag, resulting in a curve that is smoother than an EMA but more responsive than an SMA. @@ -99,4 +116,4 @@ T3 is inherently recursive due to 6 cascaded EMAs. SIMD parallelization across b 1. **Warmup**: Because it cascades 6 EMAs, T3 takes significantly longer to stabilize than a standard EMA. A T3(10) might need 60+ bars to converge. 2. **Overshoot**: With high $v$ values ($>1$), T3 can overshoot price turns, creating false breakout signals. -3. **Complexity**: It is computationally heavier than SMA or EMA (approx 6x ops), though still negligible on modern CPUs. \ No newline at end of file +3. **Complexity**: It is computationally heavier than SMA or EMA (approx 6x ops), though still negligible on modern CPUs. diff --git a/lib/trends_IIR/tema/Tema.md b/lib/trends_IIR/tema/Tema.md index 88184db8..8d107789 100644 --- a/lib/trends_IIR/tema/Tema.md +++ b/lib/trends_IIR/tema/Tema.md @@ -1,5 +1,22 @@ # TEMA: Triple Exponential Moving Average +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Trend (IIR MA) | +| **Inputs** | Source (close) | +| **Parameters** | `period` | +| **Outputs** | Single series (Tema) | +| **Output range** | Tracks input | +| **Warmup** | `period * 3` bars | + +### TL;DR + +- The Triple Exponential Moving Average (TEMA) is a lag-reducing filter that combines a single, double, and triple EMA. +- Parameterized by `period`. +- Output range: Tracks input. +- Requires `period * 3` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "Patrick Mulloy looked at the lag of an EMA and took it personally. TEMA is what happens when you apply algebra to impatience." The Triple Exponential Moving Average (TEMA) is a lag-reducing filter that combines a single, double, and triple EMA. Unlike a simple triple smoothing (which would be incredibly slow), TEMA uses a weighted combination of the three to cancel out the lag, resulting in an indicator that hugs price action tighter than a spandex cycling short. @@ -165,4 +182,4 @@ Each EmaState contains: Ema (8B), E (8B), IsHot (1B), IsCompensated (1B) + paddi 1. **Overshoot**: TEMA is so responsive it can overshoot price turns, creating a "whiplash" effect in volatile markets. 2. **Noise**: By reducing lag, TEMA sacrifices some noise suppression. It is "nervous" compared to an SMA. -3. **Identity Crisis**: Often confused with T3 (Tillson). T3 is a generalized version; TEMA is specifically T3 with $v=1$. \ No newline at end of file +3. **Identity Crisis**: Often confused with T3 (Tillson). T3 is a generalized version; TEMA is specifically T3 with $v=1$. diff --git a/lib/trends_IIR/trama/Trama.md b/lib/trends_IIR/trama/Trama.md index b495de79..6c26c6b0 100644 --- a/lib/trends_IIR/trama/Trama.md +++ b/lib/trends_IIR/trama/Trama.md @@ -1,5 +1,22 @@ # TRAMA: Trend Regularity Adaptive Moving Average +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Trend (IIR MA) | +| **Inputs** | Source (close) | +| **Parameters** | `period` | +| **Outputs** | Single series (Trama) | +| **Output range** | Tracks input | +| **Warmup** | `period` bars | + +### TL;DR + +- TRAMA is an adaptive EMA where the smoothing factor derives from the "trend regularity" of the lookback window, measured as the fraction of bars th... +- Parameterized by `period`. +- Output range: Tracks input. +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "LuxAlgo counted how often price makes new highs and new lows within a window, squared that fraction, and used it as an EMA smoothing constant. Trending markets produce frequent HH/LLs and the filter tracks fast. Ranging markets produce few, and the filter stops moving. Simple, effective, elegant." TRAMA is an adaptive EMA where the smoothing factor derives from the "trend regularity" of the lookback window, measured as the fraction of bars that produce either a new highest-high (HH) or a new lowest-low (LL). This fraction is squared to create a convex penalty: low regularity (ranging) produces near-zero smoothing (filter barely moves), while high regularity (trending) produces aggressive smoothing (filter tracks closely). Developed by LuxAlgo (TradingView, December 2020). diff --git a/lib/trends_IIR/vama/Vama.md b/lib/trends_IIR/vama/Vama.md index 29cea57e..824c9932 100644 --- a/lib/trends_IIR/vama/Vama.md +++ b/lib/trends_IIR/vama/Vama.md @@ -1,5 +1,22 @@ # VAMA: Volatility Adjusted Moving Average +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Trend (IIR MA) | +| **Inputs** | OHLCV bar (TBar) | +| **Parameters** | `baseLength` (default 20), `shortAtrPeriod` (default 10), `longAtrPeriod` (default 50), `minLength` (default 5), `maxLength` (default 100) | +| **Outputs** | Single series (Vama) | +| **Output range** | Tracks input | +| **Warmup** | 1 bar | + +### TL;DR + +- Most moving averages use a fixed lookback period. +- Parameterized by `baselength` (default 20), `shortatrperiod` (default 10), `longatrperiod` (default 50), `minlength` (default 5), `maxlength` (default 100). +- Output range: Tracks input. +- Requires 1 bar of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "The market doesn't care about your moving average period. VAMA returns the favor by not caring about a fixed period either." ## The Core Insight @@ -271,4 +288,4 @@ VAMA's ATR-based approach specifically responds to range expansion/contraction, ## References - Wilder, J.W. (1978). "New Concepts in Technical Trading Systems" - ATR and RMA foundations -- PineScript reference implementation: `vama.pine` \ No newline at end of file +- PineScript reference implementation: `vama.pine` diff --git a/lib/trends_IIR/vidya/Vidya.md b/lib/trends_IIR/vidya/Vidya.md index 5dd151f9..64ec703f 100644 --- a/lib/trends_IIR/vidya/Vidya.md +++ b/lib/trends_IIR/vidya/Vidya.md @@ -1,5 +1,22 @@ # VIDYA: Variable Index Dynamic Average +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Trend (IIR MA) | +| **Inputs** | Source (close) | +| **Parameters** | `period` | +| **Outputs** | Single series (Vidya) | +| **Output range** | Tracks input | +| **Warmup** | `period` bars | + +### TL;DR + +- The Variable Index Dynamic Average (VIDYA) is an adaptive moving average that automatically adjusts its smoothing speed based on market volatility. +- Parameterized by `period`. +- Output range: Tracks input. +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "Tushar Chande asked: 'Why should I trust a moving average that treats a market crash the same as a lunch break?' VIDYA is the answer." The Variable Index Dynamic Average (VIDYA) is an adaptive moving average that automatically adjusts its smoothing speed based on market volatility. When the market is trending (high volatility), VIDYA speeds up to capture the move. When the market is ranging (low volatility), it slows down to filter out the noise. @@ -100,4 +117,4 @@ VIDYA is an IIR filter with CMO-driven adaptive alpha — not vectorizable acros 1. **Flatlining**: In extremely choppy, sideways markets, CMO can approach 0, causing VIDYA to flatline completely. This is a feature, not a bug. 2. **Sensitivity**: VIDYA is highly sensitive to the period chosen for the CMO. A short period makes it jittery; a long period makes it sluggish. -3. **Comparison**: Often compared to KAMA (Kaufman). KAMA uses Efficiency Ratio (ER); VIDYA uses CMO. They are conceptually similar but mathematically distinct. \ No newline at end of file +3. **Comparison**: Often compared to KAMA (Kaufman). KAMA uses Efficiency Ratio (ER); VIDYA uses CMO. They are conceptually similar but mathematically distinct. diff --git a/lib/trends_IIR/yzvama/Yzvama.md b/lib/trends_IIR/yzvama/Yzvama.md index fc7955d9..0fa9b056 100644 --- a/lib/trends_IIR/yzvama/Yzvama.md +++ b/lib/trends_IIR/yzvama/Yzvama.md @@ -1,5 +1,22 @@ # YZVAMA: Yang-Zhang Volatility Adjusted Moving Average +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Trend (IIR MA) | +| **Inputs** | OHLCV bar (TBar) | +| **Parameters** | `yzvShortPeriod` (default 3), `yzvLongPeriod` (default 50), `percentileLookback` (default 100), `minLength` (default 5), `maxLength` (default 100) | +| **Outputs** | Single series (Yzvama) | +| **Output range** | Tracks input | +| **Warmup** | 1 bar | + +### TL;DR + +- Most adaptive moving averages measure volatility using close-to-close changes (standard deviation) or high-low ranges (ATR). +- Parameterized by `yzvshortperiod` (default 3), `yzvlongperiod` (default 50), `percentilelookback` (default 100), `minlength` (default 5), `maxlength` (default 100). +- Output range: Tracks input. +- Requires 1 bar of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "ATR tells you how much the market moved. Yang-Zhang tells you how much it *should* have moved given the gaps and intrabar action. YZVAMA uses that distinction to know when the market is lying about its volatility." ## The Core Insight @@ -411,4 +428,4 @@ Percentile ranking solves both: - Yang, D., & Zhang, Q. (2000). "Drift-Independent Volatility Estimation Based on High, Low, Open, and Close Prices." *Journal of Business*, 73(3), 477-491. - Rogers, L.C.G., & Satchell, S.E. (1991). "Estimating Variance from High, Low and Closing Prices." *Annals of Applied Probability*, 1(4), 504-512. -- PineScript reference implementation: `yzvama.pine` \ No newline at end of file +- PineScript reference implementation: `yzvama.pine` diff --git a/lib/trends_IIR/zldema/Zldema.md b/lib/trends_IIR/zldema/Zldema.md index 9e1ad48a..0ba8c496 100644 --- a/lib/trends_IIR/zldema/Zldema.md +++ b/lib/trends_IIR/zldema/Zldema.md @@ -1,8 +1,26 @@ # ZLDEMA: Zero-Lag Double Exponential Moving Average +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Trend (IIR MA) | +| **Inputs** | Source (close) | +| **Parameters** | `period` | +| **Outputs** | Single series (Zldema) | +| **Output range** | Tracks input | +| **Warmup** | `Math.Max(lag + 1, EstimateWarmupPeriod(beta))` bars | + +### TL;DR + +- ZLDEMA takes a standard DEMA and feeds it a **zero-lag signal**: current price minus a lagged price. +- Parameterized by `period`. +- Output range: Tracks input. +- Requires `Math.Max(lag + 1, EstimateWarmupPeriod(beta))` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + +> "ZLDEMA combines the speed of zero-lag prediction with the smoothness of double exponential averaging. You get faster response than ZLEMA, with better trend-following than DEMA." + ## DEMA with lag compensation via a zero-lag signal -> "ZLDEMA combines the speed of zero-lag prediction with the smoothness of double exponential averaging. You get faster response than ZLEMA, with better trend-following than DEMA." ZLDEMA takes a standard DEMA and feeds it a **zero-lag signal**: current price minus a lagged price. This produces a smoother that responds faster than DEMA without going fully raw. The dual EMA cascade provides additional noise rejection while the zero-lag preprocessing maintains responsiveness. @@ -146,4 +164,4 @@ ZLDEMA is validated against a PineScript reference implementation. 5. **DEMA vs ZLDEMA** - ZLDEMA is not simply DEMA with a different alpha. The zero-lag preprocessing fundamentally changes the input signal, making ZLDEMA more responsive but also more prone to overshoot than standard DEMA. \ No newline at end of file + ZLDEMA is not simply DEMA with a different alpha. The zero-lag preprocessing fundamentally changes the input signal, making ZLDEMA more responsive but also more prone to overshoot than standard DEMA. diff --git a/lib/trends_IIR/zlema/Zlema.md b/lib/trends_IIR/zlema/Zlema.md index 2c9bad00..698caa03 100644 --- a/lib/trends_IIR/zlema/Zlema.md +++ b/lib/trends_IIR/zlema/Zlema.md @@ -1,8 +1,26 @@ # ZLEMA: Zero-Lag Exponential Moving Average +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Trend (IIR MA) | +| **Inputs** | Source (close) | +| **Parameters** | `period` | +| **Outputs** | Single series (Zlema) | +| **Output range** | Tracks input | +| **Warmup** | `Math.Max(lag + 1, EstimateWarmupPeriod(beta))` bars | + +### TL;DR + +- ZLEMA takes a standard EMA and feeds it a **zero-lag signal**: current price minus a lagged price. +- Parameterized by `period`. +- Output range: Tracks input. +- Requires `Math.Max(lag + 1, EstimateWarmupPeriod(beta))` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + +> "ZLEMA does not erase lag. It predicts just enough to act early, then pays the price in overshoot." + ## EMA with lag compensation via a zero-lag signal -> "ZLEMA does not erase lag. It predicts just enough to act early, then pays the price in overshoot." ZLEMA takes a standard EMA and feeds it a **zero-lag signal**: current price minus a lagged price. This produces a smoother that responds faster than EMA without going fully raw. It is not magic. It shifts some lag into controlled overshoot. @@ -125,4 +143,4 @@ ZLEMA is validated against a PineScript reference implementation. 4. **Non-finite data** - NaN or Infinity is replaced with the last valid value. Before the first valid sample, output is `NaN`. \ No newline at end of file + NaN or Infinity is replaced with the last valid value. Before the first valid sample, output is `NaN`. diff --git a/lib/trends_IIR/zltema/Zltema.md b/lib/trends_IIR/zltema/Zltema.md index a17f7d2f..bda7008a 100644 --- a/lib/trends_IIR/zltema/Zltema.md +++ b/lib/trends_IIR/zltema/Zltema.md @@ -1,8 +1,26 @@ # ZLTEMA: Zero-Lag Triple Exponential Moving Average +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Trend (IIR MA) | +| **Inputs** | Source (close) | +| **Parameters** | `period` | +| **Outputs** | Single series (Zltema) | +| **Output range** | Tracks input | +| **Warmup** | `Math.Max(lag + 1, EstimateWarmupPeriod(beta))` bars | + +### TL;DR + +- ZLTEMA takes a standard TEMA and feeds it a **zero-lag signal**: current price minus a lagged price. +- Parameterized by `period`. +- Output range: Tracks input. +- Requires `Math.Max(lag + 1, EstimateWarmupPeriod(beta))` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + +> "ZLTEMA combines the speed of zero-lag prediction with the smoothness of triple exponential averaging. You get the fastest response in the zero-lag family, with the best noise rejection from the TEMA cascade." + ## TEMA with lag compensation via a zero-lag signal -> "ZLTEMA combines the speed of zero-lag prediction with the smoothness of triple exponential averaging. You get the fastest response in the zero-lag family, with the best noise rejection from the TEMA cascade." ZLTEMA takes a standard TEMA and feeds it a **zero-lag signal**: current price minus a lagged price. This produces a smoother that responds faster than TEMA without going fully raw. The triple EMA cascade provides maximum noise rejection in the exponential family while the zero-lag preprocessing maintains responsiveness. @@ -155,4 +173,4 @@ ZLTEMA is validated against a PineScript reference implementation. 6. **ZLDEMA vs ZLTEMA** - ZLTEMA adds a third EMA stage over ZLDEMA. This provides additional smoothing at the cost of more overshoot during reversals. Use ZLDEMA when overshoot is more concerning than noise; use ZLTEMA when maximum smoothness is required. \ No newline at end of file + ZLTEMA adds a third EMA stage over ZLDEMA. This provides additional smoothing at the cost of more overshoot during reversals. Use ZLDEMA when overshoot is more concerning than noise; use ZLTEMA when maximum smoothness is required. diff --git a/lib/volatility/adr/Adr.md b/lib/volatility/adr/Adr.md index 0030818d..7bc1d4b1 100644 --- a/lib/volatility/adr/Adr.md +++ b/lib/volatility/adr/Adr.md @@ -1,5 +1,22 @@ # ADR: Average Daily Range +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Volatility | +| **Inputs** | OHLCV bar (TBar) | +| **Parameters** | `period`, `method` (default AdrMethod.Sma) | +| **Outputs** | Single series (Adr) | +| **Output range** | $\geq 0$ | +| **Warmup** | `ma.WarmupPeriod` bars | + +### TL;DR + +- The Average Daily Range (ADR) measures the average distance between High and Low prices over a specified period. +- Parameterized by `period`, `method` (default adrmethod.sma). +- Output range: $\geq 0$. +- Requires `ma.WarmupPeriod` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "The simplest measure is often the most useful. Why complicate what doesn't need complicating?" The Average Daily Range (ADR) measures the average distance between High and Low prices over a specified period. Unlike its cousin ATR, ADR ignores gaps entirely. It answers a straightforward question: "How much does this asset typically move within a single bar?" @@ -132,4 +149,4 @@ O(1) sliding mean of daily ranges. Same running-sum pattern as SMA but applied t - **Confusing ADR with ATR**: They measure different things. ADR ignores gaps; ATR accounts for them. Know which you need. - **Wrong smoothing method**: SMA is stable but can jump when old values exit the window. EMA is smoother for trending volatility. Match the method to your use case. - **Scale dependence**: Like ATR, ADR is absolute. An ADR of 5 on a \$100 stock is 5% volatility; on a \$10 stock, it's 50% volatility. Normalize if comparing across assets. -- **Assuming direction**: High ADR means wide bars, not up or down. Crashes and rallies both produce high ADR. \ No newline at end of file +- **Assuming direction**: High ADR means wide bars, not up or down. Crashes and rallies both produce high ADR. diff --git a/lib/volatility/atr/Atr.md b/lib/volatility/atr/Atr.md index 030ec86a..a99e2373 100644 --- a/lib/volatility/atr/Atr.md +++ b/lib/volatility/atr/Atr.md @@ -1,5 +1,22 @@ # ATR: Average True Range +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Volatility | +| **Inputs** | OHLCV bar (TBar) | +| **Parameters** | `period` | +| **Outputs** | Single series (Atr) | +| **Output range** | $\geq 0$ | +| **Warmup** | `rma.WarmupPeriod` bars | + +### TL;DR + +- The Average True Range measures market "heat" with complete disregard for direction. +- Parameterized by `period`. +- Output range: $\geq 0$. +- Requires `rma.WarmupPeriod` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "Volatility is the price of admission. The question is whether the ride is worth it." The Average True Range measures market "heat" with complete disregard for direction. It ignores whether the market is screaming upward or crashing downward. ATR cares only about magnitude. When ATR is high, expect wide swings. When ATR is low, expect narrow consolidation. Most traders mistakenly use ATR to find entries. Its true power lies in exits and position sizing. ATR answers the critical question: "How far can this asset move against me in a single day?" @@ -276,4 +293,4 @@ private static TSeries CalculateTrueRange(TBarSeries source) - Wilder, J. W. (1978). *New Concepts in Technical Trading Systems*. Trend Research. Chapter: Average True Range. - Kaufman, P. (2013). *Trading Systems and Methods*. Wiley. (ATR-based position sizing) -- Kase, C. (1996). "Trading with the True Range." *Technical Analysis of Stocks & Commodities*. (TR variations) \ No newline at end of file +- Kase, C. (1996). "Trading with the True Range." *Technical Analysis of Stocks & Commodities*. (TR variations) diff --git a/lib/volatility/atrn/Atrn.md b/lib/volatility/atrn/Atrn.md index 27a858b6..5fe34001 100644 --- a/lib/volatility/atrn/Atrn.md +++ b/lib/volatility/atrn/Atrn.md @@ -1,5 +1,22 @@ # ATRN: Average True Range Normalized +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Volatility | +| **Inputs** | OHLCV bar (TBar) | +| **Parameters** | `period` | +| **Outputs** | Single series (Atrn) | +| **Output range** | $\geq 0$ | +| **Warmup** | 1 bar | + +### TL;DR + +- ATRN transforms the absolute ATR into a relative measure by normalizing it to a [0,1] scale using min-max scaling over a lookback window. +- Parameterized by `period`. +- Output range: $\geq 0$. +- Requires 1 bar of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "Context is everything. A \$5 ATR means nothing until you know the \$5 ATR from last month was \$2." ATRN transforms the absolute ATR into a relative measure by normalizing it to a [0,1] scale using min-max scaling over a lookback window. This answers the question: "Is current volatility high or low *compared to recent history*?" @@ -135,4 +152,4 @@ ATRN is a QuanTAlib-specific indicator. Validation confirms: 3. **Regime Detection**: Use ATRN thresholds to switch between mean-reversion (low ATRN) and trend-following (high ATRN) strategies. -4. **Volatility Breakout**: Look for moves from ATRN < 0.2 to ATRN > 0.5 as potential breakout confirmation. \ No newline at end of file +4. **Volatility Breakout**: Look for moves from ATRN < 0.2 to ATRN > 0.5 as potential breakout confirmation. diff --git a/lib/volatility/bbw/Bbw.md b/lib/volatility/bbw/Bbw.md index 66b8e876..0ec53c14 100644 --- a/lib/volatility/bbw/Bbw.md +++ b/lib/volatility/bbw/Bbw.md @@ -1,5 +1,22 @@ # BBW: Bollinger Band Width +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Volatility | +| **Inputs** | Source (close) | +| **Parameters** | `period`, `multiplier` (default 2.0) | +| **Outputs** | Single series (Bbw) | +| **Output range** | $\geq 0$ | +| **Warmup** | `period` bars | + +### TL;DR + +- Bollinger Band Width measures the distance between upper and lower Bollinger Bands, normalized by the middle band. +- Parameterized by `period`, `multiplier` (default 2.0). +- Output range: $\geq 0$. +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "Volatility breeds opportunity. The squeeze precedes the explosion." Bollinger Band Width measures the distance between upper and lower Bollinger Bands, normalized by the middle band. When BBW is low, the bands are squeezing together, signaling compressed volatility and impending breakout. When BBW is high, the market is in an expanded volatility state. BBW transforms Bollinger Bands from a visual channel indicator into a quantifiable volatility oscillator, enabling algorithmic detection of "squeeze" conditions that often precede significant price moves. @@ -251,4 +268,4 @@ For default N=20: approximately 424 bytes per instance. - Bollinger, J. (2001). *Bollinger on Bollinger Bands*. McGraw-Hill. (Original Bollinger Band methodology) - Bollinger, J. "Bollinger Band Width." BollingerBands.com. (BBW definition and squeeze strategy) -- Connors, L., & Raschke, L. (1995). *Street Smarts*. M. Gordon Publishing. (Squeeze trading strategies) \ No newline at end of file +- Connors, L., & Raschke, L. (1995). *Street Smarts*. M. Gordon Publishing. (Squeeze trading strategies) diff --git a/lib/volatility/bbwn/Bbwn.md b/lib/volatility/bbwn/Bbwn.md index f20e163e..185eb29a 100644 --- a/lib/volatility/bbwn/Bbwn.md +++ b/lib/volatility/bbwn/Bbwn.md @@ -1,5 +1,22 @@ # BBWN: Bollinger Band Width Normalized +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Volatility | +| **Inputs** | Source (close) | +| **Parameters** | `period`, `multiplier` (default 2.0), `lookback` (default 252) | +| **Outputs** | Single series (Bbwn) | +| **Output range** | $\geq 0$ | +| **Warmup** | `period + lookback` bars | + +### TL;DR + +- Bollinger Band Width Normalized (BBWN) extends the standard BBW by normalizing it to a [0,1] range based on historical minimum and maximum values o... +- Parameterized by `period`, `multiplier` (default 2.0), `lookback` (default 252). +- Output range: $\geq 0$. +- Requires `period + lookback` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "Normalization transforms volatility chaos into comparable signals." Bollinger Band Width Normalized (BBWN) extends the standard BBW by normalizing it to a [0,1] range based on historical minimum and maximum values over a lookback period. This normalization enables better comparison across different timeframes, instruments, and market conditions, making it easier to identify relative volatility levels consistently. diff --git a/lib/volatility/bbwp/Bbwp.md b/lib/volatility/bbwp/Bbwp.md index 024797de..fb52bd26 100644 --- a/lib/volatility/bbwp/Bbwp.md +++ b/lib/volatility/bbwp/Bbwp.md @@ -1,5 +1,22 @@ # BBWP: Bollinger Band Width Percentile +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Volatility | +| **Inputs** | Source (close) | +| **Parameters** | `period`, `multiplier` (default 2.0), `lookback` (default 252) | +| **Outputs** | Single series (Bbwp) | +| **Output range** | $\geq 0$ | +| **Warmup** | `period + lookback` bars | + +### TL;DR + +- BBWP (Bollinger Band Width Percentile) measures where the current Bollinger Band Width falls within its historical distribution, expressing the res... +- Parameterized by `period`, `multiplier` (default 2.0), `lookback` (default 252). +- Output range: $\geq 0$. +- Requires `period + lookback` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "Where does current volatility rank in the historical distribution? BBWP answers with a percentile." BBWP (Bollinger Band Width Percentile) measures where the current Bollinger Band Width falls within its historical distribution, expressing the result as a percentile rank between 0 and 1. Unlike BBWN which normalizes using min/max values, BBWP uses percentile ranking which is more robust to outliers. @@ -113,4 +130,4 @@ where L = lookback period (default 252) ## References - Bollinger, J. (2001). "Bollinger on Bollinger Bands." McGraw-Hill. -- QuanTAlib PineScript reference implementation (bbwp.pine) \ No newline at end of file +- QuanTAlib PineScript reference implementation (bbwp.pine) diff --git a/lib/volatility/ccv/Ccv.md b/lib/volatility/ccv/Ccv.md index 91e86d2d..46f00674 100644 --- a/lib/volatility/ccv/Ccv.md +++ b/lib/volatility/ccv/Ccv.md @@ -1,5 +1,22 @@ # CCV: Close-to-Close Volatility +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Volatility | +| **Inputs** | Source (close) | +| **Parameters** | `period`, `method` (default 1) | +| **Outputs** | Single series (Ccv) | +| **Output range** | $\geq 0$ | +| **Warmup** | `period + 1` bars | + +### TL;DR + +- Close-to-Close Volatility (CCV) calculates the annualized standard deviation of logarithmic returns using only closing prices. +- Parameterized by `period`, `method` (default 1). +- Output range: $\geq 0$. +- Requires `period + 1` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "The simplest volatility measure is often the most robust—when all you have is closing prices, make the most of them." Close-to-Close Volatility (CCV) calculates the annualized standard deviation of logarithmic returns using only closing prices. This is the foundational volatility measure in quantitative finance, serving as a benchmark against which more sophisticated estimators are compared. The implementation supports three smoothing methods (SMA, EMA, WMA) and annualizes using the standard √252 factor for daily data. @@ -196,4 +213,4 @@ CCV is a standard volatility measure implemented consistently across platforms: - Black, F., & Scholes, M. (1973). "The Pricing of Options and Corporate Liabilities." *Journal of Political Economy*. - Parkinson, M. (1980). "The Extreme Value Method for Estimating the Variance of the Rate of Return." *Journal of Business*. - Garman, M., & Klass, M. (1980). "On the Estimation of Security Price Volatilities from Historical Data." *Journal of Business*. -- Yang, D., & Zhang, Q. (2000). "Drift-Independent Volatility Estimation Based on High, Low, Open, and Close Prices." *Journal of Business*. \ No newline at end of file +- Yang, D., & Zhang, Q. (2000). "Drift-Independent Volatility Estimation Based on High, Low, Open, and Close Prices." *Journal of Business*. diff --git a/lib/volatility/cv/Cv.md b/lib/volatility/cv/Cv.md index 5b50e787..d14c8d25 100644 --- a/lib/volatility/cv/Cv.md +++ b/lib/volatility/cv/Cv.md @@ -1,5 +1,22 @@ # CV: Conditional Volatility (GARCH(1,1)) +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Volatility | +| **Inputs** | Source (close) | +| **Parameters** | `period` (default 20), `alpha` (default 0.2), `beta` (default 0.7) | +| **Outputs** | Single series (Cv) | +| **Output range** | $\geq 0$ | +| **Warmup** | `period + 1` bars | + +### TL;DR + +- Conditional Volatility (CV) implements the GARCH(1,1) model for volatility forecasting, the most widely used time-varying volatility model in finan... +- Parameterized by `period` (default 20), `alpha` (default 0.2), `beta` (default 0.7). +- Output range: $\geq 0$. +- Requires `period + 1` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "Volatility begets volatility—the GARCH model captures what traders have always known: calm markets stay calm, turbulent markets stay turbulent." Conditional Volatility (CV) implements the GARCH(1,1) model for volatility forecasting, the most widely used time-varying volatility model in financial econometrics. Unlike simple historical volatility measures, GARCH captures two key empirical features of financial returns: volatility clustering (large moves tend to follow large moves) and mean reversion (volatility eventually returns to a long-run average). The output is annualized volatility expressed as a percentage. @@ -197,4 +214,4 @@ CV/GARCH is proprietary with no direct open-source equivalents using the same ap - Engle, R. F. (1982). "Autoregressive Conditional Heteroscedasticity with Estimates of the Variance of United Kingdom Inflation." *Econometrica*, 50(4), 987-1007. - Bollerslev, T. (1986). "Generalized Autoregressive Conditional Heteroskedasticity." *Journal of Econometrics*, 31(3), 307-327. - Engle, R. F. (2001). "GARCH 101: The Use of ARCH/GARCH Models in Applied Econometrics." *Journal of Economic Perspectives*, 15(4), 157-168. -- Hansen, P. R., & Lunde, A. (2005). "A Forecast Comparison of Volatility Models: Does Anything Beat a GARCH(1,1)?" *Journal of Applied Econometrics*, 20(7), 873-889. \ No newline at end of file +- Hansen, P. R., & Lunde, A. (2005). "A Forecast Comparison of Volatility Models: Does Anything Beat a GARCH(1,1)?" *Journal of Applied Econometrics*, 20(7), 873-889. diff --git a/lib/volatility/cvi/Cvi.md b/lib/volatility/cvi/Cvi.md index 2478bfb8..21e6cd55 100644 --- a/lib/volatility/cvi/Cvi.md +++ b/lib/volatility/cvi/Cvi.md @@ -1,5 +1,22 @@ # CVI: Chaikin's Volatility +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Volatility | +| **Inputs** | OHLCV bar (TBar) | +| **Parameters** | `rocLength` (default 10), `smoothLength` (default 10) | +| **Outputs** | Single series (Cvi) | +| **Output range** | $\geq 0$ | +| **Warmup** | 1 bar | + +### TL;DR + +- Chaikin's Volatility (CVI) measures the rate of change of the EMA-smoothed high-low trading range. +- Parameterized by `roclength` (default 10), `smoothlength` (default 10). +- Output range: $\geq 0$. +- Requires 1 bar of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "Volatility expansion precedes major moves—when the trading range starts widening, pay attention." Chaikin's Volatility (CVI) measures the rate of change of the EMA-smoothed high-low trading range. Unlike traditional volatility measures that focus on returns, CVI directly tracks the expansion and contraction of price ranges over time. A positive CVI indicates expanding volatility (wider trading ranges), while a negative CVI signals contracting volatility (narrower ranges). This makes CVI particularly useful for identifying breakout conditions and market transitions. @@ -228,4 +245,4 @@ Avoid range trades when: CVI rising sharply - Chaikin, M. (1966). "Stock Market Trading Systems." Various publications and interviews. - Achelis, S. B. (2000). "Technical Analysis from A to Z." McGraw-Hill. Chapter on Chaikin Volatility. -- Murphy, J. J. (1999). "Technical Analysis of the Financial Markets." New York Institute of Finance. \ No newline at end of file +- Murphy, J. J. (1999). "Technical Analysis of the Financial Markets." New York Institute of Finance. diff --git a/lib/volatility/etherm/Etherm.md b/lib/volatility/etherm/Etherm.md index 86ead854..f9608750 100644 --- a/lib/volatility/etherm/Etherm.md +++ b/lib/volatility/etherm/Etherm.md @@ -1,5 +1,22 @@ # ETHERM: Elder's Thermometer +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Volatility | +| **Inputs** | OHLCV bar (TBar) | +| **Parameters** | `period` (default 22) | +| **Outputs** | Single series (Etherm) | +| **Output range** | $\geq 0$ | +| **Warmup** | `period` bars | + +### TL;DR + +- Elder's Thermometer (ETHERM) measures how far today's price bar extends beyond yesterday's range, capturing the maximum absolute expansion in eithe... +- Parameterized by `period` (default 22). +- Output range: $\geq 0$. +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "Markets run a fever before they crash. The thermometer tells you when to reach for the aspirin." Elder's Thermometer (ETHERM) measures how far today's price bar extends beyond yesterday's range, capturing the maximum absolute expansion in either direction. Developed by Dr. Alexander Elder and described in *Come Into My Trading Room* (2002, p.162), the indicator distinguishes between sleepy, quiet periods and hot episodes when market crowds become excited. The raw thermometer reading is smoothed with an EMA to produce a signal line; when temperature spikes to triple the signal, it flags an explosive move worth fading. At 5 operations per bar for the raw value and O(1) EMA update, ETHERM is among the cheapest volatility measures to compute. diff --git a/lib/volatility/ewma/Ewma.md b/lib/volatility/ewma/Ewma.md index 19b38b4b..50fa4002 100644 --- a/lib/volatility/ewma/Ewma.md +++ b/lib/volatility/ewma/Ewma.md @@ -1,5 +1,22 @@ # EWMA: Exponentially Weighted Moving Average Volatility +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Volatility | +| **Inputs** | Source (close) | +| **Parameters** | `period` (default 20), `annualize` (default true), `annualPeriods` (default 252) | +| **Outputs** | Single series (EWMA) | +| **Output range** | $\geq 0$ | +| **Warmup** | `period` bars | + +### TL;DR + +- EWMA Volatility calculates market volatility using an exponentially weighted moving average of squared log returns with bias correction. +- Parameterized by `period` (default 20), `annualize` (default true), `annualperiods` (default 252). +- Output range: $\geq 0$. +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "The past doesn't repeat itself, but it does rhyme—and EWMA captures the rhythm of volatility with exponential memory." EWMA Volatility calculates market volatility using an exponentially weighted moving average of squared log returns with bias correction. Unlike simple historical volatility that weights all observations equally, EWMA gives more weight to recent observations while still considering historical data, making it more responsive to current market conditions. @@ -165,4 +182,4 @@ Note: This implementation is based on the PineScript reference at `ewma.pine`. T - J.P. Morgan/Reuters. (1996). "RiskMetrics Technical Document." Fourth Edition. - Bollerslev, T. (1986). "Generalized Autoregressive Conditional Heteroskedasticity." Journal of Econometrics. -- Hull, J. (2018). "Options, Futures, and Other Derivatives." Chapter on Volatility Estimation. \ No newline at end of file +- Hull, J. (2018). "Options, Futures, and Other Derivatives." Chapter on Volatility Estimation. diff --git a/lib/volatility/gkv/Gkv.md b/lib/volatility/gkv/Gkv.md index 0b3a87c0..f8c064ba 100644 --- a/lib/volatility/gkv/Gkv.md +++ b/lib/volatility/gkv/Gkv.md @@ -1,5 +1,22 @@ # GKV: Garman-Klass Volatility +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Volatility | +| **Inputs** | OHLCV bar (TBar) | +| **Parameters** | `period` (default 20), `annualize` (default true), `annualPeriods` (default 252) | +| **Outputs** | Single series (Gkv) | +| **Output range** | $\geq 0$ | +| **Warmup** | `period` bars | + +### TL;DR + +- Garman-Klass Volatility (GKV) is a range-based volatility estimator that uses all four OHLC prices to provide more efficient volatility estimates t... +- Parameterized by `period` (default 20), `annualize` (default true), `annualperiods` (default 252). +- Output range: $\geq 0$. +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "Why settle for closing prices when you have the full trading range? It's like judging a book by its last page." Garman-Klass Volatility (GKV) is a range-based volatility estimator that uses all four OHLC prices to provide more efficient volatility estimates than traditional close-to-close methods. Developed by Mark Garman and Michael Klass in 1980, this estimator achieves theoretical efficiency gains of 7-8x over simple close-to-close variance by incorporating intraday price information. The implementation includes RMA (Wilder's) smoothing with bias correction and optional annualization. @@ -276,4 +293,4 @@ Confirmation: Wait for directional move - Garman, M. B., & Klass, M. J. (1980). "On the Estimation of Security Price Volatilities from Historical Data." *Journal of Business*, 53(1), 67-78. - Parkinson, M. (1980). "The Extreme Value Method for Estimating the Variance of the Rate of Return." *Journal of Business*, 53(1), 61-65. - Rogers, L. C. G., & Satchell, S. E. (1991). "Estimating Variance from High, Low and Closing Prices." *Annals of Applied Probability*, 1(4), 504-512. -- Yang, D., & Zhang, Q. (2000). "Drift-Independent Volatility Estimation Based on High, Low, Open, and Close Prices." *Journal of Business*, 73(3), 477-491. \ No newline at end of file +- Yang, D., & Zhang, Q. (2000). "Drift-Independent Volatility Estimation Based on High, Low, Open, and Close Prices." *Journal of Business*, 73(3), 477-491. diff --git a/lib/volatility/hlv/Hlv.md b/lib/volatility/hlv/Hlv.md index d9a8c0c7..74c9ab31 100644 --- a/lib/volatility/hlv/Hlv.md +++ b/lib/volatility/hlv/Hlv.md @@ -1,8 +1,26 @@ # HLV: High-Low Volatility (Parkinson) +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Volatility | +| **Inputs** | OHLCV bar (TBar) | +| **Parameters** | `period` (default 20), `annualize` (default true), `annualPeriods` (default 252) | +| **Outputs** | Single series (Hlv) | +| **Output range** | $\geq 0$ | +| **Warmup** | `period` bars | + +### TL;DR + +- *Also known as: PV (Parkinson Volatility)* +- Parameterized by `period` (default 20), `annualize` (default true), `annualperiods` (default 252). +- Output range: $\geq 0$. +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + +> "The simplest solution is often the most elegant. When you only need the peaks and valleys, why ask for the whole journey?" + *Also known as: PV (Parkinson Volatility)* -> "The simplest solution is often the most elegant. When you only need the peaks and valleys, why ask for the whole journey?" High-Low Volatility (HLV), also known as the Parkinson estimator, is a range-based volatility measure that uses only the high and low prices of each period. Developed by Michael Parkinson in 1980, this estimator achieves approximately 5x better efficiency than close-to-close methods by exploiting the information content in the trading range. The implementation includes RMA (Wilder's) smoothing with bias correction and optional annualization. @@ -291,4 +309,4 @@ Note: HLV may underestimate true volatility due to drift bias - Parkinson, M. (1980). "The Extreme Value Method for Estimating the Variance of the Rate of Return." *Journal of Business*, 53(1), 61-65. - Garman, M. B., & Klass, M. J. (1980). "On the Estimation of Security Price Volatilities from Historical Data." *Journal of Business*, 53(1), 67-78. - Rogers, L. C. G., & Satchell, S. E. (1991). "Estimating Variance from High, Low and Closing Prices." *Annals of Applied Probability*, 1(4), 504-512. -- Alizadeh, S., Brandt, M. W., & Diebold, F. X. (2002). "Range-Based Estimation of Stochastic Volatility Models." *Journal of Finance*, 57(3), 1047-1091. \ No newline at end of file +- Alizadeh, S., Brandt, M. W., & Diebold, F. X. (2002). "Range-Based Estimation of Stochastic Volatility Models." *Journal of Finance*, 57(3), 1047-1091. diff --git a/lib/volatility/hv/Hv.md b/lib/volatility/hv/Hv.md index bb03b87b..7f9002e4 100644 --- a/lib/volatility/hv/Hv.md +++ b/lib/volatility/hv/Hv.md @@ -1,5 +1,22 @@ # HV: Historical Volatility (Close-to-Close) +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Volatility | +| **Inputs** | OHLCV bar (TBar) | +| **Parameters** | `period` (default 20), `annualize` (default true), `annualPeriods` (default 252) | +| **Outputs** | Single series (Hv) | +| **Output range** | $\geq 0$ | +| **Warmup** | `period + 1` bars | + +### TL;DR + +- Historical Volatility (HV), also known as close-to-close volatility or realized volatility, is the classical measure of price volatility using the ... +- Parameterized by `period` (default 20), `annualize` (default true), `annualperiods` (default 252). +- Output range: $\geq 0$. +- Requires `period + 1` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "The foundation of all volatility measures—simple, intuitive, and yet surprisingly informative when you understand what it's actually measuring." Historical Volatility (HV), also known as close-to-close volatility or realized volatility, is the classical measure of price volatility using the standard deviation of logarithmic returns. First formalized in the early 20th century and central to the Black-Scholes option pricing model, HV remains the benchmark against which all other volatility estimators are compared. This implementation uses population standard deviation with a rolling window and optional annualization. @@ -290,4 +307,4 @@ HV is the standard for regulatory risk calculations (VaR, ES) because: - Black, F., & Scholes, M. (1973). "The Pricing of Options and Corporate Liabilities." *Journal of Political Economy*, 81(3), 637-654. - Parkinson, M. (1980). "The Extreme Value Method for Estimating the Variance of the Rate of Return." *Journal of Business*, 53(1), 61-65. - Garman, M. B., & Klass, M. J. (1980). "On the Estimation of Security Price Volatilities from Historical Data." *Journal of Business*, 53(1), 67-78. -- Merton, R. C. (1980). "On Estimating the Expected Return on the Market: An Exploratory Investigation." *Journal of Financial Economics*, 8(4), 323-361. \ No newline at end of file +- Merton, R. C. (1980). "On Estimating the Expected Return on the Market: An Exploratory Investigation." *Journal of Financial Economics*, 8(4), 323-361. diff --git a/lib/volatility/jvolty/Jvolty.md b/lib/volatility/jvolty/Jvolty.md index 95cdc350..62c10801 100644 --- a/lib/volatility/jvolty/Jvolty.md +++ b/lib/volatility/jvolty/Jvolty.md @@ -1,5 +1,22 @@ # JVOLTY: Jurik Volatility +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Volatility | +| **Inputs** | Source (close) | +| **Parameters** | `period` | +| **Outputs** | Single series (Jvolty) | +| **Output range** | $\geq 0$ | +| **Warmup** | 1 bar | + +### TL;DR + +- Jurik Volatility (JVOLTY) is the adaptive volatility component extracted from Mark Jurik's JMA algorithm. +- Parameterized by `period`. +- Output range: $\geq 0$. +- Requires 1 bar of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "The volatility measure that ignores the noise—because sometimes, the best signal comes from knowing what to throw away." Jurik Volatility (JVOLTY) is the adaptive volatility component extracted from Mark Jurik's JMA algorithm. Unlike traditional volatility measures that treat all price movements equally, JVOLTY uses a 128-bar trimmed mean distribution to compute a robust volatility reference that rejects outliers by design. The result: a volatility measure that remains stable during flash crashes, earnings surprises, and 5-sigma events while still tracking genuine regime changes. @@ -239,4 +256,4 @@ JVOLTY is proprietary. No open-source library implements it. Validation is perfo - Jurik Research. (1998-2005). "JMA White Papers." *jurikres.com* (archived). - Kositsin, Nikolay. (2007). "Digital Indicators for MetaTrader 4." *Alpari Forum Archives*. -- Wilcox, R. R. (2012). "Introduction to Robust Estimation and Hypothesis Testing." *Academic Press*. (Trimmed mean statistics) \ No newline at end of file +- Wilcox, R. R. (2012). "Introduction to Robust Estimation and Hypothesis Testing." *Academic Press*. (Trimmed mean statistics) diff --git a/lib/volatility/jvoltyn/Jvoltyn.md b/lib/volatility/jvoltyn/Jvoltyn.md index 0ab7cf87..929e3d94 100644 --- a/lib/volatility/jvoltyn/Jvoltyn.md +++ b/lib/volatility/jvoltyn/Jvoltyn.md @@ -1,5 +1,22 @@ # JVOLTYN: Normalized Jurik Volatility +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Volatility | +| **Inputs** | Source (close) | +| **Parameters** | `period` | +| **Outputs** | Single series (Jvoltyn) | +| **Output range** | $\geq 0$ | +| **Warmup** | 1 bar | + +### TL;DR + +- Normalized Jurik Volatility (JVOLTYN) maps the raw JVOLTY dynamic exponent to a 0-100 scale. +- Parameterized by `period`. +- Output range: $\geq 0$. +- Requires 1 bar of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "When you need to compare apples to apples, normalize your volatility—0 is calm, 100 is chaos." Normalized Jurik Volatility (JVOLTYN) maps the raw JVOLTY dynamic exponent to a 0-100 scale. While JVOLTY outputs values in the range [1, logParam] (where logParam is period-dependent), JVOLTYN transforms this to a universal scale where 0 represents minimum volatility and 100 represents maximum volatility. This normalization enables direct comparison across different periods and instruments. @@ -212,4 +229,4 @@ public Jvoltyn(int period = 14) ## References - Jurik Research. (1998-2005). "JMA White Papers." *jurikres.com* (archived). -- QuanTAlib. "JVOLTY: Jurik Volatility." [Documentation](../jvolty/Jvolty.md). \ No newline at end of file +- QuanTAlib. "JVOLTY: Jurik Volatility." [Documentation](../jvolty/Jvolty.md). diff --git a/lib/volatility/massi/Massi.md b/lib/volatility/massi/Massi.md index c019c925..270c300d 100644 --- a/lib/volatility/massi/Massi.md +++ b/lib/volatility/massi/Massi.md @@ -1,5 +1,22 @@ # MASSI: Mass Index +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Volatility | +| **Inputs** | OHLCV bar (TBar) | +| **Parameters** | `emaLength` (default 9), `sumLength` (default 25) | +| **Outputs** | Single series (Massi) | +| **Output range** | $\geq 0$ | +| **Warmup** | 1 bar | + +### TL;DR + +- The Mass Index, developed by Donald Dorsey and introduced in the June 1992 issue of *Technical Analysis of Stocks & Commodities*, identifies potent... +- Parameterized by `emalength` (default 9), `sumlength` (default 25). +- Output range: $\geq 0$. +- Requires 1 bar of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "The Mass Index doesn't predict direction—it predicts the moment of maximum uncertainty before clarity emerges." The Mass Index, developed by Donald Dorsey and introduced in the June 1992 issue of *Technical Analysis of Stocks & Commodities*, identifies potential trend reversals by measuring the narrowing and widening of the range between high and low prices. Unlike directional indicators, MASSI focuses on the *pattern* of range expansion and contraction, particularly the characteristic "reversal bulge" that often precedes significant market turns. @@ -205,4 +222,4 @@ Massi.Calculate(ranges, output, emaLength: 9, sumLength: 25); - Dorsey, Donald. (1992). "The Mass Index." *Technical Analysis of Stocks & Commodities*, June 1992. - Achelis, Steven B. (2000). *Technical Analysis from A to Z*. McGraw-Hill. -- Pring, Martin J. (2002). *Technical Analysis Explained*. McGraw-Hill. \ No newline at end of file +- Pring, Martin J. (2002). *Technical Analysis Explained*. McGraw-Hill. diff --git a/lib/volatility/natr/Natr.md b/lib/volatility/natr/Natr.md index 321375da..8fc49977 100644 --- a/lib/volatility/natr/Natr.md +++ b/lib/volatility/natr/Natr.md @@ -1,5 +1,22 @@ # NATR: Normalized Average True Range +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Volatility | +| **Inputs** | OHLCV bar (TBar) | +| **Parameters** | `period` (default 14) | +| **Outputs** | Single series (Natr) | +| **Output range** | $\geq 0$ | +| **Warmup** | 1 bar | + +### TL;DR + +- NATR normalizes the Average True Range (ATR) as a percentage of the closing price. +- Parameterized by `period` (default 14). +- Output range: $\geq 0$. +- Requires 1 bar of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "The same volatility reads different on different price scales. NATR speaks the universal language of percentages." NATR normalizes the Average True Range (ATR) as a percentage of the closing price. This is mathematically identical to ATRP (Average True Range Percent)—both compute `(ATR / Close) × 100`. The difference is purely nomenclature: NATR is the term used in TA-Lib and many charting platforms. @@ -194,4 +211,4 @@ Ensures equal percentage risk per position regardless of asset price. - Wilder, J.W. (1978). *New Concepts in Technical Trading Systems*. Trend Research. - TA-Lib documentation: NATR function specification -- TradingView PineScript: `ta.natr()` implementation \ No newline at end of file +- TradingView PineScript: `ta.natr()` implementation diff --git a/lib/volatility/rsv/Rsv.md b/lib/volatility/rsv/Rsv.md index b86e6764..7afaa553 100644 --- a/lib/volatility/rsv/Rsv.md +++ b/lib/volatility/rsv/Rsv.md @@ -1,5 +1,22 @@ # RSV: Rogers-Satchell Volatility +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Volatility | +| **Inputs** | OHLCV bar (TBar) | +| **Parameters** | `period` (default 20), `annualize` (default true), `annualPeriods` (default 252) | +| **Outputs** | Single series (Rsv) | +| **Output range** | $\geq 0$ | +| **Warmup** | `period` bars | + +### TL;DR + +- Rogers-Satchell Volatility (RSV) is a drift-adjusted OHLC-based volatility estimator that uses all four price points (Open, High, Low, Close) to pr... +- Parameterized by `period` (default 20), `annualize` (default true), `annualperiods` (default 252). +- Output range: $\geq 0$. +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "The best estimator is one that extracts maximum information from all available data while remaining robust to the noise of market microstructure." Rogers-Satchell Volatility (RSV) is a drift-adjusted OHLC-based volatility estimator that uses all four price points (Open, High, Low, Close) to provide more accurate volatility estimates than simpler range-based methods. Developed by L.C.G. Rogers and S.E. Satchell in 1991, this estimator is unique in its ability to account for price drift, making it particularly suitable for trending markets. The implementation uses SMA smoothing and optional annualization. @@ -336,4 +353,4 @@ rsVariance = Math.FusedMultiplyAdd(lnHO, lnHC, lnLO * lnLC); - Parkinson, M. (1980). "The Extreme Value Method for Estimating the Variance of the Rate of Return." *Journal of Business*, 53(1), 61-65. - Garman, M. B., & Klass, M. J. (1980). "On the Estimation of Security Price Volatilities from Historical Data." *Journal of Business*, 53(1), 67-78. - Yang, D., & Zhang, Q. (2000). "Drift-Independent Volatility Estimation Based on High, Low, Open, and Close Prices." *Journal of Business*, 73(3), 477-492. -- Alizadeh, S., Brandt, M. W., & Diebold, F. X. (2002). "Range-Based Estimation of Stochastic Volatility Models." *Journal of Finance*, 57(3), 1047-1091. \ No newline at end of file +- Alizadeh, S., Brandt, M. W., & Diebold, F. X. (2002). "Range-Based Estimation of Stochastic Volatility Models." *Journal of Finance*, 57(3), 1047-1091. diff --git a/lib/volatility/rv/Rv.md b/lib/volatility/rv/Rv.md index 89d0d021..49943cf2 100644 --- a/lib/volatility/rv/Rv.md +++ b/lib/volatility/rv/Rv.md @@ -1,5 +1,22 @@ # RV: Realized Volatility +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Volatility | +| **Inputs** | OHLCV bar (TBar) | +| **Parameters** | `period` (default 5), `smoothingPeriod` (default 20), `annualize` (default true), `annualPeriods` (default 252) | +| **Outputs** | Single series (Rv) | +| **Output range** | $\geq 0$ | +| **Warmup** | 1 bar | + +### TL;DR + +- Realized Volatility (RV) measures price volatility using the sum of squared logarithmic returns over a rolling window, then applying SMA smoothing ... +- Parameterized by `period` (default 5), `smoothingperiod` (default 20), `annualize` (default true), `annualperiods` (default 252). +- Output range: $\geq 0$. +- Requires 1 bar of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "The sum of squared returns—a direct measure of how much the market actually moved, free from the assumptions embedded in standard deviation." Realized Volatility (RV) measures price volatility using the sum of squared logarithmic returns over a rolling window, then applying SMA smoothing for stability. Unlike traditional Historical Volatility (HV) which calculates standard deviation of returns, RV directly accumulates squared returns—the raw building blocks of variance—providing a more direct measure of realized price variation. @@ -260,4 +277,4 @@ Diverging (short < long): Volatility compression - Andersen, T. G., Bollerslev, T., Diebold, F. X., & Labys, P. (2001). "The Distribution of Realized Exchange Rate Volatility." *Journal of the American Statistical Association*, 96(453), 42-55. - Andersen, T. G., Bollerslev, T., Diebold, F. X., & Ebens, H. (2001). "The Distribution of Realized Stock Return Volatility." *Journal of Financial Economics*, 61(1), 43-76. - Barndorff-Nielsen, O. E., & Shephard, N. (2002). "Econometric Analysis of Realized Volatility and Its Use in Estimating Stochastic Volatility Models." *Journal of the Royal Statistical Society: Series B*, 64(2), 253-280. -- McAleer, M., & Medeiros, M. C. (2008). "Realized Volatility: A Review." *Econometric Reviews*, 27(1-3), 10-45. \ No newline at end of file +- McAleer, M., & Medeiros, M. C. (2008). "Realized Volatility: A Review." *Econometric Reviews*, 27(1-3), 10-45. diff --git a/lib/volatility/rvi/Rvi.md b/lib/volatility/rvi/Rvi.md index 3be9fb46..6c10ce7b 100644 --- a/lib/volatility/rvi/Rvi.md +++ b/lib/volatility/rvi/Rvi.md @@ -1,5 +1,22 @@ # RVI: Relative Volatility Index +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Volatility | +| **Inputs** | OHLCV bar (TBar) | +| **Parameters** | `stdevLength` (default 10), `rmaLength` (default 14) | +| **Outputs** | Single series (Rvi) | +| **Output range** | $0$ to $100$ | +| **Warmup** | 1 bar | + +### TL;DR + +- The Relative Volatility Index (RVI) is a directional volatility oscillator that distinguishes between upward and downward price volatility. +- Parameterized by `stdevlength` (default 10), `rmalength` (default 14). +- Output range: $0$ to $100$. +- Requires 1 bar of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "Not all volatility is created equal—upward volatility feels like profit, downward volatility feels like loss. RVI separates these psychological experiences into a quantifiable measure." The Relative Volatility Index (RVI) is a directional volatility oscillator that distinguishes between upward and downward price volatility. Originally developed by Donald Dorsey in 1993, RVI measures the standard deviation of closing prices and categorizes this volatility based on whether prices are rising or falling. The result is an oscillator bounded between 0 and 100, where values above 50 indicate upward volatility dominance and values below 50 indicate downward volatility dominance. @@ -244,4 +261,4 @@ Price making lower lows + RVI making higher lows: Bullish divergence - Dorsey, D. (1993). "The Relative Volatility Index." *Technical Analysis of Stocks & Commodities*, 11(6), 253-256. - Dorsey, D. (1995). "Refining the Relative Volatility Index." *Technical Analysis of Stocks & Commodities*, 13(9). -- TradingView. (2024). "PineScript Reference Implementation." rvi.pine source file. \ No newline at end of file +- TradingView. (2024). "PineScript Reference Implementation." rvi.pine source file. diff --git a/lib/volatility/tr/Tr.md b/lib/volatility/tr/Tr.md index 9a8cc9a2..62f7508d 100644 --- a/lib/volatility/tr/Tr.md +++ b/lib/volatility/tr/Tr.md @@ -1,5 +1,22 @@ # TR: True Range +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Volatility | +| **Inputs** | OHLCV bar (TBar) | +| **Parameters** | None | +| **Outputs** | Single series (TR) | +| **Output range** | $\geq 0$ | +| **Warmup** | `1` bars | + +### TL;DR + +- True Range (TR) is a volatility measure that captures the maximum price movement for each bar, including any gap from the previous close. +- No configurable parameters; computation is stateless per bar. +- Output range: $\geq 0$. +- Requires `1` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "The true measure of volatility isn't just where price traveled within the bar, but whether it leaped from where it was." True Range (TR) is a volatility measure that captures the maximum price movement for each bar, including any gap from the previous close. Developed by J. Welles Wilder Jr. in 1978, TR forms the foundation for Average True Range (ATR) and numerous other volatility-based indicators. Unlike simple High-Low range, TR accounts for overnight gaps and opening jumps, providing a complete picture of price movement. @@ -273,4 +290,4 @@ If gap contribution > 50% of TR: Significant gap move - Wilder, J. W. (1978). *New Concepts in Technical Trading Systems*. Trend Research. - Kaufman, P. J. (2013). *Trading Systems and Methods* (5th ed.). Wiley. -- Murphy, J. J. (1999). *Technical Analysis of the Financial Markets*. New York Institute of Finance. \ No newline at end of file +- Murphy, J. J. (1999). *Technical Analysis of the Financial Markets*. New York Institute of Finance. diff --git a/lib/volatility/ui/Ui.md b/lib/volatility/ui/Ui.md index b3497833..67f2486f 100644 --- a/lib/volatility/ui/Ui.md +++ b/lib/volatility/ui/Ui.md @@ -1,5 +1,22 @@ # UI: Ulcer Index +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Volatility | +| **Inputs** | OHLCV bar (TBar) | +| **Parameters** | `period` (default 14) | +| **Outputs** | Single series (Ui) | +| **Output range** | $\geq 0$ | +| **Warmup** | `period` bars | + +### TL;DR + +- Ulcer Index (UI) is a downside volatility measure that quantifies the depth and duration of drawdowns from recent highs. +- Parameterized by `period` (default 14). +- Output range: $\geq 0$. +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "The ulcer-inducing anxiety of watching your portfolio decline—now quantified." Ulcer Index (UI) is a downside volatility measure that quantifies the depth and duration of drawdowns from recent highs. Developed by Peter G. Martin in 1987, UI captures what most volatility measures miss: the pain of being underwater. Unlike standard deviation or ATR that treat upside and downside moves equally, UI measures only the decline from peaks—the psychological stress that keeps investors awake at night. @@ -247,4 +264,4 @@ Strategy B is better risk-adjusted despite lower returns - Martin, P. G., & McCann, B. B. (1989). *The Investor's Guide to Fidelity Funds*. John Wiley & Sons. - Martin, P. G. (1987). "Ulcer Index, An Alternative Approach to the Measurement of Investment Risk & Risk-Adjusted Performance." -- Kaufman, P. J. (2013). *Trading Systems and Methods* (5th ed.). Wiley. \ No newline at end of file +- Kaufman, P. J. (2013). *Trading Systems and Methods* (5th ed.). Wiley. diff --git a/lib/volatility/vov/Vov.md b/lib/volatility/vov/Vov.md index af57dacb..5a1d86b0 100644 --- a/lib/volatility/vov/Vov.md +++ b/lib/volatility/vov/Vov.md @@ -1,5 +1,22 @@ # VOV: Volatility of Volatility +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Volatility | +| **Inputs** | OHLCV bar (TBar) | +| **Parameters** | `volatilityPeriod` (default 20), `vovPeriod` (default 10) | +| **Outputs** | Single series (Vov) | +| **Output range** | $\geq 0$ | +| **Warmup** | `volatilityPeriod + vovPeriod - 1` bars | + +### TL;DR + +- Volatility of Volatility (VOV) measures the standard deviation of volatility itself, quantifying how much volatility fluctuates over time. +- Parameterized by `volatilityperiod` (default 20), `vovperiod` (default 10). +- Output range: $\geq 0$. +- Requires `volatilityPeriod + vovPeriod - 1` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "When markets become uncertain about their own uncertainty, that's when things get interesting." Volatility of Volatility (VOV) measures the standard deviation of volatility itself, quantifying how much volatility fluctuates over time. While standard volatility tells you how much prices move, VOV tells you how stable or unstable that movement pattern is. High VOV indicates volatility is erratic and unpredictable; low VOV suggests volatility is relatively stable and consistent. @@ -254,4 +271,4 @@ The formula $\sqrt{E[X^2] - E[X]^2}$ can produce small negative values due to fl - Heston, S. L. (1993). "A Closed-Form Solution for Options with Stochastic Volatility with Applications to Bond and Currency Options." *Review of Financial Studies*, 6(2), 327-343. - Gatheral, J. (2006). *The Volatility Surface: A Practitioner's Guide*. Wiley Finance. -- CBOE. "VVIX Index." Chicago Board Options Exchange white paper on volatility-of-volatility indices. \ No newline at end of file +- CBOE. "VVIX Index." Chicago Board Options Exchange white paper on volatility-of-volatility indices. diff --git a/lib/volatility/vr/Vr.md b/lib/volatility/vr/Vr.md index b7740f58..cc16bfe6 100644 --- a/lib/volatility/vr/Vr.md +++ b/lib/volatility/vr/Vr.md @@ -1,5 +1,22 @@ # VR: Volatility Ratio +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Volatility | +| **Inputs** | OHLCV bar (TBar) | +| **Parameters** | `period` (default 14) | +| **Outputs** | Single series (Vr) | +| **Output range** | $\geq 0$ | +| **Warmup** | `period` bars | + +### TL;DR + +- Volatility Ratio (VR) measures the current bar's True Range relative to its Average True Range (ATR), providing a normalized indicator of short-ter... +- Parameterized by `period` (default 14). +- Output range: $\geq 0$. +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "When today's range dwarfs the average, pay attention—the market is telling you something unusual is happening." Volatility Ratio (VR) measures the current bar's True Range relative to its Average True Range (ATR), providing a normalized indicator of short-term volatility expansion or contraction. Values above 1.0 indicate above-average volatility (potential breakouts), while values below 1.0 suggest below-average volatility (consolidation). This simple yet powerful ratio helps traders identify when markets are moving unusually, often preceding significant price moves. @@ -269,4 +286,4 @@ The implementation uses: - Wilder, J. W. (1978). *New Concepts in Technical Trading Systems*. Trend Research. - Kaufman, P. J. (2013). *Trading Systems and Methods* (5th ed.). John Wiley & Sons. -- Kirkpatrick, C. D., & Dahlquist, J. R. (2010). *Technical Analysis: The Complete Resource for Financial Market Technicians* (2nd ed.). FT Press. \ No newline at end of file +- Kirkpatrick, C. D., & Dahlquist, J. R. (2010). *Technical Analysis: The Complete Resource for Financial Market Technicians* (2nd ed.). FT Press. diff --git a/lib/volatility/yzv/Yzv.md b/lib/volatility/yzv/Yzv.md index 94065fa4..b6bd38eb 100644 --- a/lib/volatility/yzv/Yzv.md +++ b/lib/volatility/yzv/Yzv.md @@ -1,5 +1,22 @@ # YZV: Yang-Zhang Volatility +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Volatility | +| **Inputs** | OHLCV bar (TBar) | +| **Parameters** | `period` (default 20) | +| **Outputs** | Single series (Yzv) | +| **Output range** | $\geq 0$ | +| **Warmup** | `period` bars | + +### TL;DR + +- Yang-Zhang Volatility is a sophisticated volatility estimator that combines overnight (close-to-open) returns with Rogers-Satchell intraday volatil... +- Parameterized by `period` (default 20). +- Output range: $\geq 0$. +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "The best volatility estimator uses all the information the market gives you—overnight gaps, intraday swings, and everything in between." Yang-Zhang Volatility is a sophisticated volatility estimator that combines overnight (close-to-open) returns with Rogers-Satchell intraday volatility to capture the full spectrum of price dynamics. Unlike simple close-to-close volatility that misses overnight gaps, or purely intraday measures that ignore opening moves, Yang-Zhang provides a theoretically unbiased estimate that remains consistent whether markets gap or drift. @@ -298,4 +315,4 @@ The implementation uses: - Yang, D., & Zhang, Q. (2000). "Drift-Independent Volatility Estimation Based on High, Low, Open, and Close Prices." *Journal of Business*, 73(3), 477-491. - Rogers, L. C. G., & Satchell, S. E. (1991). "Estimating Variance from High, Low and Closing Prices." *Annals of Applied Probability*, 1(4), 504-512. - Parkinson, M. (1980). "The Extreme Value Method for Estimating the Variance of the Rate of Return." *Journal of Business*, 53(1), 61-65. -- Garman, M. B., & Klass, M. J. (1980). "On the Estimation of Security Price Volatilities from Historical Data." *Journal of Business*, 53(1), 67-78. \ No newline at end of file +- Garman, M. B., & Klass, M. J. (1980). "On the Estimation of Security Price Volatilities from Historical Data." *Journal of Business*, 53(1), 67-78. diff --git a/lib/volume/adl/Adl.md b/lib/volume/adl/Adl.md index 85e9eaaf..2046e2ff 100644 --- a/lib/volume/adl/Adl.md +++ b/lib/volume/adl/Adl.md @@ -1,5 +1,22 @@ # ADL: Accumulation/Distribution Line +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Volume | +| **Inputs** | OHLCV bar (TBar) | +| **Parameters** | None | +| **Outputs** | Single series (ADL) | +| **Output range** | Unbounded | +| **Warmup** | 1 bar | + +### TL;DR + +- The Accumulation/Distribution Line (ADL) is the bedrock of volume analysis. +- No configurable parameters; computation is stateless per bar. +- Output range: Unbounded. +- Requires 1 bar of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "Volume precedes price." — Old Wall Street Adage The Accumulation/Distribution Line (ADL) is the bedrock of volume analysis. It attempts to answer a single, vital question: "Are the big players buying or selling?" diff --git a/lib/volume/adosc/Adosc.md b/lib/volume/adosc/Adosc.md index 35452fea..5a2adfa9 100644 --- a/lib/volume/adosc/Adosc.md +++ b/lib/volume/adosc/Adosc.md @@ -1,5 +1,22 @@ # ADOSC: Chaikin A/D Oscillator +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Volume | +| **Inputs** | OHLCV bar (TBar) | +| **Parameters** | `fastPeriod` (default 3), `slowPeriod` (default 10) | +| **Outputs** | Single series (Adosc) | +| **Output range** | Unbounded | +| **Warmup** | `slowPeriod` bars | + +### TL;DR + +- The Chaikin Oscillator (ADOSC) is an indicator of an indicator. +- Parameterized by `fastperiod` (default 3), `slowperiod` (default 10). +- Output range: Unbounded. +- Requires `slowPeriod` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "Momentum precedes price. Volume momentum precedes price momentum." The Chaikin Oscillator (ADOSC) is an indicator of an indicator. It applies the MACD formula to the Accumulation/Distribution Line (ADL) instead of the price. diff --git a/lib/volume/aobv/Aobv.md b/lib/volume/aobv/Aobv.md index bdda90bc..2be193cb 100644 --- a/lib/volume/aobv/Aobv.md +++ b/lib/volume/aobv/Aobv.md @@ -1,5 +1,22 @@ # AOBV: Archer On-Balance Volume +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Volume | +| **Inputs** | OHLCV bar (TBar) | +| **Parameters** | None | +| **Outputs** | Multiple series (LastFast, LastSlow) | +| **Output range** | Unbounded | +| **Warmup** | `> SlowPeriod` bars | + +### TL;DR + +- Archer On-Balance Volume (AOBV) applies dual exponential smoothing to the classic On-Balance Volume indicator, creating a responsive yet noise-filt... +- No configurable parameters; computation is stateless per bar. +- Output range: Unbounded. +- Requires `> SlowPeriod` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "OBV told me what was happening. AOBV told me when to act." — Adapted trader wisdom Archer On-Balance Volume (AOBV) applies dual exponential smoothing to the classic On-Balance Volume indicator, creating a responsive yet noise-filtered momentum signal. The intersection of fast and slow EMAs provides actionable crossover signals while preserving OBV's core insight: volume precedes price. diff --git a/lib/volume/cmf/Cmf.md b/lib/volume/cmf/Cmf.md index 83aa2cf3..fe09af19 100644 --- a/lib/volume/cmf/Cmf.md +++ b/lib/volume/cmf/Cmf.md @@ -1,5 +1,22 @@ # CMF: Chaikin Money Flow +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Volume | +| **Inputs** | OHLCV bar (TBar) | +| **Parameters** | `period` (default 20) | +| **Outputs** | Single series (CMF) | +| **Output range** | Unbounded | +| **Warmup** | `> period` bars | + +### TL;DR + +- Chaikin Money Flow (CMF) is the normalized cousin of the Accumulation/Distribution Line. +- Parameterized by `period` (default 20). +- Output range: Unbounded. +- Requires `> period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "Money flow tells you what the big players are doing. CMF tells you if they're winning." — Marc Chaikin Chaikin Money Flow (CMF) is the normalized cousin of the Accumulation/Distribution Line. While ADL is cumulative and unbounded, CMF oscillates between -1 and +1, measuring the persistence of buying or selling pressure over a rolling window. diff --git a/lib/volume/efi/Efi.md b/lib/volume/efi/Efi.md index 497ce734..e89f91e6 100644 --- a/lib/volume/efi/Efi.md +++ b/lib/volume/efi/Efi.md @@ -1,5 +1,22 @@ # EFI: Elder's Force Index +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Volume | +| **Inputs** | OHLCV bar (TBar) | +| **Parameters** | `period` (default 13) | +| **Outputs** | Single series (EFI) | +| **Output range** | Unbounded | +| **Warmup** | `> period` bars | + +### TL;DR + +- Elder's Force Index (EFI) quantifies the buying and selling pressure behind price movements by multiplying price change by volume. +- Parameterized by `period` (default 13). +- Output range: Unbounded. +- Requires `> period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "Force Index combines price movement with volume to measure the power behind every move. It's the market's polygraph test." — Dr. Alexander Elder Elder's Force Index (EFI) quantifies the buying and selling pressure behind price movements by multiplying price change by volume. Large positive values indicate strong buying pressure (bulls in control), while large negative values reveal strong selling pressure (bears dominant). @@ -152,4 +169,4 @@ Note: Most libraries use standard EMA without bias correction, causing warmup di - Elder, A. (1993). "Trading for a Living." John Wiley & Sons. - Elder, A. (2002). "Come Into My Trading Room." John Wiley & Sons. - StockCharts. "Force Index." [Technical Indicators](https://school.stockcharts.com/doku.php?id=technical_indicators:force_index) -- Investopedia. "Force Index Definition." [Technical Analysis](https://www.investopedia.com/terms/f/force-index.asp) \ No newline at end of file +- Investopedia. "Force Index Definition." [Technical Analysis](https://www.investopedia.com/terms/f/force-index.asp) diff --git a/lib/volume/eom/Eom.md b/lib/volume/eom/Eom.md index 764f92ca..ffdea07a 100644 --- a/lib/volume/eom/Eom.md +++ b/lib/volume/eom/Eom.md @@ -1,5 +1,22 @@ # EOM: Ease of Movement +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Volume | +| **Inputs** | OHLCV bar (TBar) | +| **Parameters** | `period` (default 14), `volumeScale` (default 10000) | +| **Outputs** | Single series (Eom) | +| **Output range** | Unbounded | +| **Warmup** | `period + 1` bars | + +### TL;DR + +- Ease of Movement (EOM) quantifies how easily price moves relative to volume. +- Parameterized by `period` (default 14), `volumescale` (default 10000). +- Output range: Unbounded. +- Requires `period + 1` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "Ease of Movement reveals when price advances effortlessly versus when it struggles against resistance. It's the market's accelerometer." — Richard W. Arms Jr. Ease of Movement (EOM) quantifies how easily price moves relative to volume. High positive values indicate price is advancing with little resistance (low volume relative to price range), while high negative values reveal price declining easily. Values near zero suggest price is meeting resistance, requiring substantial volume to produce movement. @@ -171,4 +188,4 @@ Note: External library implementations vary in their handling of volume scaling - Arms, R.W. Jr. (1994). "Trading Without Fear." John Wiley & Sons. - StockCharts. "Ease of Movement (EMV)." [Technical Indicators](https://school.stockcharts.com/doku.php?id=technical_indicators:ease_of_movement_emv) - Investopedia. "Ease of Movement Indicator." [Technical Analysis](https://www.investopedia.com/terms/e/easeofmovement.asp) -- TradingView Wiki. "Ease of Movement." [Pine Script Reference](https://www.tradingview.com/pine-script-reference/) \ No newline at end of file +- TradingView Wiki. "Ease of Movement." [Pine Script Reference](https://www.tradingview.com/pine-script-reference/) diff --git a/lib/volume/evwma/Evwma.md b/lib/volume/evwma/Evwma.md index 6c4a8f4d..c6947271 100644 --- a/lib/volume/evwma/Evwma.md +++ b/lib/volume/evwma/Evwma.md @@ -1,5 +1,22 @@ # EVWMA: Elastic Volume Weighted Moving Average +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Volume | +| **Inputs** | OHLCV bar (TBar) | +| **Parameters** | `period` (default 20) | +| **Outputs** | Single series (EVWMA) | +| **Output range** | Unbounded | +| **Warmup** | `> period` bars | + +### TL;DR + +- EVWMA (Elastic Volume Weighted Moving Average) is a volume-adaptive moving average that weights each bar's contribution to the average by its volum... +- Parameterized by `period` (default 20). +- Output range: Unbounded. +- Requires `> period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "Volume is the one technical indicator that never lies." — Joe Granville ## Introduction diff --git a/lib/volume/iii/Iii.md b/lib/volume/iii/Iii.md index 12a21d8b..122ad448 100644 --- a/lib/volume/iii/Iii.md +++ b/lib/volume/iii/Iii.md @@ -1,5 +1,22 @@ # III: Intraday Intensity Index +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Volume | +| **Inputs** | OHLCV bar (TBar) | +| **Parameters** | `period` (default 14), `cumulative` (default false) | +| **Outputs** | Single series (III) | +| **Output range** | Unbounded | +| **Warmup** | `period` bars | + +### TL;DR + +- The Intraday Intensity Index (III) measures buying and selling pressure by analyzing where the close price falls within the high-low range, weighte... +- Parameterized by `period` (default 14), `cumulative` (default false). +- Output range: Unbounded. +- Requires `period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "Where the close lands within the day's range tells you who won the battle—bulls or bears. Volume tells you how hard they fought." The Intraday Intensity Index (III) measures buying and selling pressure by analyzing where the close price falls within the high-low range, weighted by volume. Originally developed by David Bostian, this indicator quantifies whether money is flowing into or out of a security on an intraday basis. Values range from -1 (close at low, maximum selling pressure) to +1 (close at high, maximum buying pressure), multiplied by volume for magnitude. @@ -132,4 +149,4 @@ Validation focuses on internal consistency (streaming vs batch vs span modes). ## References - Bostian, D. "Intraday Intensity Index." *Technical Analysis of Stocks & Commodities*. -- Arms, R. W. (1989). "The Arms Index (TRIN)." *Dow Jones-Irwin*. \ No newline at end of file +- Arms, R. W. (1989). "The Arms Index (TRIN)." *Dow Jones-Irwin*. diff --git a/lib/volume/kvo/Kvo.md b/lib/volume/kvo/Kvo.md index 03efbb59..ad385d76 100644 --- a/lib/volume/kvo/Kvo.md +++ b/lib/volume/kvo/Kvo.md @@ -1,5 +1,22 @@ # KVO: Klinger Volume Oscillator +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Volume | +| **Inputs** | OHLCV bar (TBar) | +| **Parameters** | `fastPeriod` (default 34), `slowPeriod` (default 55), `signalPeriod` (default 13) | +| **Outputs** | Single series (Kvo) | +| **Output range** | Unbounded | +| **Warmup** | `slowPeriod` bars | + +### TL;DR + +- The Klinger Volume Oscillator (KVO), developed by Stephen Klinger in the 1970s, measures the long-term trend of money flow while remaining sensitiv... +- Parameterized by `fastperiod` (default 34), `slowperiod` (default 55), `signalperiod` (default 13). +- Output range: Unbounded. +- Requires `slowPeriod` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "Volume is the fuel that drives the market train." The Klinger Volume Oscillator (KVO), developed by Stephen Klinger in the 1970s, measures the long-term trend of money flow while remaining sensitive to short-term fluctuations. Unlike simple volume indicators, KVO incorporates price direction and range into its volume analysis, creating a comprehensive measure of buying and selling pressure that can identify divergences before they appear in price action. @@ -167,4 +184,4 @@ $$ - Klinger, S. (1977). "Summing Up Volume." *Stocks & Commodities Magazine*. - Murphy, J. (1999). *Technical Analysis of the Financial Markets*. New York Institute of Finance. -- https://github.com/mihakralj/pinescript/blob/main/indicators/volume/kvo.md \ No newline at end of file +- https://github.com/mihakralj/pinescript/blob/main/indicators/volume/kvo.md diff --git a/lib/volume/mfi/Mfi.md b/lib/volume/mfi/Mfi.md index 3a26b764..4dbfca2c 100644 --- a/lib/volume/mfi/Mfi.md +++ b/lib/volume/mfi/Mfi.md @@ -1,5 +1,22 @@ # MFI: Money Flow Index +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Volume | +| **Inputs** | OHLCV bar (TBar) | +| **Parameters** | `period` (default 14) | +| **Outputs** | Single series (Mfi) | +| **Output range** | Unbounded | +| **Warmup** | `> period` bars | + +### TL;DR + +- Money Flow Index is the volume-weighted cousin of RSI. +- Parameterized by `period` (default 14). +- Output range: Unbounded. +- Requires `> period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "Volume confirms price, but money flow confirms intent." — Gene Quong & Avrum Soudack Money Flow Index is the volume-weighted cousin of RSI. While RSI measures the momentum of price changes alone, MFI incorporates volume to determine whether the price movement has conviction behind it. The result is an oscillator that can identify when strong hands are accumulating or distributing. @@ -142,4 +159,4 @@ The TP and RMF calculations are fully vectorizable. The directional classificati - Quong, G. & Soudack, A. (1989). "Money Flow Index." *Technical Analysis of Stocks & Commodities*. - Investopedia. "Money Flow Index (MFI)." [Definition](https://www.investopedia.com/terms/m/mfi.asp) -- StockCharts. "Money Flow Index (MFI)." [Technical Indicators](https://school.stockcharts.com/doku.php?id=technical_indicators:money_flow_index_mfi) \ No newline at end of file +- StockCharts. "Money Flow Index (MFI)." [Technical Indicators](https://school.stockcharts.com/doku.php?id=technical_indicators:money_flow_index_mfi) diff --git a/lib/volume/nvi/Nvi.md b/lib/volume/nvi/Nvi.md index 703389b2..5e90654d 100644 --- a/lib/volume/nvi/Nvi.md +++ b/lib/volume/nvi/Nvi.md @@ -1,5 +1,22 @@ # NVI: Negative Volume Index +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Volume | +| **Inputs** | OHLCV bar (TBar) | +| **Parameters** | `startValue` (default 100.0) | +| **Outputs** | Single series (Nvi) | +| **Output range** | Unbounded | +| **Warmup** | `> 2` bars | + +### TL;DR + +- The Negative Volume Index tracks price changes exclusively on days when trading volume decreases compared to the previous day. +- Parameterized by `startvalue` (default 100.0). +- Output range: Unbounded. +- Requires `> 2` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "Low volume suggests smart money is at work; high volume days are for the crowd." — Norman Fosback The Negative Volume Index tracks price changes exclusively on days when trading volume decreases compared to the previous day. The underlying theory: institutional investors—the "smart money"—prefer to accumulate or distribute positions during quiet, low-volume periods, while retail traders drive high-volume days with more emotional, less informed decisions. @@ -179,4 +196,4 @@ NVI and PVI provide complementary signals: - Fosback, N. (1976). *Stock Market Logic*. Institute for Econometric Research. - Investopedia. "Negative Volume Index (NVI)." [Definition](https://www.investopedia.com/terms/n/nvi.asp) - StockCharts. "Negative Volume Index (NVI)." [Technical Indicators](https://school.stockcharts.com/doku.php?id=technical_indicators:negative_volume_index) -- TradingView. "PineScript ta.nvi()." [Reference](https://www.tradingview.com/pine-script-reference/v5/#fun_ta{dot}nvi) \ No newline at end of file +- TradingView. "PineScript ta.nvi()." [Reference](https://www.tradingview.com/pine-script-reference/v5/#fun_ta{dot}nvi) diff --git a/lib/volume/obv/Obv.md b/lib/volume/obv/Obv.md index 6a6deb0c..1b362a05 100644 --- a/lib/volume/obv/Obv.md +++ b/lib/volume/obv/Obv.md @@ -1,5 +1,22 @@ # OBV: On Balance Volume +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Volume | +| **Inputs** | OHLCV bar (TBar) | +| **Parameters** | None | +| **Outputs** | Single series (OBV) | +| **Output range** | Unbounded | +| **Warmup** | `> 2` bars | + +### TL;DR + +- On Balance Volume distills the relationship between price and volume into a single cumulative indicator. +- No configurable parameters; computation is stateless per bar. +- Output range: Unbounded. +- Requires `> 2` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "Volume is the fuel that drives price." — Joseph Granville On Balance Volume distills the relationship between price and volume into a single cumulative indicator. The premise is elegantly simple: volume flows into a security when it closes higher, and flows out when it closes lower. OBV tracks this flow as a running total, creating a momentum indicator that often leads price movements. @@ -180,4 +197,4 @@ The slope of OBV indicates buying/selling intensity: - Murphy, J. (1999). *Technical Analysis of the Financial Markets*. New York Institute of Finance. - Investopedia. "On-Balance Volume (OBV)." [Definition](https://www.investopedia.com/terms/o/onbalancevolume.asp) - StockCharts. "On Balance Volume (OBV)." [Technical Indicators](https://school.stockcharts.com/doku.php?id=technical_indicators:on_balance_volume_obv) -- TradingView. "PineScript ta.obv()." [Reference](https://www.tradingview.com/pine-script-reference/v5/#fun_ta{dot}obv) \ No newline at end of file +- TradingView. "PineScript ta.obv()." [Reference](https://www.tradingview.com/pine-script-reference/v5/#fun_ta{dot}obv) diff --git a/lib/volume/pvd/Pvd.md b/lib/volume/pvd/Pvd.md index b4444667..186c8d90 100644 --- a/lib/volume/pvd/Pvd.md +++ b/lib/volume/pvd/Pvd.md @@ -1,5 +1,22 @@ # PVD: Price Volume Divergence +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Volume | +| **Inputs** | OHLCV bar (TBar) | +| **Parameters** | `pricePeriod` (default 14), `volumePeriod` (default 14), `smoothingPeriod` (default 3) | +| **Outputs** | Single series (Pvd) | +| **Output range** | Unbounded | +| **Warmup** | 1 bar | + +### TL;DR + +- Price Volume Divergence (PVD) quantifies the disagreement between price momentum and volume momentum. +- Parameterized by `priceperiod` (default 14), `volumeperiod` (default 14), `smoothingperiod` (default 3). +- Output range: Unbounded. +- Requires 1 bar of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "When price and volume disagree, one of them is lying." Price Volume Divergence (PVD) quantifies the disagreement between price momentum and volume momentum. The indicator identifies situations where price movement lacks volume confirmation—a classic warning signal that the current trend may be weakening or about to reverse. @@ -184,4 +201,4 @@ PVD is a custom indicator not found in standard technical analysis libraries. Va - Dow, C. (1900-1902). *Wall Street Journal* editorials on price-volume relationships. - Murphy, J. J. (1999). *Technical Analysis of the Financial Markets*. New York Institute of Finance. -- Achelis, S. B. (2001). *Technical Analysis from A to Z*. McGraw-Hill. \ No newline at end of file +- Achelis, S. B. (2001). *Technical Analysis from A to Z*. McGraw-Hill. diff --git a/lib/volume/pvi/Pvi.md b/lib/volume/pvi/Pvi.md index 87728a4c..5c8454b5 100644 --- a/lib/volume/pvi/Pvi.md +++ b/lib/volume/pvi/Pvi.md @@ -1,5 +1,22 @@ # PVI: Positive Volume Index +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Volume | +| **Inputs** | OHLCV bar (TBar) | +| **Parameters** | `startValue` (default 100.0) | +| **Outputs** | Single series (Pvi) | +| **Output range** | Unbounded | +| **Warmup** | `> 2` bars | + +### TL;DR + +- The Positive Volume Index tracks price changes exclusively on days when trading volume increases compared to the previous day. +- Parameterized by `startvalue` (default 100.0). +- Output range: Unbounded. +- Requires `> 2` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "High volume days reveal where retail traders swarm; smart money prefers the quiet." — Norman Fosback The Positive Volume Index tracks price changes exclusively on days when trading volume increases compared to the previous day. The underlying theory: retail investors—the "uninformed crowd"—drive high-volume trading days, often reacting emotionally to news and price movements. Institutional investors prefer to operate during quieter periods to avoid moving markets. @@ -178,4 +195,4 @@ The danger signal: **PVI rising while NVI falling**. Retail enthusiasm without i - Fosback, N. (1976). *Stock Market Logic*. Institute for Econometric Research. - Investopedia. "Positive Volume Index (PVI)." [Definition](https://www.investopedia.com/terms/p/pvi.asp) - StockCharts. "Positive Volume Index (PVI)." [Technical Indicators](https://school.stockcharts.com/doku.php?id=technical_indicators:positive_volume_index) -- TradingView. "PineScript ta.pvi()." [Reference](https://www.tradingview.com/pine-script-reference/v5/#fun_ta{dot}pvi) \ No newline at end of file +- TradingView. "PineScript ta.pvi()." [Reference](https://www.tradingview.com/pine-script-reference/v5/#fun_ta{dot}pvi) diff --git a/lib/volume/pvo/Pvo.md b/lib/volume/pvo/Pvo.md index b0e01a03..91702abe 100644 --- a/lib/volume/pvo/Pvo.md +++ b/lib/volume/pvo/Pvo.md @@ -1,5 +1,22 @@ # PVO: Percentage Volume Oscillator +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Volume | +| **Inputs** | OHLCV bar (TBar) | +| **Parameters** | `fastPeriod` (default 12), `slowPeriod` (default 26), `signalPeriod` (default 9) | +| **Outputs** | Multiple series (Signal, Histogram) | +| **Output range** | Unbounded | +| **Warmup** | `slowPeriod` bars | + +### TL;DR + +- The Percentage Volume Oscillator (PVO) measures the difference between two exponential moving averages of volume, expressed as a percentage of the ... +- Parameterized by `fastperiod` (default 12), `slowperiod` (default 26), `signalperiod` (default 9). +- Output range: Unbounded. +- Requires `slowPeriod` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "Volume precedes price—PVO measures whether the market is inhaling or exhaling." The Percentage Volume Oscillator (PVO) measures the difference between two exponential moving averages of volume, expressed as a percentage of the slower EMA. Essentially the MACD of volume, PVO identifies whether volume is expanding (accumulation) or contracting (distribution) relative to its recent history. This percentage normalization makes it comparable across instruments with vastly different volume profiles. @@ -196,4 +213,4 @@ PVO's recursive EMA structure limits SIMD parallelization. The span-based `Calcu - Murphy, J. (1999). *Technical Analysis of the Financial Markets*. New York Institute of Finance. - Achelis, S. (2001). *Technical Analysis from A to Z*. McGraw-Hill. - https://school.stockcharts.com/doku.php?id=technical_indicators:percentage_volume_oscillator_pvo -- https://github.com/mihakralj/pinescript/blob/main/indicators/volume/pvo.md \ No newline at end of file +- https://github.com/mihakralj/pinescript/blob/main/indicators/volume/pvo.md diff --git a/lib/volume/pvr/Pvr.md b/lib/volume/pvr/Pvr.md index ddb46d56..095a280c 100644 --- a/lib/volume/pvr/Pvr.md +++ b/lib/volume/pvr/Pvr.md @@ -1,5 +1,22 @@ # PVR: Price Volume Rank +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Volume | +| **Inputs** | OHLCV bar (TBar) | +| **Parameters** | None | +| **Outputs** | Single series (PVR) | +| **Output range** | Unbounded | +| **Warmup** | 1 bar | + +### TL;DR + +- Price Volume Rank distills the price-volume relationship into a simple categorical indicator. +- No configurable parameters; computation is stateless per bar. +- Output range: Unbounded. +- Requires 1 bar of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "The relationship between price and volume reveals the conviction behind market moves." — Technical Analysis Axiom Price Volume Rank distills the price-volume relationship into a simple categorical indicator. Rather than producing a continuous value, PVR returns one of five discrete states (0-4) that classify the current bar's price and volume behavior relative to the previous bar. This creates an instant "market condition" snapshot. @@ -187,4 +204,4 @@ Track PVR distribution over rolling windows: - Arms, R. (1989). *Volume Cycles in the Stock Market*. Equis International. - Blau, W. (1995). *Momentum, Direction, and Divergence*. Wiley. - Elder, A. (1993). *Trading for a Living*. Wiley. -- Murphy, J. (1999). *Technical Analysis of the Financial Markets*. New York Institute of Finance. \ No newline at end of file +- Murphy, J. (1999). *Technical Analysis of the Financial Markets*. New York Institute of Finance. diff --git a/lib/volume/pvt/Pvt.md b/lib/volume/pvt/Pvt.md index e9b6a8d4..8356f4c5 100644 --- a/lib/volume/pvt/Pvt.md +++ b/lib/volume/pvt/Pvt.md @@ -1,5 +1,22 @@ # PVT: Price Volume Trend +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Volume | +| **Inputs** | OHLCV bar (TBar) | +| **Parameters** | None | +| **Outputs** | Single series (PVT) | +| **Output range** | Unbounded | +| **Warmup** | `> 2` bars | + +### TL;DR + +- Price Volume Trend refines the OBV concept by weighting volume according to the percentage price change rather than using an all-or-nothing approach. +- No configurable parameters; computation is stateless per bar. +- Output range: Unbounded. +- Requires `> 2` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "Volume tells you about the intensity of price moves, but PVT tells you what volume is actually accomplishing." — Unknown Price Volume Trend refines the OBV concept by weighting volume according to the percentage price change rather than using an all-or-nothing approach. Where OBV assigns the entire bar's volume to either buyers or sellers, PVT scales the volume contribution by the relative price movement—a 1% move adds only 1% of volume to the running total. @@ -200,4 +217,4 @@ The default signal period is typically 14-21 bars. - Murphy, J. (1999). *Technical Analysis of the Financial Markets*. New York Institute of Finance. - Investopedia. "Price Volume Trend (PVT)." [Definition](https://www.investopedia.com/terms/p/pricevolumetrend.asp) - StockCharts. "Price Volume Trend." [Technical Indicators](https://school.stockcharts.com/doku.php?id=technical_indicators:price_volume_trend_pvt) -- TradingView. "Volume Indicators." [Reference](https://www.tradingview.com/scripts/volume/) \ No newline at end of file +- TradingView. "Volume Indicators." [Reference](https://www.tradingview.com/scripts/volume/) diff --git a/lib/volume/tvi/Tvi.md b/lib/volume/tvi/Tvi.md index 458678ca..8a9f5731 100644 --- a/lib/volume/tvi/Tvi.md +++ b/lib/volume/tvi/Tvi.md @@ -1,5 +1,22 @@ # TVI: Trade Volume Index +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Volume | +| **Inputs** | OHLCV bar (TBar) | +| **Parameters** | `minTick` (default 0.125) | +| **Outputs** | Single series (Tvi) | +| **Output range** | Unbounded | +| **Warmup** | `> 2` bars | + +### TL;DR + +- Trade Volume Index refines the relationship between price and volume by introducing a threshold filter. +- Parameterized by `mintick` (default 0.125). +- Output range: Unbounded. +- Requires `> 2` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "The direction of money flow matters more than the magnitude of price change." — William Blau Trade Volume Index refines the relationship between price and volume by introducing a threshold filter. Unlike OBV which responds to any price change, TVI only changes direction when price movement exceeds a minimum tick threshold. This "sticky direction" behavior filters out noise from insignificant price fluctuations, allowing the indicator to better capture genuine accumulation and distribution. @@ -215,4 +232,4 @@ The minTick should generally match or exceed the instrument's minimum price incr - Blau, W. (1995). *Momentum, Direction, and Divergence*. Wiley. - Blau, W. (1993). "The Trade Volume Index." *Technical Analysis of Stocks & Commodities*. - Achelis, S. (2001). *Technical Analysis from A to Z*. McGraw-Hill. -- TradingView. "PineScript TVI Implementation." Community Scripts. \ No newline at end of file +- TradingView. "PineScript TVI Implementation." Community Scripts. diff --git a/lib/volume/twap/Twap.md b/lib/volume/twap/Twap.md index 89e8e66b..0ecccb0f 100644 --- a/lib/volume/twap/Twap.md +++ b/lib/volume/twap/Twap.md @@ -1,5 +1,22 @@ # TWAP: Time Weighted Average Price +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Volume | +| **Inputs** | OHLCV bar (TBar) | +| **Parameters** | `period` (default DefaultPeriod) | +| **Outputs** | Single series (TWAP) | +| **Output range** | Unbounded | +| **Warmup** | `> 1` bars | + +### TL;DR + +- Time Weighted Average Price (TWAP) calculates the average price over a period by giving equal weight to each price point, regardless of volume. +- Parameterized by `period` (default defaultperiod). +- Output range: Unbounded. +- Requires `> 1` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "Equal time, equal weight—the simplest benchmark refuses to let any single moment dominate the conversation." — Anonymous Quant Time Weighted Average Price (TWAP) calculates the average price over a period by giving equal weight to each price point, regardless of volume. Unlike VWAP which emphasizes high-volume periods, TWAP treats every moment as equally important. This makes it a pure temporal benchmark—ideal for evaluating execution quality when volume patterns could bias the analysis. @@ -255,4 +272,4 @@ Target: Minimize absolute slippage to achieve the unbiased average price. - Almgren, R., & Chriss, N. (2001). "Optimal Execution of Portfolio Transactions." *Journal of Risk*. - Berkowitz, S., Logue, D., & Noser, E. (1988). "The Total Cost of Transactions on the NYSE." *Journal of Finance*. - Kissell, R., & Glantz, M. (2003). *Optimal Trading Strategies*. AMACOM. -- TradingView. "PineScript TWAP Implementation." Community Scripts. \ No newline at end of file +- TradingView. "PineScript TWAP Implementation." Community Scripts. diff --git a/lib/volume/va/Va.md b/lib/volume/va/Va.md index 62609785..2762ec95 100644 --- a/lib/volume/va/Va.md +++ b/lib/volume/va/Va.md @@ -1,5 +1,22 @@ # VA: Volume Accumulation +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Volume | +| **Inputs** | OHLCV bar (TBar) | +| **Parameters** | None | +| **Outputs** | Single series (VA) | +| **Output range** | Unbounded | +| **Warmup** | `> 1` bars | + +### TL;DR + +- Volume Accumulation (VA) measures the cumulative flow of volume weighted by where price closes relative to the bar's midpoint. +- No configurable parameters; computation is stateless per bar. +- Output range: Unbounded. +- Requires `> 1` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "Volume tells you who's winning the argument between bulls and bears—VA keeps a running tally of the score." — Anonymous Trader Volume Accumulation (VA) measures the cumulative flow of volume weighted by where price closes relative to the bar's midpoint. When price closes above the midpoint, volume is considered buying pressure; when below, selling pressure. The cumulative sum reveals the net directional conviction of market participants over time. @@ -230,4 +247,4 @@ var smoothedVa = new Ema(5); // 5-period smoothing - Williams, L. (1979). "How I Made One Million Dollars Last Year Trading Commodities." Windsor Books. - Granville, J. (1976). "Granville's New Strategy of Daily Stock Market Timing." Prentice-Hall. - Achelis, S. (2000). "Technical Analysis from A to Z." McGraw-Hill. -- TradingView. "PineScript Volume Accumulation." Community Reference. \ No newline at end of file +- TradingView. "PineScript Volume Accumulation." Community Reference. diff --git a/lib/volume/vf/Vf.md b/lib/volume/vf/Vf.md index c76a20c4..461e71bc 100644 --- a/lib/volume/vf/Vf.md +++ b/lib/volume/vf/Vf.md @@ -1,5 +1,22 @@ # VF: Volume Force +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Volume | +| **Inputs** | OHLCV bar (TBar) | +| **Parameters** | `period` (default 14) | +| **Outputs** | Single series (Vf) | +| **Output range** | Unbounded | +| **Warmup** | `> period` bars | + +### TL;DR + +- Volume Force (VF) quantifies the strength of volume behind price movements by multiplying price change by volume and applying EMA smoothing with wa... +- Parameterized by `period` (default 14). +- Output range: Unbounded. +- Requires `> period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "Price without volume is like a punch without body weight behind it—VF measures the momentum of conviction." — Anonymous Quant Volume Force (VF) quantifies the strength of volume behind price movements by multiplying price change by volume and applying EMA smoothing with warmup compensation. The result is a momentum-style oscillator that distinguishes between genuine volume-backed moves and hollow price action. @@ -280,4 +297,4 @@ VF occupies a middle ground: more responsive than OBV/CMF (not cumulative), smoo - Elder, A. (1993). "Trading for a Living." John Wiley & Sons. - Ehlers, J. (2001). "Rocket Science for Traders." John Wiley & Sons. - Murphy, J. (1999). "Technical Analysis of the Financial Markets." New York Institute of Finance. -- TradingView. "PineScript Volume Force." Community Reference. \ No newline at end of file +- TradingView. "PineScript Volume Force." Community Reference. diff --git a/lib/volume/vo/Vo.md b/lib/volume/vo/Vo.md index 1bade6ab..e975d808 100644 --- a/lib/volume/vo/Vo.md +++ b/lib/volume/vo/Vo.md @@ -1,5 +1,22 @@ # VO: Volume Oscillator +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Volume | +| **Inputs** | OHLCV bar (TBar) | +| **Parameters** | `shortPeriod` (default 5), `longPeriod` (default 10), `signalPeriod` (default 10) | +| **Outputs** | Single series (Vo) | +| **Output range** | Unbounded | +| **Warmup** | 1 bar | + +### TL;DR + +- The Volume Oscillator (VO) measures the difference between two moving averages of volume, expressed as a percentage. +- Parameterized by `shortperiod` (default 5), `longperiod` (default 10), `signalperiod` (default 10). +- Output range: Unbounded. +- Requires 1 bar of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "Volume tells us the conviction behind price moves—the oscillator reveals when that conviction is accelerating or fading." The Volume Oscillator (VO) measures the difference between two moving averages of volume, expressed as a percentage. It helps identify changes in volume trends and potential momentum shifts by comparing short-term volume activity against longer-term volume norms. @@ -167,4 +184,4 @@ With defaults (5, 10, 10): ~328 bytes per instance. - Murphy, J. J. (1999). *Technical Analysis of the Financial Markets*. New York Institute of Finance. - Achelis, S. B. (2001). *Technical Analysis from A to Z*. McGraw-Hill. -- PineScript Reference: vo.pine \ No newline at end of file +- PineScript Reference: vo.pine diff --git a/lib/volume/vroc/Vroc.md b/lib/volume/vroc/Vroc.md index 4299afad..3c6cfbbb 100644 --- a/lib/volume/vroc/Vroc.md +++ b/lib/volume/vroc/Vroc.md @@ -1,5 +1,22 @@ # VROC: Volume Rate of Change +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Volume | +| **Inputs** | OHLCV bar (TBar) | +| **Parameters** | `period` (default 12), `usePercent` (default true) | +| **Outputs** | Single series (Vroc) | +| **Output range** | Unbounded | +| **Warmup** | `> period + 1` bars | + +### TL;DR + +- VROC (Volume Rate of Change) measures the percentage or absolute change in volume over a specified lookback period. +- Parameterized by `period` (default 12), `usepercent` (default true). +- Output range: Unbounded. +- Requires `> period + 1` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "Yesterday's volume is ancient history; what matters is how fast it's changing." VROC (Volume Rate of Change) measures the percentage or absolute change in volume over a specified lookback period. Unlike moving average-based volume indicators that smooth data, VROC provides a direct comparison between current volume and historical volume, making it particularly useful for detecting sudden volume surges or contractions that may signal significant market events. @@ -129,4 +146,4 @@ Per instance: `8 bytes × (period + 1)` for the ring buffer plus ~32 bytes for s - Appel, G., & Hitschler, F. (1979). *Stock Market Trading Systems*. Dow Jones-Irwin. - Murphy, J. J. (1999). *Technical Analysis of the Financial Markets*. New York Institute of Finance. -- Achelis, S. B. (2001). *Technical Analysis from A to Z*. McGraw-Hill. \ No newline at end of file +- Achelis, S. B. (2001). *Technical Analysis from A to Z*. McGraw-Hill. diff --git a/lib/volume/vwad/Vwad.md b/lib/volume/vwad/Vwad.md index 5131d1c2..afb4bd66 100644 --- a/lib/volume/vwad/Vwad.md +++ b/lib/volume/vwad/Vwad.md @@ -1,5 +1,22 @@ # VWAD: Volume Weighted Accumulation/Distribution +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Volume | +| **Inputs** | OHLCV bar (TBar) | +| **Parameters** | `period` (default 20) | +| **Outputs** | Single series (VWAD) | +| **Output range** | Unbounded | +| **Warmup** | `> period` bars | + +### TL;DR + +- Volume Weighted Accumulation/Distribution (VWAD) takes the classic ADL concept and asks a sharper question: not just "where did the close fall in t... +- Parameterized by `period` (default 20). +- Output range: Unbounded. +- Requires `> period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "The market's memory isn't just about price—it's about who showed up with conviction." Volume Weighted Accumulation/Distribution (VWAD) takes the classic ADL concept and asks a sharper question: not just "where did the close fall in the range?" but "how significant was this bar's volume compared to recent activity?" @@ -176,4 +193,4 @@ VWAD is a proprietary indicator. Validation is performed against the PineScript ## References - Chaikin, M. (1996). "Accumulation/Distribution Line." *Technical Analysis of Stocks & Commodities*. -- QuanTAlib. "Volume Weighted Accumulation/Distribution." [PineScript Reference](https://github.com/mihakralj/pinescript/blob/main/indicators/volume/vwad.md) \ No newline at end of file +- QuanTAlib. "Volume Weighted Accumulation/Distribution." [PineScript Reference](https://github.com/mihakralj/pinescript/blob/main/indicators/volume/vwad.md) diff --git a/lib/volume/vwap/Vwap.md b/lib/volume/vwap/Vwap.md index 2b0aa871..93ea3324 100644 --- a/lib/volume/vwap/Vwap.md +++ b/lib/volume/vwap/Vwap.md @@ -1,5 +1,22 @@ # VWAP: Volume Weighted Average Price +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Volume | +| **Inputs** | OHLCV bar (TBar) | +| **Parameters** | `period` (default 0) | +| **Outputs** | Single series (VWAP) | +| **Output range** | Unbounded | +| **Warmup** | `> 1` bars | + +### TL;DR + +- VWAP (Volume Weighted Average Price) calculates the cumulative average price weighted by trading volume, typically reset at session boundaries. +- Parameterized by `period` (default 0). +- Output range: Unbounded. +- Requires `> 1` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "VWAP doesn't predict where price will go—it reveals where institutional money has already committed." VWAP (Volume Weighted Average Price) calculates the cumulative average price weighted by trading volume, typically reset at session boundaries. It represents the true average price at which a security has traded throughout the period, giving more weight to prices where higher volume occurred. This implementation supports flexible period-based resets rather than traditional session-based anchoring. @@ -167,4 +184,4 @@ VWAP implementations vary primarily in reset behavior. This implementation uses - Berkowitz, S., Logue, D., & Noser, E. (1988). "The Total Cost of Transactions on the NYSE." *Journal of Finance*. - Madhavan, A. (2002). "VWAP Strategies." *Trading*, Spring 2002. -- Kissell, R. (2006). "The Science of Algorithmic Trading and Portfolio Management." *Academic Press*. \ No newline at end of file +- Kissell, R. (2006). "The Science of Algorithmic Trading and Portfolio Management." *Academic Press*. diff --git a/lib/volume/vwma/Vwma.md b/lib/volume/vwma/Vwma.md index a197380f..8c9435e6 100644 --- a/lib/volume/vwma/Vwma.md +++ b/lib/volume/vwma/Vwma.md @@ -1,5 +1,22 @@ # VWMA: Volume Weighted Moving Average +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Volume | +| **Inputs** | OHLCV bar (TBar) | +| **Parameters** | `period` (default 20) | +| **Outputs** | Single series (VWMA) | +| **Output range** | Unbounded | +| **Warmup** | `> period` bars | + +### TL;DR + +- VWMA (Volume Weighted Moving Average) calculates a moving average where each price is weighted by its corresponding volume over a specified lookbac... +- Parameterized by `period` (default 20). +- Output range: Unbounded. +- Requires `> period` bars of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "VWMA reveals where the smart money traded—not just where price went, but where conviction backed the moves." VWMA (Volume Weighted Moving Average) calculates a moving average where each price is weighted by its corresponding volume over a specified lookback period. Unlike VWAP which accumulates from a reset point, VWMA uses a sliding window that continuously drops old values, making it a true moving average. Bars with higher volume contribute more to the average, surfacing price levels where institutional activity concentrated. @@ -165,4 +182,4 @@ For batch calculation from scratch, SIMD can parallelize: - Arms, R. (1989). "Volume Cycles in the Stock Market." Equis International. - Achelis, S. (2000). "Technical Analysis from A to Z." McGraw-Hill. -- TradingView. "Pine Script VWMA Reference." [tradingview.com](https://www.tradingview.com/pine-script-reference/v5/#fun_ta.vwma) \ No newline at end of file +- TradingView. "Pine Script VWMA Reference." [tradingview.com](https://www.tradingview.com/pine-script-reference/v5/#fun_ta.vwma) diff --git a/lib/volume/wad/Wad.md b/lib/volume/wad/Wad.md index f210b92c..12548f97 100644 --- a/lib/volume/wad/Wad.md +++ b/lib/volume/wad/Wad.md @@ -1,5 +1,22 @@ # WAD: Williams Accumulation/Distribution +| Property | Value | +| ---------------- | -------------------------------- | +| **Category** | Volume | +| **Inputs** | OHLCV bar (TBar) | +| **Parameters** | None | +| **Outputs** | Single series (WAD) | +| **Output range** | Unbounded | +| **Warmup** | 1 bar | + +### TL;DR + +- Williams Accumulation/Distribution (WAD) is Larry Williams' contribution to the volume analysis toolkit. +- No configurable parameters; computation is stateless per bar. +- Output range: Unbounded. +- Requires 1 bar of warmup before first valid output (IsHot = true). +- Validated against TA-Lib, Skender, and Tulip reference implementations where available. + > "Volume is the fuel that drives price." — Larry Williams Williams Accumulation/Distribution (WAD) is Larry Williams' contribution to the volume analysis toolkit. Unlike the standard Accumulation/Distribution Line that uses the close's position within the day's range, WAD incorporates **True Range** concepts. This gives it a different perspective on buying and selling pressure. @@ -124,4 +141,4 @@ O(1) cumulative. No window, no smoothing. The conditional branch (up day vs down ## References - Williams, L. (1979). "How I Made One Million Dollars... Last Year... Trading Commodities." Windsor Books. -- https://school.stockcharts.com/doku.php?id=technical_indicators:williams_ad \ No newline at end of file +- https://school.stockcharts.com/doku.php?id=technical_indicators:williams_ad diff --git a/ndepend/generate-badges.ps1 b/ndepend/generate-badges.ps1 index 88b87710..f26db07a 100644 --- a/ndepend/generate-badges.ps1 +++ b/ndepend/generate-badges.ps1 @@ -28,7 +28,7 @@ if (-not (Test-Path $NDBadgePath)) { if (-not (Test-Path $XmlPath)) { Write-Error "NDepend trend data XML not found at: $XmlPath" - Write-Host "Please run ndepend.ps1 first to generate analysis data" -ForegroundColor Yellow + Write-Information "Please run ndepend.ps1 first to generate analysis data" exit 1 } @@ -40,54 +40,53 @@ if (-not (Test-Path $OutputDir)) { New-Item -ItemType Directory -Path $OutputDir -Force | Out-Null } -Write-Host "=== Generating QuanTAlib Quality Badges ===" -ForegroundColor Cyan -Write-Host "Output directory: $OutputDir`n" -ForegroundColor Gray +Write-Information "=== Generating QuanTAlib Quality Badges ===" +Write-Information "Output directory: $OutputDir`n" # Selected badges for QuanTAlib README -Write-Host "Generating QuanTAlib badges..." -ForegroundColor Green +Write-Information "Generating QuanTAlib badges..." $HighValueBadges = @( @{ - Metric = "# Lines of Code" - Output = "loc.svg" + Metric = "# Lines of Code" + Output = "loc.svg" Description = "Total lines of code" }, @{ - Metric = "# Source Files" - Output = "files.svg" + Metric = "# Source Files" + Output = "files.svg" Description = "Source files" }, @{ - Metric = "# Classes" - Output = "classes.svg" + Metric = "# Classes" + Output = "classes.svg" Description = "Classes" }, @{ - Metric = "# Methods" - Output = "methods.svg" + Metric = "# Methods" + Output = "methods.svg" Description = "Methods" }, @{ - Metric = "# Public Types" - Output = "public-api.svg" + Metric = "# Public Types" + Output = "public-api.svg" Description = "Public API surface" }, @{ - Metric = "Percentage of Comments" - Output = "comments.svg" + Metric = "Percentage of Comments" + Output = "comments.svg" Description = "Comment percentage" }, @{ - Metric = "Average Cyclomatic Complexity for Methods" - Output = "complexity.svg" + Metric = "Average Cyclomatic Complexity for Methods" + Output = "complexity.svg" Description = "Average complexity" } ) foreach ($badge in $HighValueBadges) { $outputPath = Join-Path $OutputDir $badge.Output - Write-Host " [$($badge.Output)]" -ForegroundColor Cyan -NoNewline - Write-Host " $($badge.Description)" -ForegroundColor Gray + Write-Information " [$($badge.Output)] $($badge.Description)" & $NDBadgePath --xml $XmlPath --metric $badge.Metric --output $outputPath @@ -98,17 +97,17 @@ foreach ($badge in $HighValueBadges) { # Generate summary -Write-Host "`n=== Badge Generation Complete ===" -ForegroundColor Green +Write-Information "`n=== Badge Generation Complete ===" $generatedBadges = Get-ChildItem -Path $OutputDir -Filter "*.svg" -Write-Host "Generated $($generatedBadges.Count) badges in: $OutputDir" +Write-Information "Generated $($generatedBadges.Count) badges in: $OutputDir" -Write-Host "`nGenerated badges:" -ForegroundColor Green +Write-Information "`nGenerated badges:" $HighValueBadges | ForEach-Object { - Write-Host " - $($_.Output.PadRight(20)) : $($_.Description)" -ForegroundColor Gray + Write-Information " - $($_.Output.PadRight(20)) : $($_.Description)" } -Write-Host "`nMarkdown snippet for README.md:" -ForegroundColor Cyan -Write-Host @" +Write-Information "`nMarkdown snippet for README.md:" +Write-Information @" ## Quality Metrics @@ -120,4 +119,4 @@ Write-Host @" [![Comments](ndepend/badges/comments.svg)]() [![Complexity](ndepend/badges/complexity.svg)]() -"@ -ForegroundColor Gray +"@ diff --git a/ndepend/ndepend.ps1 b/ndepend/ndepend.ps1 index 7d86f871..03225120 100644 --- a/ndepend/ndepend.ps1 +++ b/ndepend/ndepend.ps1 @@ -46,7 +46,7 @@ if (-not (Test-Path $SolutionFile)) { # Helper function for section headers function Write-Section { param([string]$Message) - Write-Host "`n=== $Message ===" -ForegroundColor Cyan + Write-Information "`n=== $Message ===" } # Track analysis failure @@ -58,25 +58,25 @@ try { if (-not (Test-Path $SarifDir)) { New-Item -ItemType Directory -Path $SarifDir -Force | Out-Null } - Write-Host "SARIF directory: $SarifDir" + Write-Information "SARIF directory: $SarifDir" # Restore, clean, and build Write-Section "Cleaning and building solution (generates SARIF files)" - Write-Host "Restoring packages..." -ForegroundColor Gray + Write-Information "Restoring packages..." dotnet restore $SolutionFile -v q if ($LASTEXITCODE -ne 0) { throw "Restore failed with exit code $LASTEXITCODE" } - Write-Host "Cleaning solution..." -ForegroundColor Gray + Write-Information "Cleaning solution..." dotnet clean $SolutionFile -v q if ($LASTEXITCODE -ne 0) { throw "Clean failed with exit code $LASTEXITCODE" } - Write-Host "Removing old coverage data..." -ForegroundColor Gray + Write-Information "Removing old coverage data..." if (Test-Path $CoverageDir) { Remove-Item -Path $CoverageDir -Recurse -Force } - Write-Host "Building solution..." -ForegroundColor Gray + Write-Information "Building solution..." dotnet build $SolutionFile -c Debug --no-incremental if ($LASTEXITCODE -ne 0) { throw "Build failed with exit code $LASTEXITCODE" } @@ -103,15 +103,16 @@ try { if ($LASTEXITCODE -ne 0) { throw "Tests failed for Quantower.Tests with exit code $LASTEXITCODE" } # Find coverage files - Write-Host "`nSearching for coverage files..." -ForegroundColor Gray + Write-Information "`nSearching for coverage files..." $CoverageFiles = Get-ChildItem -Path $CoverageDir -Filter "coverage.opencover.xml" -Recurse -File | - Select-Object -ExpandProperty FullName + Select-Object -ExpandProperty FullName if (-not $CoverageFiles) { Write-Warning "No coverage files found in $CoverageDir" - } else { + } + else { $CoverageFiles | ForEach-Object { - Write-Host "Coverage file: $_" -ForegroundColor Green + Write-Information "Coverage file: $_" } } @@ -120,16 +121,18 @@ try { $InspectCodeOutput = Join-Path $SarifDir "resharper.sarif.json" $jbPath = Get-Command "jb" -ErrorAction SilentlyContinue if ($jbPath) { - Write-Host "Running InspectCode analysis..." -ForegroundColor Gray + Write-Information "Running InspectCode analysis..." jb inspectcode $SolutionFile --output=$InspectCodeOutput --format=Sarif --no-build if ($LASTEXITCODE -ne 0) { Write-Warning "InspectCode completed with exit code $LASTEXITCODE" - } else { - Write-Host "InspectCode SARIF saved to: $InspectCodeOutput" -ForegroundColor Green } - } else { + else { + Write-Information "InspectCode SARIF saved to: $InspectCodeOutput" + } + } + else { Write-Warning "JetBrains CLI (jb) not found. Skipping InspectCode analysis." - Write-Host " Install with: dotnet tool install -g JetBrains.ReSharper.GlobalTools" -ForegroundColor Gray + Write-Information " Install with: dotnet tool install -g JetBrains.ReSharper.GlobalTools" } # List SARIF files @@ -137,10 +140,11 @@ try { $SarifFiles = Get-ChildItem -Path $SarifDir -Filter "*.json" -ErrorAction SilentlyContinue if ($SarifFiles) { $SarifFiles | ForEach-Object { - Write-Host " $($_.Name) ($([math]::Round($_.Length / 1KB, 2)) KB)" -ForegroundColor Gray + Write-Information " $($_.Name) ($([math]::Round($_.Length / 1KB, 2)) KB)" } - } else { - Write-Host "No SARIF files found" -ForegroundColor Yellow + } + else { + Write-Information "No SARIF files found" } # Activate NDepend license @@ -148,7 +152,8 @@ try { if (-not [string]::IsNullOrWhiteSpace($NdependLicense)) { dotnet $NdependDll --RegLic $NdependLicense if ($LASTEXITCODE -ne 0) { Write-Warning "License activation returned exit code $LASTEXITCODE" } - } else { + } + else { Write-Warning "Skipping license activation (no license provided)" } @@ -168,17 +173,20 @@ try { $AnalysisFailed = $true } -} catch { +} +catch { Write-Error "Script failed: $_" $AnalysisFailed = $true -} finally { +} +finally { # Always deactivate license Write-Section "Deactivating NDepend license" if (-not [string]::IsNullOrWhiteSpace($NdependLicense)) { dotnet $NdependDll --UnregLic if ($LASTEXITCODE -ne 0) { Write-Warning "License deactivation returned exit code $LASTEXITCODE" } - } else { - Write-Host "Skipping license deactivation (no license provided)" -ForegroundColor Gray + } + else { + Write-Information "Skipping license deactivation (no license provided)" } # Generate badges from NDepend trend data @@ -188,9 +196,10 @@ try { $TrendMetricsDir = Join-Path $ScriptDir "NDependOut\TrendMetrics" $TrendXml = if (Test-Path $TrendMetricsDir) { Get-ChildItem -Path $TrendMetricsDir -Filter "NDependTrendData*.xml" -File | - Sort-Object Name -Descending | - Select-Object -First 1 -ExpandProperty FullName - } else { $null } + Sort-Object Name -Descending | + Select-Object -First 1 -ExpandProperty FullName + } + else { $null } $BadgeDir = Join-Path $ScriptDir "badges" if ((Test-Path $NDBadgePath) -and $TrendXml -and (Test-Path $TrendXml)) { @@ -212,18 +221,19 @@ try { $outputPath = Join-Path $BadgeDir $badge.Output & $NDBadgePath --xml $TrendXml --metric $badge.Metric --output $outputPath 2>$null if ($LASTEXITCODE -eq 0) { - Write-Host " Generated: $($badge.Output)" -ForegroundColor Gray + Write-Information " Generated: $($badge.Output)" } } - Write-Host "Badges saved to: $BadgeDir" -ForegroundColor Green - } else { - Write-Host "Skipping badge generation (NDBadge.exe or trend data not found)" -ForegroundColor Yellow + Write-Information "Badges saved to: $BadgeDir" + } + else { + Write-Information "Skipping badge generation (NDBadge.exe or trend data not found)" } Write-Section "Done" if ($AnalysisFailed) { - Write-Host "Note: Analysis completed with quality gate failures" -ForegroundColor Yellow + Write-Information "Note: Analysis completed with quality gate failures" exit 1 } } \ No newline at end of file