From 920e517ced441740a42f6a9a9101f2397e7ec3e8 Mon Sep 17 00:00:00 2001 From: Miha Kralj Date: Fri, 11 Nov 2022 09:51:57 -0800 Subject: [PATCH 1/4] workflow update --- .github/workflows/main_automation.yml | 7 +++ docs/crossovers.ipynb | 57 ++++--------------------- docs/readme.md | 61 +++++++++++++-------------- 3 files changed, 46 insertions(+), 79 deletions(-) diff --git a/.github/workflows/main_automation.yml b/.github/workflows/main_automation.yml index cf67c903..8686df9f 100644 --- a/.github/workflows/main_automation.yml +++ b/.github/workflows/main_automation.yml @@ -87,6 +87,13 @@ jobs: title: "Latest Build" files: /Quantower/Settings/Scripts/Indicators/QuanTAlib/*.dll + - name: Push package to github + if: ${{ github.ref == 'refs/heads/dev' }} + run: dotnet nuget push '.\Source\bin\Release\QuanTAlib.*.nupkg' + --api-key ${{ secrets.GITHUB_TOKEN }} + --source https://nuget.pkg.github.com/mihakralj/index.json + --skip-duplicate + - name: Push package to nuget.org if: ${{ github.ref == 'refs/heads/main' }} run: dotnet nuget push '.\Source\bin\Release\QuanTAlib.*.nupkg' diff --git a/docs/crossovers.ipynb b/docs/crossovers.ipynb index 0e185e25..f54ef389 100644 --- a/docs/crossovers.ipynb +++ b/docs/crossovers.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "code", - "execution_count": 1, + "execution_count": 51, "metadata": { "dotnet_interactive": { "language": "csharp" @@ -20,15 +20,6 @@ }, "metadata": {}, "output_type": "display_data" - }, - { - "data": { - "text/markdown": [ - "Loading extensions from `Plotly.NET.Interactive.dll`" - ] - }, - "metadata": {}, - "output_type": "display_data" } ], "source": [ @@ -43,7 +34,7 @@ }, { "cell_type": "code", - "execution_count": 49, + "execution_count": 52, "metadata": { "dotnet_interactive": { "language": "csharp" @@ -62,7 +53,7 @@ }, { "cell_type": "code", - "execution_count": 50, + "execution_count": 53, "metadata": { "dotnet_interactive": { "language": "csharp" @@ -73,42 +64,12 @@ }, "outputs": [ { - "data": { - "text/html": [ - "\n", - "
\n", - "
\r\n", - "\r\n", - "\n", - " \n", - "
\n" - ] - }, - "metadata": {}, - "output_type": "display_data" + "ename": "Error", + "evalue": "(21,5): error CS7017: Member definition, statement, or end-of-file expected", + "output_type": "error", + "traceback": [ + "(21,5): error CS7017: Member definition, statement, or end-of-file expected" + ] } ], "source": [ diff --git a/docs/readme.md b/docs/readme.md index d98f2c3b..1f973337 100644 --- a/docs/readme.md +++ b/docs/readme.md @@ -43,11 +43,11 @@ See [Getting Started](https://github.com/mihakralj/QuanTAlib/blob/main/Docs/gett | ✔️ OHL3 - (Open+High+Low)/3 | `.OHL3` ||| | ⭐ OHLC4 - Average Price | `.OHLC4` | `AVGPRICE` |️ `GetBaseQuote` | | ⭐ HLCC4 - Weighted Price | `.HLCC4` | `WCLPRICE` || -| ✔️ ZL - De-lagged price (Zero-Lag) | `ZL_Series` ||| | ⭐ MAX - Max value | `MAX_Series` | `MAX` || +| ⭐ MIN - Min value | `MIN_Series` | `MIN` || | ⛔ MID - Midpoint value || `MIDPOINT` || | ⛔ MIDP - Midpoint price || `MIDPRICE` || -| ⭐ MIN - Min value | `MIN_Series` | `MIN` || +| ⛔ SUM - Summation || `SUM` || | ⭐ ADD - Addition | `ADD_Series` | `ADD` || | ⭐ SUB - Subtraction | `SUB_Series` | `SUB` || | ⭐ MUL - Multiplication | `MUL_Series` | `MUL` || @@ -65,10 +65,10 @@ See [Getting Started](https://github.com/mihakralj/QuanTAlib/blob/main/Docs/gett | ✔️ MED - Median value | MED_Series ||| | ✔️ MSE - Mean Squared Error | MSE_Series || GetSma | | ⛔ SKEW - Skewness |||| -| ⭐ SDEV - Standard Deviation (Volatility) | SDEV_Series ||| +| ⭐ SDEV - Standard Deviation (Volatility) | SDEV_Series | STDDEV || | ✔️ SSDEV - Sample Standard Deviation | SSDEV_Series ||| | ✔️ SMAPE - Symmetric Mean Absolute Percent Error | SMAPE_Series ||| -| ✔️ VAR - Population Variance | VAR_Series ||| +| ✔️ VAR - Population Variance | VAR_Series | VAR || | ✔️ SVAR - Sample Variance | SVAR_Series ||| | ⛔ QUANT - Quantile |||| | ✔️ WMAPE - Weighted Mean Absolute Percent Error | WMAPE_Series ||| @@ -81,16 +81,20 @@ See [Getting Started](https://github.com/mihakralj/QuanTAlib/blob/main/Docs/gett | ⭐ DEMA - Double EMA Average | DEMA_Series | DEMA | GetDema | | ⭐ EMA - Exponential Moving Average | EMA_Series || GetEma | | ⛔ EPMA - Endpoint Moving Average ||| GetEpma | +| ⛔ FRAMA - Fractal Adaptive Moving Average |||| | ⛔ FWMA - Fibonacci's Weighted Moving Average |||| +| ⛔ HILO - Gann High-Low Activator |||| | ✔️ HEMA - Hull/EMA Average | HEMA_Series ||| | ⛔ Hilbert Transform Instantaneous Trendline || HT_TRENDLINE | GetHtTrendline | | ⭐ HMA - Hull Moving Average | HMA_Series || GetHma | | ⛔ HWMA - Holt-Winter Moving Average |||| | ✔️ JMA - Jurik Moving Average | JMA_Series ||| | ⭐ KAMA - Kaufman's Adaptive Moving Average | KAMA_Series | KAMA | GetKama | +| ⛔ KDJ - KDJ Indicator (trend reversal) |||| | ⛔ LSMA - Least Squares Moving Average |||| | ⭐ MACD - Moving Average Convergence/Divergence | MACD_Series | MACD | GetMacd | | ⛔ MAMA - MESA Adaptive Moving Average || MAMA | GetMama | +| ⛔ MCGD - McGinley Dynamic |||| | ⛔ MMA - Modified Moving Average |||| | ⛔ PPMA - Pivot Point Moving Average |||| | ⛔ PWMA - Pascal's Weighted Moving Average |||| @@ -101,11 +105,13 @@ See [Getting Started](https://github.com/mihakralj/QuanTAlib/blob/main/Docs/gett | ⛔ SSF - Ehler's Super Smoother Filter |||| | ⛔ SUP - Supertrend |||| | ⛔ SWMA - Symmetric Weighted Moving Average |||| -| ⛔ T3 - Tillson T3 Moving Average |||| -| ⭐ TEMA - Triple EMA Average | TEMA_Series ||| -| ⛔ TRIMA - Triangular Moving Average |||| +| ⛔ T3 - Tillson T3 Moving Average || T3 | GetT3 | +| ⭐ TEMA - Triple EMA Average | TEMA_Series | TEMA | GetTema | +| ⛔ TRIMA - Triangular Moving Average || TRIMA || +| ⛔ TSF - Time Series Forecast || TSF || | ⛔ VIDYA - Variable Index Dynamic Average |||| -| ⭐ WMA - Weighted Moving Average | WMA_Series ||| +| ⛔ VOR - Vortex Indicator |||| +| ⭐ WMA - Weighted Moving Average | WMA_Series | WMA | GetWma | | ✔️ ZLEMA - Zero Lag EMA Average | ZLEMA_Series ||| ||||| | **VOLATILITY INDICATORS** | **QuanTAlib** | **TA-LIB** | **Skender** | @@ -113,8 +119,9 @@ See [Getting Started](https://github.com/mihakralj/QuanTAlib/blob/main/Docs/gett | ⭐ ADOSC - Chaikin Accumulation Distribution Oscillator | ADOSC_Series | ADOSC| GetAdl | | ⭐ ATR - Average True Range | ATR_Series | ATR | GetAtr | | ⭐ ATRP - Average True Range Percent | ATRP_Series || GetAtr | -| ✔️ BETA - Beta coefficient || BETA | GetBeta | +| ⛔ BETA - Beta coefficient || BETA | GetBeta | | ⭐ BBANDS - Bollinger Bands® | BBANDS_Series | BBANDS | GetBollingerBands | +| ⛔ CHAND - Chandelier Exit ||| GetChandelier | | ⛔ CRSI - Connor RSI ||| GetConnorsRsi | | ⛔ DON - Donchian Channels ||| GetDonchian | | ⛔ FCB - Fractal Chaos Bands ||| GetFcb | @@ -122,11 +129,12 @@ See [Getting Started](https://github.com/mihakralj/QuanTAlib/blob/main/Docs/gett | ⛔ ICH - Ichimoku ||| GetIchimoku | | ⛔ KEL - Keltner Channels ||| GetKeltner | | ⛔ NATR - Normalized Average True Range || NATR | GetAtr | -| ⭐ RSI - Relative Strength Index | RSI_Series || +| ⛔ CHN - Price Channel Indicator |||| +| ⭐ RSI - Relative Strength Index | RSI_Series | RSI | GetRsi | | ⛔ SAR - Parabolic Stop and Reverse || SAR | GetParabolicSar | -| ⛔ SRSI - Stochastic RSI |||| +| ⛔ SRSI - Stochastic RSI || STOCHRSI | GetStochRsi | | ⛔ STARC - Starc Bands |||| -| ⭐ TR - True Range | TR_Series ||| +| ⭐ TR - True Range | TR_Series | TRANGE | GetTr | | ⛔ UI - Ulcer Index |||| | ⛔ VSTOP - Volatility Stop |||| ||||| @@ -140,9 +148,9 @@ See [Getting Started](https://github.com/mihakralj/QuanTAlib/blob/main/Docs/gett | ⛔ BOP - Balance of Power || BOP | GetBop | | ⭐ CCI - Commodity Channel Index | CCI_Series | CCI | GetCci | | ⛔ CFO - Chande Forcast Oscillator |||| -| ⛔ CMF - Chaikin Money Flow |||| | ⛔ CMO - Chande Momentum Oscillator || CMO | GetCmo | | ⛔ COG - Center of Gravity |||| +| ⛔ COPPOCK - Coppock Curve |||| | ⛔ CTI - Ehler's Correlation Trend Indicator |||| | ⛔ DPO - Detrended Price Oscillator ||| GetDpo | | ⛔ DMI - Directional Movement Index || DX | GetAdx | @@ -152,22 +160,27 @@ See [Getting Started](https://github.com/mihakralj/QuanTAlib/blob/main/Docs/gett | ⛔ KRI - Kairi Relative Index |||| | ⛔ KVO - Klinger Volume Oscillator |||| | ⛔ MFI - Money Flow Index || MFI | GetMfi | -| ⛔ ROC - Rate of Change (Momentum) || MOM | GetRoc | +| ⛔ MOM - Momentum || MOM || | ⛔ NVI - Negative Volume Index |||| | ⛔ PO - Price Oscillator |||| | ⛔ PPO - Percentage Price Oscillator || PPO || | ⛔ PMO - Price Momentum Oscillator |||| | ⛔ PVI - Positive Volume Index |||| +| ⛔ ROC - Rate of Change || MOM | GetRoc | | ⛔ RVGI - Relative Vigor Index |||| | ⛔ SMI - Stochastic Momentum Index |||| -| ⛔ STOCH - Stochastic Oscillator |||| -| ⛔ TRIX - 1-day ROC of TEMA |||| +| ⛔ STC - Schaff Trend Cycle |||| +| ⛔ STOCH - Stochastic Oscillator || STOCH | GetStoch | +| ⛔ TRIX - 1-day ROC of TEMA || TRIX | GetTrix | | ⛔ TSI - True Strength Index |||| -| ⛔ UO - Ultimate Oscillator |||| +| ⛔ UO - Ultimate Oscillator || ULTOSC | GetUltimate | +| ⛔ WILLR - Larry Williams' %R || WILLR | GetWilliamsR | | ⛔ WGAT - Williams Alligator |||| ||||| | **VOLUME INDICATORS** | **QuanTAlib** | **TA-LIB** | **Skender** | | ⛔ AOBV - Archer On-Balance Volume |||| +| ⛔ CMF - Chaikin Money Flow |||| +| ⛔ EOM - Ease of Movement |||| | ⛔ OBV - On-Balance Volume || OBV | GetObv | | ⛔ PRS - Price Relative Strength ||| | ⛔ PVOL - Price-Volume |||| @@ -177,17 +190,3 @@ See [Getting Started](https://github.com/mihakralj/QuanTAlib/blob/main/Docs/gett | ⛔ VP - Volume Profile |||| | ⛔ VWAP - Volume Weighted Average Price |||| | ⛔ VWMA - Volume Weighted Moving Average |||| -||||| -|**Unsorted** | **QuanTAlib** | **TA-LIB** | **Skender** | -| ⛔ CHN - Price Channel |||| -| ⛔ COPPOCK - Coppock Curve |||| -| ⛔ EOM - Ease of Movement |||| -| ⛔ HILO - Gann High-Low Activator |||| -| ⛔ HT - HT Trendline |||| -| ⛔ MCGD - McGinley Dynamic |||| -| ⛔ STC - Schaff Trend Cycle |||| -| ⛔ WILLR - Larry Williams' %R |||| -| ⛔ VOR - Vortex Indicator |||| -| ⛔ PVT - Pivot Points |||| -| ⛔ KDJ - KDJ Index |||| -| ⛔ CHAND - Chandelier Exit |||| From 4c963c56b2f04126163c11e27592637a2de2833a Mon Sep 17 00:00:00 2001 From: Miha Kralj Date: Fri, 11 Nov 2022 09:51:57 -0800 Subject: [PATCH 2/4] workflow update --- .github/workflows/main_automation.yml | 14 ++++++ docs/crossovers.ipynb | 57 ++++--------------------- docs/readme.md | 61 +++++++++++++-------------- 3 files changed, 53 insertions(+), 79 deletions(-) diff --git a/.github/workflows/main_automation.yml b/.github/workflows/main_automation.yml index cf67c903..d18249e0 100644 --- a/.github/workflows/main_automation.yml +++ b/.github/workflows/main_automation.yml @@ -87,6 +87,20 @@ jobs: title: "Latest Build" files: /Quantower/Settings/Scripts/Indicators/QuanTAlib/*.dll + - name: Authenticate to Github packages source + run: dotnet nuget add source + --username mihakralj + --password ${{ secrets.GITHUB_TOKEN }} + --store-password-in-clear-text + --name github "https://nuget.pkg.github.com/mihakralj/index.json" + + - name: Push package to github + if: ${{ github.ref == 'refs/heads/dev' }} + run: dotnet nuget push '.\Source\bin\Release\QuanTAlib.*.nupkg' + --source https://nuget.pkg.github.com/mihakralj/index.json + --skip-duplicate + --no-symbols + - name: Push package to nuget.org if: ${{ github.ref == 'refs/heads/main' }} run: dotnet nuget push '.\Source\bin\Release\QuanTAlib.*.nupkg' diff --git a/docs/crossovers.ipynb b/docs/crossovers.ipynb index 0e185e25..f54ef389 100644 --- a/docs/crossovers.ipynb +++ b/docs/crossovers.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "code", - "execution_count": 1, + "execution_count": 51, "metadata": { "dotnet_interactive": { "language": "csharp" @@ -20,15 +20,6 @@ }, "metadata": {}, "output_type": "display_data" - }, - { - "data": { - "text/markdown": [ - "Loading extensions from `Plotly.NET.Interactive.dll`" - ] - }, - "metadata": {}, - "output_type": "display_data" } ], "source": [ @@ -43,7 +34,7 @@ }, { "cell_type": "code", - "execution_count": 49, + "execution_count": 52, "metadata": { "dotnet_interactive": { "language": "csharp" @@ -62,7 +53,7 @@ }, { "cell_type": "code", - "execution_count": 50, + "execution_count": 53, "metadata": { "dotnet_interactive": { "language": "csharp" @@ -73,42 +64,12 @@ }, "outputs": [ { - "data": { - "text/html": [ - "\n", - "
\n", - "
\r\n", - "\r\n", - "\n", - " \n", - "
\n" - ] - }, - "metadata": {}, - "output_type": "display_data" + "ename": "Error", + "evalue": "(21,5): error CS7017: Member definition, statement, or end-of-file expected", + "output_type": "error", + "traceback": [ + "(21,5): error CS7017: Member definition, statement, or end-of-file expected" + ] } ], "source": [ diff --git a/docs/readme.md b/docs/readme.md index d98f2c3b..1f973337 100644 --- a/docs/readme.md +++ b/docs/readme.md @@ -43,11 +43,11 @@ See [Getting Started](https://github.com/mihakralj/QuanTAlib/blob/main/Docs/gett | ✔️ OHL3 - (Open+High+Low)/3 | `.OHL3` ||| | ⭐ OHLC4 - Average Price | `.OHLC4` | `AVGPRICE` |️ `GetBaseQuote` | | ⭐ HLCC4 - Weighted Price | `.HLCC4` | `WCLPRICE` || -| ✔️ ZL - De-lagged price (Zero-Lag) | `ZL_Series` ||| | ⭐ MAX - Max value | `MAX_Series` | `MAX` || +| ⭐ MIN - Min value | `MIN_Series` | `MIN` || | ⛔ MID - Midpoint value || `MIDPOINT` || | ⛔ MIDP - Midpoint price || `MIDPRICE` || -| ⭐ MIN - Min value | `MIN_Series` | `MIN` || +| ⛔ SUM - Summation || `SUM` || | ⭐ ADD - Addition | `ADD_Series` | `ADD` || | ⭐ SUB - Subtraction | `SUB_Series` | `SUB` || | ⭐ MUL - Multiplication | `MUL_Series` | `MUL` || @@ -65,10 +65,10 @@ See [Getting Started](https://github.com/mihakralj/QuanTAlib/blob/main/Docs/gett | ✔️ MED - Median value | MED_Series ||| | ✔️ MSE - Mean Squared Error | MSE_Series || GetSma | | ⛔ SKEW - Skewness |||| -| ⭐ SDEV - Standard Deviation (Volatility) | SDEV_Series ||| +| ⭐ SDEV - Standard Deviation (Volatility) | SDEV_Series | STDDEV || | ✔️ SSDEV - Sample Standard Deviation | SSDEV_Series ||| | ✔️ SMAPE - Symmetric Mean Absolute Percent Error | SMAPE_Series ||| -| ✔️ VAR - Population Variance | VAR_Series ||| +| ✔️ VAR - Population Variance | VAR_Series | VAR || | ✔️ SVAR - Sample Variance | SVAR_Series ||| | ⛔ QUANT - Quantile |||| | ✔️ WMAPE - Weighted Mean Absolute Percent Error | WMAPE_Series ||| @@ -81,16 +81,20 @@ See [Getting Started](https://github.com/mihakralj/QuanTAlib/blob/main/Docs/gett | ⭐ DEMA - Double EMA Average | DEMA_Series | DEMA | GetDema | | ⭐ EMA - Exponential Moving Average | EMA_Series || GetEma | | ⛔ EPMA - Endpoint Moving Average ||| GetEpma | +| ⛔ FRAMA - Fractal Adaptive Moving Average |||| | ⛔ FWMA - Fibonacci's Weighted Moving Average |||| +| ⛔ HILO - Gann High-Low Activator |||| | ✔️ HEMA - Hull/EMA Average | HEMA_Series ||| | ⛔ Hilbert Transform Instantaneous Trendline || HT_TRENDLINE | GetHtTrendline | | ⭐ HMA - Hull Moving Average | HMA_Series || GetHma | | ⛔ HWMA - Holt-Winter Moving Average |||| | ✔️ JMA - Jurik Moving Average | JMA_Series ||| | ⭐ KAMA - Kaufman's Adaptive Moving Average | KAMA_Series | KAMA | GetKama | +| ⛔ KDJ - KDJ Indicator (trend reversal) |||| | ⛔ LSMA - Least Squares Moving Average |||| | ⭐ MACD - Moving Average Convergence/Divergence | MACD_Series | MACD | GetMacd | | ⛔ MAMA - MESA Adaptive Moving Average || MAMA | GetMama | +| ⛔ MCGD - McGinley Dynamic |||| | ⛔ MMA - Modified Moving Average |||| | ⛔ PPMA - Pivot Point Moving Average |||| | ⛔ PWMA - Pascal's Weighted Moving Average |||| @@ -101,11 +105,13 @@ See [Getting Started](https://github.com/mihakralj/QuanTAlib/blob/main/Docs/gett | ⛔ SSF - Ehler's Super Smoother Filter |||| | ⛔ SUP - Supertrend |||| | ⛔ SWMA - Symmetric Weighted Moving Average |||| -| ⛔ T3 - Tillson T3 Moving Average |||| -| ⭐ TEMA - Triple EMA Average | TEMA_Series ||| -| ⛔ TRIMA - Triangular Moving Average |||| +| ⛔ T3 - Tillson T3 Moving Average || T3 | GetT3 | +| ⭐ TEMA - Triple EMA Average | TEMA_Series | TEMA | GetTema | +| ⛔ TRIMA - Triangular Moving Average || TRIMA || +| ⛔ TSF - Time Series Forecast || TSF || | ⛔ VIDYA - Variable Index Dynamic Average |||| -| ⭐ WMA - Weighted Moving Average | WMA_Series ||| +| ⛔ VOR - Vortex Indicator |||| +| ⭐ WMA - Weighted Moving Average | WMA_Series | WMA | GetWma | | ✔️ ZLEMA - Zero Lag EMA Average | ZLEMA_Series ||| ||||| | **VOLATILITY INDICATORS** | **QuanTAlib** | **TA-LIB** | **Skender** | @@ -113,8 +119,9 @@ See [Getting Started](https://github.com/mihakralj/QuanTAlib/blob/main/Docs/gett | ⭐ ADOSC - Chaikin Accumulation Distribution Oscillator | ADOSC_Series | ADOSC| GetAdl | | ⭐ ATR - Average True Range | ATR_Series | ATR | GetAtr | | ⭐ ATRP - Average True Range Percent | ATRP_Series || GetAtr | -| ✔️ BETA - Beta coefficient || BETA | GetBeta | +| ⛔ BETA - Beta coefficient || BETA | GetBeta | | ⭐ BBANDS - Bollinger Bands® | BBANDS_Series | BBANDS | GetBollingerBands | +| ⛔ CHAND - Chandelier Exit ||| GetChandelier | | ⛔ CRSI - Connor RSI ||| GetConnorsRsi | | ⛔ DON - Donchian Channels ||| GetDonchian | | ⛔ FCB - Fractal Chaos Bands ||| GetFcb | @@ -122,11 +129,12 @@ See [Getting Started](https://github.com/mihakralj/QuanTAlib/blob/main/Docs/gett | ⛔ ICH - Ichimoku ||| GetIchimoku | | ⛔ KEL - Keltner Channels ||| GetKeltner | | ⛔ NATR - Normalized Average True Range || NATR | GetAtr | -| ⭐ RSI - Relative Strength Index | RSI_Series || +| ⛔ CHN - Price Channel Indicator |||| +| ⭐ RSI - Relative Strength Index | RSI_Series | RSI | GetRsi | | ⛔ SAR - Parabolic Stop and Reverse || SAR | GetParabolicSar | -| ⛔ SRSI - Stochastic RSI |||| +| ⛔ SRSI - Stochastic RSI || STOCHRSI | GetStochRsi | | ⛔ STARC - Starc Bands |||| -| ⭐ TR - True Range | TR_Series ||| +| ⭐ TR - True Range | TR_Series | TRANGE | GetTr | | ⛔ UI - Ulcer Index |||| | ⛔ VSTOP - Volatility Stop |||| ||||| @@ -140,9 +148,9 @@ See [Getting Started](https://github.com/mihakralj/QuanTAlib/blob/main/Docs/gett | ⛔ BOP - Balance of Power || BOP | GetBop | | ⭐ CCI - Commodity Channel Index | CCI_Series | CCI | GetCci | | ⛔ CFO - Chande Forcast Oscillator |||| -| ⛔ CMF - Chaikin Money Flow |||| | ⛔ CMO - Chande Momentum Oscillator || CMO | GetCmo | | ⛔ COG - Center of Gravity |||| +| ⛔ COPPOCK - Coppock Curve |||| | ⛔ CTI - Ehler's Correlation Trend Indicator |||| | ⛔ DPO - Detrended Price Oscillator ||| GetDpo | | ⛔ DMI - Directional Movement Index || DX | GetAdx | @@ -152,22 +160,27 @@ See [Getting Started](https://github.com/mihakralj/QuanTAlib/blob/main/Docs/gett | ⛔ KRI - Kairi Relative Index |||| | ⛔ KVO - Klinger Volume Oscillator |||| | ⛔ MFI - Money Flow Index || MFI | GetMfi | -| ⛔ ROC - Rate of Change (Momentum) || MOM | GetRoc | +| ⛔ MOM - Momentum || MOM || | ⛔ NVI - Negative Volume Index |||| | ⛔ PO - Price Oscillator |||| | ⛔ PPO - Percentage Price Oscillator || PPO || | ⛔ PMO - Price Momentum Oscillator |||| | ⛔ PVI - Positive Volume Index |||| +| ⛔ ROC - Rate of Change || MOM | GetRoc | | ⛔ RVGI - Relative Vigor Index |||| | ⛔ SMI - Stochastic Momentum Index |||| -| ⛔ STOCH - Stochastic Oscillator |||| -| ⛔ TRIX - 1-day ROC of TEMA |||| +| ⛔ STC - Schaff Trend Cycle |||| +| ⛔ STOCH - Stochastic Oscillator || STOCH | GetStoch | +| ⛔ TRIX - 1-day ROC of TEMA || TRIX | GetTrix | | ⛔ TSI - True Strength Index |||| -| ⛔ UO - Ultimate Oscillator |||| +| ⛔ UO - Ultimate Oscillator || ULTOSC | GetUltimate | +| ⛔ WILLR - Larry Williams' %R || WILLR | GetWilliamsR | | ⛔ WGAT - Williams Alligator |||| ||||| | **VOLUME INDICATORS** | **QuanTAlib** | **TA-LIB** | **Skender** | | ⛔ AOBV - Archer On-Balance Volume |||| +| ⛔ CMF - Chaikin Money Flow |||| +| ⛔ EOM - Ease of Movement |||| | ⛔ OBV - On-Balance Volume || OBV | GetObv | | ⛔ PRS - Price Relative Strength ||| | ⛔ PVOL - Price-Volume |||| @@ -177,17 +190,3 @@ See [Getting Started](https://github.com/mihakralj/QuanTAlib/blob/main/Docs/gett | ⛔ VP - Volume Profile |||| | ⛔ VWAP - Volume Weighted Average Price |||| | ⛔ VWMA - Volume Weighted Moving Average |||| -||||| -|**Unsorted** | **QuanTAlib** | **TA-LIB** | **Skender** | -| ⛔ CHN - Price Channel |||| -| ⛔ COPPOCK - Coppock Curve |||| -| ⛔ EOM - Ease of Movement |||| -| ⛔ HILO - Gann High-Low Activator |||| -| ⛔ HT - HT Trendline |||| -| ⛔ MCGD - McGinley Dynamic |||| -| ⛔ STC - Schaff Trend Cycle |||| -| ⛔ WILLR - Larry Williams' %R |||| -| ⛔ VOR - Vortex Indicator |||| -| ⛔ PVT - Pivot Points |||| -| ⛔ KDJ - KDJ Index |||| -| ⛔ CHAND - Chandelier Exit |||| From f6c82ff1512d83985274a1f847c029c99510340a Mon Sep 17 00:00:00 2001 From: Miha Kralj Date: Fri, 11 Nov 2022 21:15:18 -0800 Subject: [PATCH 3/4] OBV, TRIMA --- Source/Basics/MAX_Series.cs | 5 +- Source/Basics/MIN_Series.cs | 5 +- Source/{Indicators => Momentum}/CCI_Series.cs | 0 Source/{Indicators => Trends}/ALMA_Series.cs | 130 ++++++++-------- Source/{Indicators => Trends}/DEMA_Series.cs | 0 Source/{Indicators => Trends}/EMA_Series.cs | 0 Source/{Indicators => Trends}/HEMA_Series.cs | 0 Source/{Indicators => Trends}/HMA_Series.cs | 0 Source/{Indicators => Trends}/JMA_Series.cs | 0 Source/{Indicators => Trends}/KAMA_Series.cs | 128 ++++++++-------- Source/{Indicators => Trends}/MACD_Series.cs | 0 Source/{Indicators => Trends}/RMA_Series.cs | 0 Source/{Indicators => Trends}/SMA_Series.cs | 0 Source/{Indicators => Trends}/SMMA_Series.cs | 0 Source/{Indicators => Trends}/TEMA_Series.cs | 0 Source/Trends/TRIMA_Series.cs | 49 ++++++ Source/{Indicators => Trends}/WMA_Series.cs | 0 Source/{Indicators => Trends}/ZLEMA_Series.cs | 142 +++++++++--------- .../{Indicators => Volatility}/ADL_Series.cs | 0 .../ADOSC_Series.cs | 0 .../{Indicators => Volatility}/ATRP_Series.cs | 0 .../{Indicators => Volatility}/ATR_Series.cs | 0 .../BBANDS_Series.cs | 0 .../{Indicators => Volatility}/RSI_Series.cs | 0 Source/Volume/OBV_Series.cs | 62 ++++++++ Tests/Validations/Skender_Stock.cs | 83 +++++----- Tests/Validations/TA_LIB.cs | 76 ++++++---- docs/crossovers.ipynb | 54 +++++-- docs/readme.md | 104 ++++++------- 29 files changed, 507 insertions(+), 331 deletions(-) rename Source/{Indicators => Momentum}/CCI_Series.cs (100%) rename Source/{Indicators => Trends}/ALMA_Series.cs (97%) rename Source/{Indicators => Trends}/DEMA_Series.cs (100%) rename Source/{Indicators => Trends}/EMA_Series.cs (100%) rename Source/{Indicators => Trends}/HEMA_Series.cs (100%) rename Source/{Indicators => Trends}/HMA_Series.cs (100%) rename Source/{Indicators => Trends}/JMA_Series.cs (100%) rename Source/{Indicators => Trends}/KAMA_Series.cs (97%) rename Source/{Indicators => Trends}/MACD_Series.cs (100%) rename Source/{Indicators => Trends}/RMA_Series.cs (100%) rename Source/{Indicators => Trends}/SMA_Series.cs (100%) rename Source/{Indicators => Trends}/SMMA_Series.cs (100%) rename Source/{Indicators => Trends}/TEMA_Series.cs (100%) create mode 100644 Source/Trends/TRIMA_Series.cs rename Source/{Indicators => Trends}/WMA_Series.cs (100%) rename Source/{Indicators => Trends}/ZLEMA_Series.cs (96%) rename Source/{Indicators => Volatility}/ADL_Series.cs (100%) rename Source/{Indicators => Volatility}/ADOSC_Series.cs (100%) rename Source/{Indicators => Volatility}/ATRP_Series.cs (100%) rename Source/{Indicators => Volatility}/ATR_Series.cs (100%) rename Source/{Indicators => Volatility}/BBANDS_Series.cs (100%) rename Source/{Indicators => Volatility}/RSI_Series.cs (100%) create mode 100644 Source/Volume/OBV_Series.cs diff --git a/Source/Basics/MAX_Series.cs b/Source/Basics/MAX_Series.cs index b22ce2aa..591f6739 100644 --- a/Source/Basics/MAX_Series.cs +++ b/Source/Basics/MAX_Series.cs @@ -22,7 +22,10 @@ public class MAX_Series : Single_TSeries_Indicator double _max = TValue.v; for (int i = 0; i < this._buffer.Count; i++) - { _max = (this._buffer[i] > _max) ? this._buffer[i] : _max; } + { + //_max = (this._buffer[i] > _max) ? this._buffer[i] : _max; + _max = Math.Max(this._buffer[i], _max); + } var result = (TValue.t, this.Count < this._p - 1 && this._NaN ? double.NaN : _max); diff --git a/Source/Basics/MIN_Series.cs b/Source/Basics/MIN_Series.cs index 8c513d8e..4209d0b1 100644 --- a/Source/Basics/MIN_Series.cs +++ b/Source/Basics/MIN_Series.cs @@ -22,7 +22,10 @@ public class MIN_Series : Single_TSeries_Indicator double _min = TValue.v; for (int i = 0; i < this._buffer.Count; i++) - { _min = (this._buffer[i] < _min) ? this._buffer[i] : _min; } + { + //_min = (this._buffer[i] < _min) ? this._buffer[i] : _min; + _min = Math.Min(this._buffer[i], _min); + } var result = (TValue.t, (this.Count < this._p - 1 && this._NaN) ? double.NaN : _min); diff --git a/Source/Indicators/CCI_Series.cs b/Source/Momentum/CCI_Series.cs similarity index 100% rename from Source/Indicators/CCI_Series.cs rename to Source/Momentum/CCI_Series.cs diff --git a/Source/Indicators/ALMA_Series.cs b/Source/Trends/ALMA_Series.cs similarity index 97% rename from Source/Indicators/ALMA_Series.cs rename to Source/Trends/ALMA_Series.cs index 82072d68..ab3f4593 100644 --- a/Source/Indicators/ALMA_Series.cs +++ b/Source/Trends/ALMA_Series.cs @@ -1,65 +1,65 @@ -namespace QuanTAlib; -using System; - -/* -ALMA: Arnaud Legoux Moving Average - The ALMA moving average uses the curve of the Normal (Gauss) distribution, which - can be shifted from 0 to 1. This allows regulating the smoothness and high - sensitivity of the indicator. Sigma is another parameter that is responsible for - the shape of the curve coefficients. This moving average reduces lag of the data - in conjunction with smoothing to reduce noise. - - -Sources: - https://phemex.com/academy/what-is-arnaud-legoux-moving-averages - https://www.prorealcode.com/prorealtime-indicators/alma-arnaud-legoux-moving-average/ - - */ - -public class ALMA_Series : Single_TSeries_Indicator -{ - private readonly System.Collections.Generic.List _buffer = new(); - private readonly double[] _weight; - private double _norm; - private readonly double _offset, _sigma; - - public ALMA_Series(TSeries source, int period, double offset = 0.85, double sigma = 6.0, bool useNaN = false) - : base(source, period, useNaN) - { - _offset = offset; - _sigma = sigma; - _weight = new double[period]; - - if (this._data.Count > 0) { base.Add(this._data); } - } - - public override void Add((System.DateTime t, double v) TValue, bool update) - { - if (update) { this._buffer[this._buffer.Count - 1] = TValue.v; } - else { this._buffer.Add(TValue.v); } - if (this._buffer.Count > this._p) { this._buffer.RemoveAt(0); } - - if (this._buffer.Count <= _p) { calc_weights(); } - - double _weightedSum = 0; - for (int i = 0; i < this._buffer.Count; i++) { _weightedSum += _weight[i] * _buffer[i]; } - double _alma = _weightedSum / _norm; - - var ret = (TValue.t, this.Count < this._p - 1 && this._NaN ? double.NaN : _alma); - base.Add(ret, update); - } - - private void calc_weights() - { - int _len = this._buffer.Count; - _norm = 0; - double _m = _offset * (_len - 1); - double _s = _len / _sigma; - for (int i = 0; i < _len; i++) - { - double _wt = Math.Exp(-((i - _m) * (i - _m)) / (2 * _s * _s)); - _weight[i] = _wt; - _norm += _wt; - } - } -} +namespace QuanTAlib; +using System; + +/* +ALMA: Arnaud Legoux Moving Average + The ALMA moving average uses the curve of the Normal (Gauss) distribution, which + can be shifted from 0 to 1. This allows regulating the smoothness and high + sensitivity of the indicator. Sigma is another parameter that is responsible for + the shape of the curve coefficients. This moving average reduces lag of the data + in conjunction with smoothing to reduce noise. + + +Sources: + https://phemex.com/academy/what-is-arnaud-legoux-moving-averages + https://www.prorealcode.com/prorealtime-indicators/alma-arnaud-legoux-moving-average/ + + */ + +public class ALMA_Series : Single_TSeries_Indicator +{ + private readonly System.Collections.Generic.List _buffer = new(); + private readonly double[] _weight; + private double _norm; + private readonly double _offset, _sigma; + + public ALMA_Series(TSeries source, int period, double offset = 0.85, double sigma = 6.0, bool useNaN = false) + : base(source, period, useNaN) + { + _offset = offset; + _sigma = sigma; + _weight = new double[period]; + + if (this._data.Count > 0) { base.Add(this._data); } + } + + public override void Add((System.DateTime t, double v) TValue, bool update) + { + if (update) { this._buffer[this._buffer.Count - 1] = TValue.v; } + else { this._buffer.Add(TValue.v); } + if (this._buffer.Count > this._p) { this._buffer.RemoveAt(0); } + + if (this._buffer.Count <= _p) { calc_weights(); } + + double _weightedSum = 0; + for (int i = 0; i < this._buffer.Count; i++) { _weightedSum += _weight[i] * _buffer[i]; } + double _alma = _weightedSum / _norm; + + var ret = (TValue.t, this.Count < this._p - 1 && this._NaN ? double.NaN : _alma); + base.Add(ret, update); + } + + private void calc_weights() + { + int _len = this._buffer.Count; + _norm = 0; + double _m = _offset * (_len - 1); + double _s = _len / _sigma; + for (int i = 0; i < _len; i++) + { + double _wt = Math.Exp(-((i - _m) * (i - _m)) / (2 * _s * _s)); + _weight[i] = _wt; + _norm += _wt; + } + } +} diff --git a/Source/Indicators/DEMA_Series.cs b/Source/Trends/DEMA_Series.cs similarity index 100% rename from Source/Indicators/DEMA_Series.cs rename to Source/Trends/DEMA_Series.cs diff --git a/Source/Indicators/EMA_Series.cs b/Source/Trends/EMA_Series.cs similarity index 100% rename from Source/Indicators/EMA_Series.cs rename to Source/Trends/EMA_Series.cs diff --git a/Source/Indicators/HEMA_Series.cs b/Source/Trends/HEMA_Series.cs similarity index 100% rename from Source/Indicators/HEMA_Series.cs rename to Source/Trends/HEMA_Series.cs diff --git a/Source/Indicators/HMA_Series.cs b/Source/Trends/HMA_Series.cs similarity index 100% rename from Source/Indicators/HMA_Series.cs rename to Source/Trends/HMA_Series.cs diff --git a/Source/Indicators/JMA_Series.cs b/Source/Trends/JMA_Series.cs similarity index 100% rename from Source/Indicators/JMA_Series.cs rename to Source/Trends/JMA_Series.cs diff --git a/Source/Indicators/KAMA_Series.cs b/Source/Trends/KAMA_Series.cs similarity index 97% rename from Source/Indicators/KAMA_Series.cs rename to Source/Trends/KAMA_Series.cs index 2f46e25d..f27d08cd 100644 --- a/Source/Indicators/KAMA_Series.cs +++ b/Source/Trends/KAMA_Series.cs @@ -1,65 +1,65 @@ -namespace QuanTAlib; -using System; - -/* -KAMA: Kaufman's Adaptive Moving Average - Created in 1988 by American quantitative finance theorist Perry J. Kaufman and is known as - Kaufman's Adaptive Moving Average (KAMA). Even though the method was developed as early as 1972, - it was not until the popular book titled "Trading Systems and Methods" that it was made widely - available to the public. Unlike other conventional moving averages systems, the Kaufman's Adaptive - Moving Average, considers market volatility apart from price fluctuations. - - KAMAi = KAMAi - 1 + SC * ( price - KAMAi-1 ) - -Sources: - https://www.tutorialspoint.com/kaufman-s-adaptive-moving-average-kama-formula-and-how-does-it-work - https://corporatefinanceinstitute.com/resources/knowledge/trading-investing/kaufmans-adaptive-moving-average-kama/ - https://www.technicalindicators.net/indicators-technical-analysis/152-kama-kaufman-adaptive-moving-average - -Remark: - If useNaN:true argument is provided, KAMA starts calculating values from [period] bar onwards. - Without useNaN argument (default setting), KAMA starts calculating values from bar 1 - and yields - slightly different results for the first 50 bars - and then converges with the other one. - - */ - -public class KAMA_Series : Single_TSeries_Indicator -{ - private readonly double _scFast, _scSlow; - private readonly System.Collections.Generic.List _buffer = new(); - private double _lastkama = double.NaN; - private double _lastlastkama; - - public KAMA_Series(TSeries source, int period, int fast = 2, int slow= 30, bool useNaN = false) : base(source, period, useNaN) { - _scFast = 2.0 / (fast+1); - _scSlow = 2.0 / (slow+1); - if (base._data.Count > 0) { base.Add(base._data); } - } - public override void Add((System.DateTime t, double v) TValue, bool update) - { - if (update){ - _buffer[_buffer.Count - 1] = TValue.v; - this._lastkama = this._lastlastkama; - } else { - _buffer.Add(TValue.v); - } - if (_buffer.Count > _p + 1) { _buffer.RemoveAt(0); } - double _kama = 0; - if (this.Count < this._p) { - for (int i = 0; i < this._buffer.Count; i++) { _kama += this._buffer[i]; } - _kama /= this._buffer.Count; - } else { - double _change = Math.Abs(_buffer[_buffer.Count - 1] - _buffer[(_buffer.Count > _p + 1) ? 1 : 0]); - double _sumpv = 0; - for (int i = 1; i < _buffer.Count; i++) - { _sumpv += Math.Abs(_buffer[(_buffer.Count > 0) ? i : 0] - _buffer[i - 1]); } - double _er = (_sumpv == 0) ? 0 : _change / _sumpv; - double _sc = (_er * (_scFast - _scSlow)) + _scSlow; - _kama = (_lastkama + (_sc * _sc * (TValue.v - _lastkama))); - } - _lastlastkama = _lastkama; - _lastkama = _kama; - var result = (TValue.t, (this.Count < this._p - 1 && this._NaN) ? double.NaN : _kama); - base.Add(result, update); - } +namespace QuanTAlib; +using System; + +/* +KAMA: Kaufman's Adaptive Moving Average + Created in 1988 by American quantitative finance theorist Perry J. Kaufman and is known as + Kaufman's Adaptive Moving Average (KAMA). Even though the method was developed as early as 1972, + it was not until the popular book titled "Trading Systems and Methods" that it was made widely + available to the public. Unlike other conventional moving averages systems, the Kaufman's Adaptive + Moving Average, considers market volatility apart from price fluctuations. + + KAMAi = KAMAi - 1 + SC * ( price - KAMAi-1 ) + +Sources: + https://www.tutorialspoint.com/kaufman-s-adaptive-moving-average-kama-formula-and-how-does-it-work + https://corporatefinanceinstitute.com/resources/knowledge/trading-investing/kaufmans-adaptive-moving-average-kama/ + https://www.technicalindicators.net/indicators-technical-analysis/152-kama-kaufman-adaptive-moving-average + +Remark: + If useNaN:true argument is provided, KAMA starts calculating values from [period] bar onwards. + Without useNaN argument (default setting), KAMA starts calculating values from bar 1 - and yields + slightly different results for the first 50 bars - and then converges with the other one. + + */ + +public class KAMA_Series : Single_TSeries_Indicator +{ + private readonly double _scFast, _scSlow; + private readonly System.Collections.Generic.List _buffer = new(); + private double _lastkama = double.NaN; + private double _lastlastkama; + + public KAMA_Series(TSeries source, int period, int fast = 2, int slow= 30, bool useNaN = false) : base(source, period, useNaN) { + _scFast = 2.0 / (fast+1); + _scSlow = 2.0 / (slow+1); + if (base._data.Count > 0) { base.Add(base._data); } + } + public override void Add((System.DateTime t, double v) TValue, bool update) + { + if (update){ + _buffer[_buffer.Count - 1] = TValue.v; + this._lastkama = this._lastlastkama; + } else { + _buffer.Add(TValue.v); + } + if (_buffer.Count > _p + 1) { _buffer.RemoveAt(0); } + double _kama = 0; + if (this.Count < this._p) { + for (int i = 0; i < this._buffer.Count; i++) { _kama += this._buffer[i]; } + _kama /= this._buffer.Count; + } else { + double _change = Math.Abs(_buffer[_buffer.Count - 1] - _buffer[(_buffer.Count > _p + 1) ? 1 : 0]); + double _sumpv = 0; + for (int i = 1; i < _buffer.Count; i++) + { _sumpv += Math.Abs(_buffer[(_buffer.Count > 0) ? i : 0] - _buffer[i - 1]); } + double _er = (_sumpv == 0) ? 0 : _change / _sumpv; + double _sc = (_er * (_scFast - _scSlow)) + _scSlow; + _kama = (_lastkama + (_sc * _sc * (TValue.v - _lastkama))); + } + _lastlastkama = _lastkama; + _lastkama = _kama; + var result = (TValue.t, (this.Count < this._p - 1 && this._NaN) ? double.NaN : _kama); + base.Add(result, update); + } } \ No newline at end of file diff --git a/Source/Indicators/MACD_Series.cs b/Source/Trends/MACD_Series.cs similarity index 100% rename from Source/Indicators/MACD_Series.cs rename to Source/Trends/MACD_Series.cs diff --git a/Source/Indicators/RMA_Series.cs b/Source/Trends/RMA_Series.cs similarity index 100% rename from Source/Indicators/RMA_Series.cs rename to Source/Trends/RMA_Series.cs diff --git a/Source/Indicators/SMA_Series.cs b/Source/Trends/SMA_Series.cs similarity index 100% rename from Source/Indicators/SMA_Series.cs rename to Source/Trends/SMA_Series.cs diff --git a/Source/Indicators/SMMA_Series.cs b/Source/Trends/SMMA_Series.cs similarity index 100% rename from Source/Indicators/SMMA_Series.cs rename to Source/Trends/SMMA_Series.cs diff --git a/Source/Indicators/TEMA_Series.cs b/Source/Trends/TEMA_Series.cs similarity index 100% rename from Source/Indicators/TEMA_Series.cs rename to Source/Trends/TEMA_Series.cs diff --git a/Source/Trends/TRIMA_Series.cs b/Source/Trends/TRIMA_Series.cs new file mode 100644 index 00000000..78304982 --- /dev/null +++ b/Source/Trends/TRIMA_Series.cs @@ -0,0 +1,49 @@ +namespace QuanTAlib; +using System; + +/* +TRIMA: Triangular Moving Average + A weighted moving average where the shape of the weights are triangular and the greatest + weight is in the middle of the period, + +Sources: + https://www.tradingtechnologies.com/help/x-study/technical-indicator-definitions/triangular-moving-average-trima/ + +Remark: + trima = sma(sma(signal, n/2), n/2) + + */ + +public class TRIMA_Series : Single_TSeries_Indicator +{ + private readonly System.Collections.Generic.List _buffer1 = new(); + private readonly System.Collections.Generic.List _buffer2 = new(); + private readonly int _p1a, _p1b; + + public TRIMA_Series(TSeries source, int period, bool useNaN = false) : base(source, period, useNaN) + { + _p1a = (int) Math.Floor((period * 0.5) + 1); + _p1b = (int) Math.Ceiling(0.5 * period); + if (base._data.Count > 0) { base.Add(base._data); } + } + + public override void Add((System.DateTime t, double v) TValue, bool update) + { + if (update) { _buffer1[_buffer1.Count - 1] = TValue.v; } else { _buffer1.Add(TValue.v); } + if (_buffer1.Count > this._p1b && this._p1b != 0) { _buffer1.RemoveAt(0); } + + double _sma1 = 0; + for (int i = 0; i < _buffer1.Count; i++) { _sma1 += _buffer1[i]; } + _sma1 /= this._buffer1.Count; + + if (update) { _buffer2[_buffer2.Count - 1] = _sma1; } else { _buffer2.Add(_sma1); } + if (_buffer2.Count > this._p1a && this._p1a != 0) { _buffer2.RemoveAt(0); } + + double _trima = 0; + for (int i = 0; i < _buffer2.Count; i++) { _trima += _buffer2[i]; } + _trima /= this._buffer2.Count; + + var result = (TValue.t, (this.Count < this._p - 1 && this._NaN) ? double.NaN : _trima); + base.Add(result, update); + } +} \ No newline at end of file diff --git a/Source/Indicators/WMA_Series.cs b/Source/Trends/WMA_Series.cs similarity index 100% rename from Source/Indicators/WMA_Series.cs rename to Source/Trends/WMA_Series.cs diff --git a/Source/Indicators/ZLEMA_Series.cs b/Source/Trends/ZLEMA_Series.cs similarity index 96% rename from Source/Indicators/ZLEMA_Series.cs rename to Source/Trends/ZLEMA_Series.cs index ae4fef30..fdc53877 100644 --- a/Source/Indicators/ZLEMA_Series.cs +++ b/Source/Trends/ZLEMA_Series.cs @@ -1,72 +1,72 @@ -namespace QuanTAlib; -using System; - -/* -ZLEMA: Zero Lag Exponential Moving Average - The Zero lag exponential moving average (ZLEMA) indicator was created by John - Ehlers and Ric Way. - -The formula for a given N-Day period and for a given Data series is: - Lag = (Period-1)/2 - Ema Data = {Data+(Data-Data(Lag days ago)) - ZLEMA = EMA (EmaData,Period) - -Remark: - The idea is do a regular exponential moving average (EMA) calculation but on a - de-lagged data instead of doing it on the regular data. Data is de-lagged by - removing the data from "lag" days ago thus removing (or attempting to remove) - the cumulative lag effect of the moving average. - - */ - -public class ZLEMA_Series : Single_TSeries_Indicator -{ - private readonly System.Collections.Generic.List _buffer = new(); - private readonly double _k, _k1m; - private double _lastema, _lastlastema; - - public ZLEMA_Series(TSeries source, int period, bool useNaN = false) : base(source, period, useNaN) - { - this._k = 2.0 / (this._p + 1); - this._k1m = 1.0 - this._k; - this._lastema = this._lastlastema = double.NaN; - if (base._data.Count > 0) - { base.Add(base._data); } - } - - public override void Add((System.DateTime t, double v) TValue, bool update) - { - int _lag = (int)((_p-1) * 0.5); - _lag = (this.Count-_lag < 0) ? 0 : this.Count-_lag; - double _zl = TValue.v + (TValue.v - _data[_lag].v); - - double _ema = 0; - if (update) - { this._lastema = this._lastlastema; } - if (this.Count < this._p) - { - if (update) - { this._buffer[this._buffer.Count - 1] = _zl; } - else - { - this._buffer.Add(_zl); - } - if (this._buffer.Count > this._p) - { this._buffer.RemoveAt(0); } - - for (int i = 0; i < this._buffer.Count; i++) - { _ema += this._buffer[i]; } - _ema /= this._buffer.Count; - } - else - { - _ema = (_zl * this._k) + (this._lastema * this._k1m); - } - - this._lastlastema = this._lastema; - this._lastema = _ema; - - var ret = (TValue.t, this.Count < this._p - 1 && this._NaN ? double.NaN : _ema); - base.Add(ret, update); - } +namespace QuanTAlib; +using System; + +/* +ZLEMA: Zero Lag Exponential Moving Average + The Zero lag exponential moving average (ZLEMA) indicator was created by John + Ehlers and Ric Way. + +The formula for a given N-Day period and for a given Data series is: + Lag = (Period-1)/2 + Ema Data = {Data+(Data-Data(Lag days ago)) + ZLEMA = EMA (EmaData,Period) + +Remark: + The idea is do a regular exponential moving average (EMA) calculation but on a + de-lagged data instead of doing it on the regular data. Data is de-lagged by + removing the data from "lag" days ago thus removing (or attempting to remove) + the cumulative lag effect of the moving average. + + */ + +public class ZLEMA_Series : Single_TSeries_Indicator +{ + private readonly System.Collections.Generic.List _buffer = new(); + private readonly double _k, _k1m; + private double _lastema, _lastlastema; + + public ZLEMA_Series(TSeries source, int period, bool useNaN = false) : base(source, period, useNaN) + { + this._k = 2.0 / (this._p + 1); + this._k1m = 1.0 - this._k; + this._lastema = this._lastlastema = double.NaN; + if (base._data.Count > 0) + { base.Add(base._data); } + } + + public override void Add((System.DateTime t, double v) TValue, bool update) + { + int _lag = (int)((_p-1) * 0.5); + _lag = (this.Count-_lag < 0) ? 0 : this.Count-_lag; + double _zl = TValue.v + (TValue.v - _data[_lag].v); + + double _ema = 0; + if (update) + { this._lastema = this._lastlastema; } + if (this.Count < this._p) + { + if (update) + { this._buffer[this._buffer.Count - 1] = _zl; } + else + { + this._buffer.Add(_zl); + } + if (this._buffer.Count > this._p) + { this._buffer.RemoveAt(0); } + + for (int i = 0; i < this._buffer.Count; i++) + { _ema += this._buffer[i]; } + _ema /= this._buffer.Count; + } + else + { + _ema = (_zl * this._k) + (this._lastema * this._k1m); + } + + this._lastlastema = this._lastema; + this._lastema = _ema; + + var ret = (TValue.t, this.Count < this._p - 1 && this._NaN ? double.NaN : _ema); + base.Add(ret, update); + } } \ No newline at end of file diff --git a/Source/Indicators/ADL_Series.cs b/Source/Volatility/ADL_Series.cs similarity index 100% rename from Source/Indicators/ADL_Series.cs rename to Source/Volatility/ADL_Series.cs diff --git a/Source/Indicators/ADOSC_Series.cs b/Source/Volatility/ADOSC_Series.cs similarity index 100% rename from Source/Indicators/ADOSC_Series.cs rename to Source/Volatility/ADOSC_Series.cs diff --git a/Source/Indicators/ATRP_Series.cs b/Source/Volatility/ATRP_Series.cs similarity index 100% rename from Source/Indicators/ATRP_Series.cs rename to Source/Volatility/ATRP_Series.cs diff --git a/Source/Indicators/ATR_Series.cs b/Source/Volatility/ATR_Series.cs similarity index 100% rename from Source/Indicators/ATR_Series.cs rename to Source/Volatility/ATR_Series.cs diff --git a/Source/Indicators/BBANDS_Series.cs b/Source/Volatility/BBANDS_Series.cs similarity index 100% rename from Source/Indicators/BBANDS_Series.cs rename to Source/Volatility/BBANDS_Series.cs diff --git a/Source/Indicators/RSI_Series.cs b/Source/Volatility/RSI_Series.cs similarity index 100% rename from Source/Indicators/RSI_Series.cs rename to Source/Volatility/RSI_Series.cs diff --git a/Source/Volume/OBV_Series.cs b/Source/Volume/OBV_Series.cs new file mode 100644 index 00000000..30758e9f --- /dev/null +++ b/Source/Volume/OBV_Series.cs @@ -0,0 +1,62 @@ +namespace QuanTAlib; +using System; + +/* +OBV: On-Balance Volume + On-balance volume (OBV) is a technical trading momentum indicator that uses volume flow to predict + changes in stock price. Joseph Granville first developed the OBV metric in the 1963 book + Granville's New Key to Stock Market Profits. + + | +volume; if close > close[previous] + OBV = OBV[previous] + | 0; if close = close[previous] + | -volume; if close < close[previous] + +Sources: + https://www.investopedia.com/terms/o/onbalancevolume.asp + https://www.tradingview.com/wiki/On_Balance_Volume_(OBV) + https://www.tradingtechnologies.com/help/x-study/technical-indicator-definitions/on-balance-volume-obv/ + https://www.motivewave.com/studies/on_balance_volume.htm + +Note: + There is no consensus on what is the first OBV value in the series: + - TA-LIB uses the first volume: OBV[0] = volume[0] + - Skender stock library uses 0: OBV[0] = 0 + + */ + +public class OBV_Series : Single_TBars_Indicator +{ + private double _lastobv, _lastlastobv; + private double _lastclose, _lastlastclose; + public OBV_Series(TBars source, int period = 10, bool useNaN = false) : base(source, period: period, useNaN: useNaN) + { + this._lastobv = this._lastlastobv = 0; + this._lastclose = this._lastlastclose = 0; + if (_bars.Count > 0) { base.Add(_bars); } + } + + public override void Add((DateTime t, double o, double h, double l, double c, double v) TBar, bool update) + { + if (update) + { + this._lastobv = this._lastlastobv; + this._lastclose = this._lastlastclose; + } + + double _obv = this._lastobv; + if (TBar.c > this._lastclose) { _obv += TBar.v; } + if (TBar.c < this._lastclose) { _obv -= TBar.v; } + + // Unclear what the first value in OBV series is - currently set to volume[0] + // if (this.Count == 0) { _obv = 0; } + + this._lastlastobv = this._lastobv; + this._lastobv = _obv; + + this._lastlastclose = this._lastclose; + this._lastclose = TBar.c; + + var result = (TBar.t, (this.Count < this._p && this._NaN) ? double.NaN : _obv); + base.Add(result, update); + } +} diff --git a/Tests/Validations/Skender_Stock.cs b/Tests/Validations/Skender_Stock.cs index 736c76cd..05b06066 100644 --- a/Tests/Validations/Skender_Stock.cs +++ b/Tests/Validations/Skender_Stock.cs @@ -13,7 +13,7 @@ public class Skender_Stock public Skender_Stock() { - this.bars = new(1000); + this.bars = new(Bars: 1, Volatility:0.7, Drift:0.0); this.period = this.rnd.Next(28) + 3; this.quotes = this.bars.Select( q => new Quote @@ -33,7 +33,7 @@ public class Skender_Stock SMA_Series QL = new(this.bars.Close, this.period, false); var SK = this.quotes.GetSma(this.period); - Assert.Equal(Math.Round((double)SK.Last().Sma!, 8), Math.Round(QL.Last().v, 8)); + Assert.Equal(Math.Round((double)SK.Last().Sma!, 6), Math.Round(QL.Last().v, 6)); } [Fact] @@ -42,7 +42,7 @@ public class Skender_Stock EMA_Series QL = new(this.bars.Close, this.period, false); var SK = this.quotes.GetEma(this.period); - Assert.Equal(Math.Round((double)SK.Last().Ema!, 8), Math.Round(QL.Last().v, 8)); + Assert.Equal(Math.Round((double)SK.Last().Ema!, 6), Math.Round(QL.Last().v, 6)); } [Fact] public void WMA() @@ -50,7 +50,7 @@ public class Skender_Stock WMA_Series QL = new(this.bars.Close, this.period, false); var SK = this.quotes.GetWma(this.period); - Assert.Equal(Math.Round((double)SK.Last().Wma!, 8), Math.Round(QL.Last().v, 8)); + Assert.Equal(Math.Round((double)SK.Last().Wma!, 6), Math.Round(QL.Last().v, 6)); } [Fact] @@ -59,7 +59,7 @@ public class Skender_Stock DEMA_Series QL = new(this.bars.Close, this.period, false); var SK = this.quotes.GetDema(this.period); - Assert.Equal(Math.Round((double)SK.Last().Dema!, 8), Math.Round(QL.Last().v, 8)); + Assert.Equal(Math.Round((double)SK.Last().Dema!, 6), Math.Round(QL.Last().v, 6)); } [Fact] @@ -68,7 +68,7 @@ public class Skender_Stock TEMA_Series QL = new(this.bars.Close, this.period, false); var SK = this.quotes.GetTema(this.period); - Assert.Equal(Math.Round((double)SK.Last().Tema!, 8), Math.Round(QL.Last().v, 8)); + Assert.Equal(Math.Round((double)SK.Last().Tema!, 6), Math.Round(QL.Last().v, 6)); } [Fact] @@ -77,7 +77,7 @@ public class Skender_Stock MAD_Series QL = new(this.bars.Close, this.period, false); var SK = this.quotes.GetSmaAnalysis(this.period); - Assert.Equal(Math.Round((double)SK.Last().Mad!, 8), Math.Round(QL.Last().v, 8)); + Assert.Equal(Math.Round((double)SK.Last().Mad!, 6), Math.Round(QL.Last().v, 6)); } [Fact] @@ -86,7 +86,7 @@ public class Skender_Stock MAPE_Series QL = new(this.bars.Close, this.period, false); var SK = this.quotes.GetSmaAnalysis(this.period); - Assert.Equal(Math.Round((double)SK.Last().Mape!, 8), Math.Round(QL.Last().v, 8)); + Assert.Equal(Math.Round((double)SK.Last().Mape!, 6), Math.Round(QL.Last().v, 6)); } [Fact] @@ -95,7 +95,18 @@ public class Skender_Stock ATR_Series QL = new(this.bars, this.period, false); var SK = this.quotes.GetAtr(this.period); - Assert.Equal(Math.Round((double)SK.Last().Atr!, 8), Math.Round(QL.Last().v, 8)); + Assert.Equal(Math.Round((double)SK.Last().Atr!, 6), Math.Round(QL.Last().v, 6)); + } + + [Fact] + public void OBV() + { + OBV_Series QL = new(this.bars, this.period, false); + var SK = this.quotes.GetObv(this.period); + + // adding volume[0] to OBV to pass the test and keep compatibility with TA-LIB + Assert.Equal(Math.Round((double)SK.Last().Obv!, 6) + Math.Round((double)this.quotes.First().Volume!, 6), + Math.Round(QL.Last().v, 6)); } [Fact] @@ -104,7 +115,7 @@ public class Skender_Stock ADL_Series QL = new(this.bars, false); var SK = this.quotes.GetAdl(); - Assert.Equal(Math.Round((double)SK.Last().Adl!, 6), Math.Round(QL.Last().v, 6)); + Assert.Equal(Math.Round((double)SK.Last().Adl!, 5), Math.Round(QL.Last().v, 5)); } [Fact] @@ -113,7 +124,7 @@ public class Skender_Stock CCI_Series QL = new(this.bars, this.period, false); var SK = this.quotes.GetCci(this.period); - Assert.Equal(Math.Round((double)SK.Last().Cci!, 8), Math.Round(QL.Last().v, 8)); + Assert.Equal(Math.Round((double)SK.Last().Cci!, 6), Math.Round(QL.Last().v, 6)); } [Fact] @@ -122,7 +133,7 @@ public class Skender_Stock ATRP_Series QL = new(this.bars, this.period, false); var SK = this.quotes.GetAtr(this.period); - Assert.Equal(Math.Round((double)SK.Last().Atrp!, 8), Math.Round(QL.Last().v, 8)); + Assert.Equal(Math.Round((double)SK.Last().Atrp!, 6), Math.Round(QL.Last().v, 6)); } [Fact] @@ -131,7 +142,7 @@ public class Skender_Stock KAMA_Series QL = new(this.bars.Close, this.period, useNaN: false); var SK = this.quotes.GetKama(this.period); - Assert.Equal(Math.Round((double)SK.Last().Kama!, 8), Math.Round(QL.Last().v, 8)); + Assert.Equal(Math.Round((double)SK.Last().Kama!, 6), Math.Round(QL.Last().v, 6)); } [Fact] @@ -140,7 +151,7 @@ public class Skender_Stock HMA_Series QL = new(this.bars.Close, this.period, useNaN: false); var SK = this.quotes.GetHma(this.period); - Assert.Equal(Math.Round((double)SK.Last().Hma!, 8), Math.Round(QL.Last().v, 8)); + Assert.Equal(Math.Round((double)SK.Last().Hma!, 6), Math.Round(QL.Last().v, 6)); } [Fact] @@ -149,7 +160,7 @@ public class Skender_Stock SMMA_Series QL = new(this.bars.Close, this.period, useNaN: false); var SK = this.quotes.GetSmma(this.period); - Assert.Equal(Math.Round((double)SK.Last().Smma!, 8), Math.Round(QL.Last().v, 8)); + Assert.Equal(Math.Round((double)SK.Last().Smma!, 6), Math.Round(QL.Last().v, 6)); } [Fact] @@ -158,8 +169,8 @@ public class Skender_Stock MACD_Series QL = new(this.bars.Close, 26,12,9, useNaN: false); var SK = this.quotes.GetMacd(12,26,9); - Assert.Equal(Math.Round((double)SK.Last().Macd!, 8), Math.Round(QL.Last().v, 8)); - Assert.Equal(Math.Round((double)SK.Last().Signal!, 8), Math.Round(QL.Signal.Last().v, 8)); + Assert.Equal(Math.Round((double)SK.Last().Macd!, 6), Math.Round(QL.Last().v, 6)); + Assert.Equal(Math.Round((double)SK.Last().Signal!, 6), Math.Round(QL.Signal.Last().v, 6)); } [Fact] @@ -168,12 +179,12 @@ public class Skender_Stock BBANDS_Series QL = new(this.bars.Close, this.period, 2.0, useNaN: false); var SK = this.quotes.GetBollingerBands(this.period, 2.0); - Assert.Equal(Math.Round((double)SK.Last().Sma!, 8), Math.Round(QL.Mid.Last().v, 8)); - Assert.Equal(Math.Round((double)SK.Last().UpperBand!, 8), Math.Round(QL.Upper.Last().v, 8)); - Assert.Equal(Math.Round((double)SK.Last().LowerBand!, 8), Math.Round(QL.Lower.Last().v, 8)); - Assert.Equal(Math.Round((double)SK.Last().Width!, 8), Math.Round(QL.Bandwidth.Last().v, 8)); - Assert.Equal(Math.Round((double)SK.Last().PercentB!, 8), Math.Round(QL.PercentB.Last().v, 8)); - Assert.Equal(Math.Round((double)SK.Last().ZScore!, 8), Math.Round(QL.Zscore.Last().v, 8)); + Assert.Equal(Math.Round((double)SK.Last().Sma!, 6), Math.Round(QL.Mid.Last().v, 6)); + Assert.Equal(Math.Round((double)SK.Last().UpperBand!, 6), Math.Round(QL.Upper.Last().v, 6)); + Assert.Equal(Math.Round((double)SK.Last().LowerBand!, 6), Math.Round(QL.Lower.Last().v, 6)); + Assert.Equal(Math.Round((double)SK.Last().Width!, 6), Math.Round(QL.Bandwidth.Last().v, 6)); + Assert.Equal(Math.Round((double)SK.Last().PercentB!, 6), Math.Round(QL.PercentB.Last().v, 6)); + Assert.Equal(Math.Round((double)SK.Last().ZScore!, 6), Math.Round(QL.Zscore.Last().v, 6)); } [Fact] @@ -182,7 +193,7 @@ public class Skender_Stock RSI_Series QL = new(this.bars.Close, this.period, useNaN: false); var SK = this.quotes.GetRsi(this.period); - Assert.Equal(Math.Round((double)SK.Last().Rsi!, 8), Math.Round(QL.Last().v, 8)); + Assert.Equal(Math.Round((double)SK.Last().Rsi!, 6), Math.Round(QL.Last().v, 6)); } [Fact] @@ -191,7 +202,7 @@ public class Skender_Stock ALMA_Series QL = new(this.bars.Close, this.period, useNaN: false); var SK = this.quotes.GetAlma(this.period); - Assert.Equal(Math.Round((double)SK.Last().Alma!, 8), Math.Round(QL.Last().v, 8)); + Assert.Equal(Math.Round((double)SK.Last().Alma!, 6), Math.Round(QL.Last().v, 6)); } [Fact] @@ -200,7 +211,7 @@ public class Skender_Stock SDEV_Series QL = new(this.bars.Close, this.period, useNaN: false); var SK = this.quotes.GetStdDev(this.period); - Assert.Equal(Math.Round((double)SK.Last().StdDev!, 8), Math.Round(QL.Last().v, 8)); + Assert.Equal(Math.Round((double)SK.Last().StdDev!, 6), Math.Round(QL.Last().v, 6)); } [Fact] @@ -209,10 +220,10 @@ public class Skender_Stock LINREG_Series QL = new(this.bars.Close, this.period, useNaN: false); var SK = this.quotes.GetSlope(this.period); - Assert.Equal(Math.Round((double)SK.Last().Slope!, 8), Math.Round(QL.Last().v, 8)); - Assert.Equal(Math.Round((double)SK.Last().Intercept!, 8), Math.Round(QL.Intercept.Last().v, 8)); - Assert.Equal(Math.Round((double)SK.Last().RSquared!, 8), Math.Round(QL.RSquared.Last().v, 8)); - Assert.Equal(Math.Round((double)SK.Last().StdDev!, 8), Math.Round(QL.StdDev.Last().v, 8)); + Assert.Equal(Math.Round((double)SK.Last().Slope!, 6), Math.Round(QL.Last().v, 6)); + Assert.Equal(Math.Round((double)SK.Last().Intercept!, 6), Math.Round(QL.Intercept.Last().v, 6)); + Assert.Equal(Math.Round((double)SK.Last().RSquared!, 6), Math.Round(QL.RSquared.Last().v, 6)); + Assert.Equal(Math.Round((double)SK.Last().StdDev!, 6), Math.Round(QL.StdDev.Last().v, 6)); } [Fact] @@ -221,7 +232,7 @@ public class Skender_Stock TR_Series QL = new(this.bars, useNaN: false); var SK = this.quotes.GetTr(); - Assert.Equal(Math.Round((double)SK.Last().Tr!, 8), Math.Round(QL.Last().v, 8)); + Assert.Equal(Math.Round((double)SK.Last().Tr!, 6), Math.Round(QL.Last().v, 6)); } [Fact] @@ -230,7 +241,7 @@ public class Skender_Stock TSeries QL = this.bars.HL2; var SK = this.quotes.GetBaseQuote(CandlePart.HL2); - Assert.Equal(Math.Round((double)SK.Last().Value!, 8), Math.Round(QL.Last().v, 8)); + Assert.Equal(Math.Round((double)SK.Last().Value!, 6), Math.Round(QL.Last().v, 6)); } [Fact] @@ -239,7 +250,7 @@ public class Skender_Stock TSeries QL = this.bars.OC2; var SK = this.quotes.GetBaseQuote(CandlePart.OC2); - Assert.Equal(Math.Round((double)SK.Last().Value!, 8), Math.Round(QL.Last().v, 8)); + Assert.Equal(Math.Round((double)SK.Last().Value!, 6), Math.Round(QL.Last().v, 6)); } [Fact] @@ -248,7 +259,7 @@ public class Skender_Stock TSeries QL = this.bars.HLC3; var SK = this.quotes.GetBaseQuote(CandlePart.HLC3); - Assert.Equal(Math.Round((double)SK.Last().Value!, 8), Math.Round(QL.Last().v, 8)); + Assert.Equal(Math.Round((double)SK.Last().Value!, 6), Math.Round(QL.Last().v, 6)); } [Fact] @@ -257,7 +268,7 @@ public class Skender_Stock TSeries QL = this.bars.OHL3; var SK = this.quotes.GetBaseQuote(CandlePart.OHL3); - Assert.Equal(Math.Round((double)SK.Last().Value!, 8), Math.Round(QL.Last().v, 8)); + Assert.Equal(Math.Round((double)SK.Last().Value!, 6), Math.Round(QL.Last().v, 6)); } [Fact] @@ -266,6 +277,6 @@ public class Skender_Stock TSeries QL = this.bars.OHLC4; var SK = this.quotes.GetBaseQuote(CandlePart.OHLC4); - Assert.Equal(Math.Round((double)SK.Last().Value!, 8), Math.Round(QL.Last().v, 8)); + Assert.Equal(Math.Round((double)SK.Last().Value!, 6), Math.Round(QL.Last().v, 6)); } } diff --git a/Tests/Validations/TA_LIB.cs b/Tests/Validations/TA_LIB.cs index a954ae2c..4680de66 100644 --- a/Tests/Validations/TA_LIB.cs +++ b/Tests/Validations/TA_LIB.cs @@ -18,7 +18,7 @@ public class TA_LIB public TA_LIB() { - this.bars = new(1000); + this.bars = new(5000); this.period = this.rnd.Next(28) + 3; this.TALIB = new double[this.bars.Count]; this.inopen = this.bars.Open.v.ToArray(); @@ -36,7 +36,7 @@ public class TA_LIB ADD_Series QL = new(this.bars.Open, this.bars.Close); Core.Add(this.inopen, this.inclose, 0, this.bars.Count - 1, this.TALIB, out int outBegIdx, out _); - Assert.Equal(Math.Round(this.TALIB[this.TALIB.Length - outBegIdx - 1], 8), Math.Round(QL.Last().v, 8)); + Assert.Equal(Math.Round(this.TALIB[this.TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero)); } [Fact] @@ -45,7 +45,7 @@ public class TA_LIB SUB_Series QL = new(this.bars.Open, this.bars.Close); Core.Sub(this.inopen, this.inclose, 0, this.bars.Count - 1, this.TALIB, out int outBegIdx, out _); - Assert.Equal(Math.Round(this.TALIB[this.TALIB.Length - outBegIdx - 1], 8), Math.Round(QL.Last().v, 8)); + Assert.Equal(Math.Round(this.TALIB[this.TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero)); } [Fact] @@ -54,7 +54,7 @@ public class TA_LIB MUL_Series QL = new(this.bars.Open, this.bars.Close); Core.Mult(this.inopen, this.inclose, 0, this.bars.Count - 1, this.TALIB, out int outBegIdx, out _); - Assert.Equal(Math.Round(this.TALIB[this.TALIB.Length - outBegIdx - 1], 8), Math.Round(QL.Last().v, 8)); + Assert.Equal(Math.Round(this.TALIB[this.TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero)); } [Fact] @@ -63,7 +63,7 @@ public class TA_LIB DIV_Series QL = new(this.bars.Open, this.bars.Close); Core.Div(this.inopen, this.inclose, 0, this.bars.Count - 1, this.TALIB, out int outBegIdx, out _); - Assert.Equal(Math.Round(this.TALIB[this.TALIB.Length - outBegIdx - 1], 8), Math.Round(QL.Last().v, 8)); + Assert.Equal(Math.Round(this.TALIB[this.TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero)); } [Fact] @@ -72,7 +72,7 @@ public class TA_LIB SDEV_Series QL = new(this.bars.Close, this.period, false); Core.StdDev(this.inclose, 0, this.bars.Count - 1, this.TALIB, out int outBegIdx, out _, this.period); - Assert.Equal(Math.Round(this.TALIB[this.TALIB.Length - outBegIdx - 1], 8), Math.Round(QL.Last().v, 8)); + Assert.Equal(Math.Round(this.TALIB[this.TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero)); } [Fact] @@ -81,7 +81,16 @@ public class TA_LIB SMA_Series QL = new(this.bars.Close, this.period, false); Core.Sma(this.inclose, 0, this.bars.Count - 1, this.TALIB, out int outBegIdx, out _, this.period); - Assert.Equal(Math.Round(this.TALIB[this.TALIB.Length - outBegIdx - 1], 8), Math.Round(QL.Last().v, 8)); + Assert.Equal(Math.Round(this.TALIB[this.TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero)); + } + + [Fact] + public void TRIMA() + { + TRIMA_Series QL = new(this.bars.Close, this.period, false); + Core.Trima(this.inclose, 0, this.bars.Count - 1, this.TALIB, out int outBegIdx, out _, this.period); + + Assert.Equal(Math.Round(this.TALIB[this.TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero)); } [Fact] @@ -90,7 +99,7 @@ public class TA_LIB EMA_Series QL = new(this.bars.Close, this.period, false); Core.Ema(this.inclose, 0, this.bars.Count - 1, this.TALIB, out int outBegIdx, out _, this.period); - Assert.Equal(Math.Round(this.TALIB[this.TALIB.Length - outBegIdx - 1], 8), Math.Round(QL.Last().v, 8)); + Assert.Equal(Math.Round(this.TALIB[this.TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero)); } [Fact] @@ -98,8 +107,8 @@ public class TA_LIB { WMA_Series QL = new(this.bars.Close, this.period, false); Core.Wma(this.inclose, 0, this.bars.Count - 1, this.TALIB, out int outBegIdx, out _, this.period); - - Assert.Equal(Math.Round(this.TALIB[this.TALIB.Length - outBegIdx - 1], 8), Math.Round(QL.Last().v, 8)); + + Assert.Equal(Math.Round(this.TALIB[this.TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero)); } [Fact] @@ -108,7 +117,7 @@ public class TA_LIB DEMA_Series QL = new(this.bars.Close, this.period, false); Core.Dema(this.inclose, 0, this.bars.Count - 1, this.TALIB, out int outBegIdx, out _, this.period); - Assert.Equal(Math.Round(this.TALIB[this.TALIB.Length - outBegIdx - 1], 8), Math.Round(QL.Last().v, 8)); + Assert.Equal(Math.Round(this.TALIB[this.TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero)); } [Fact] @@ -117,7 +126,7 @@ public class TA_LIB TEMA_Series QL = new(this.bars.Close, this.period, false); Core.Tema(this.inclose, 0, this.bars.Count - 1, this.TALIB, out int outBegIdx, out _, this.period); - Assert.Equal(Math.Round(this.TALIB[this.TALIB.Length - outBegIdx - 1], 8), Math.Round(QL.Last().v, 8)); + Assert.Equal(Math.Round(this.TALIB[this.TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero)); } [Fact] @@ -126,7 +135,7 @@ public class TA_LIB MAX_Series QL = new(this.bars.Close, this.period, false); Core.Max(this.inclose, 0, this.bars.Count - 1, this.TALIB, out int outBegIdx, out _, this.period); - Assert.Equal(Math.Round(this.TALIB[this.TALIB.Length - outBegIdx - 1], 8), Math.Round(QL.Last().v, 8)); + Assert.Equal(Math.Round(this.TALIB[this.TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero)); } [Fact] @@ -135,7 +144,7 @@ public class TA_LIB MIN_Series QL = new(this.bars.Close, this.period, false); Core.Min(this.inclose, 0, this.bars.Count - 1, this.TALIB, out int outBegIdx, out _, this.period); - Assert.Equal(Math.Round(this.TALIB[this.TALIB.Length - outBegIdx - 1], 8), Math.Round(QL.Last().v, 8)); + Assert.Equal(Math.Round(this.TALIB[this.TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero)); } [Fact] @@ -144,7 +153,16 @@ public class TA_LIB ADL_Series QL = new(this.bars, false); Core.Ad(this.inhigh, this.inlow, this.inclose, this.involume, 0, this.bars.Count - 1, this.TALIB, out int outBegIdx, out _); - Assert.Equal(Math.Round(this.TALIB[this.TALIB.Length - outBegIdx - 1], 8), Math.Round(QL.Last().v, 8)); + Assert.Equal(Math.Round(this.TALIB[this.TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero)); + } + + [Fact] + public void OBV() + { + OBV_Series QL = new(this.bars, this.period, false); + Core.Obv(this.inclose, this.involume, 0, this.bars.Count - 1, this.TALIB, out int outBegIdx, out _); + + Assert.Equal(Math.Round(this.TALIB[this.TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero)); } [Fact] @@ -153,7 +171,7 @@ public class TA_LIB ADOSC_Series QL = new(this.bars, false); Core.AdOsc(this.inhigh, this.inlow, this.inclose, this.involume, 0, this.bars.Count - 1, this.TALIB, out int outBegIdx, out _); - Assert.Equal(Math.Round(this.TALIB[this.TALIB.Length - outBegIdx - 1], 8), Math.Round(QL.Last().v, 8)); + Assert.Equal(Math.Round(this.TALIB[this.TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero)); } [Fact] @@ -162,7 +180,7 @@ public class TA_LIB ATR_Series QL = new(this.bars, this.period, false); Core.Atr(this.inhigh, this.inlow, this.inclose, 0, this.bars.Count - 1, this.TALIB, out int outBegIdx, out _, this.period); - Assert.Equal(Math.Round(this.TALIB[this.TALIB.Length - outBegIdx - 1], 8), Math.Round(QL.Last().v, 8)); + Assert.Equal(Math.Round(this.TALIB[this.TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero)); } [Fact] @@ -171,7 +189,7 @@ public class TA_LIB CCI_Series QL = new(this.bars, this.period, false); Core.Cci(this.inhigh, this.inlow, this.inclose, 0, this.bars.Count - 1, this.TALIB, out int outBegIdx, out _, this.period); - Assert.Equal(Math.Round(this.TALIB[this.TALIB.Length - outBegIdx - 1], 8), Math.Round(QL.Last().v, 8)); + Assert.Equal(Math.Round(this.TALIB[this.TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero)); } [Fact] @@ -180,7 +198,7 @@ public class TA_LIB RSI_Series QL = new(this.bars.Close, this.period, false); Core.Rsi(this.inclose, 0, this.bars.Count - 1, this.TALIB, out int outBegIdx, out _, this.period); - Assert.Equal(Math.Round(this.TALIB[this.TALIB.Length - outBegIdx - 1], 8), Math.Round(QL.Last().v, 8)); + Assert.Equal(Math.Round(this.TALIB[this.TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero)); } [Fact] @@ -189,7 +207,7 @@ public class TA_LIB TR_Series QL = new(this.bars, false); Core.TRange(this.inhigh, this.inlow, this.inclose, 0, this.bars.Count - 1, this.TALIB, out int outBegIdx, out _); - Assert.Equal(Math.Round(this.TALIB[this.TALIB.Length - outBegIdx - 1], 8), Math.Round(QL.Last().v, 8)); + Assert.Equal(Math.Round(this.TALIB[this.TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero)); } [Fact] @@ -199,8 +217,8 @@ public class TA_LIB double[] macdHist = new double[this.bars.Count]; MACD_Series QL = new(this.bars.Close, slow: 26, fast: 12, signal: 9, false); Core.Macd(this.inclose, 0, this.bars.Count - 1, outMacd: this.TALIB, outMacdSignal: macdSignal, outMacdHist: macdHist, out int outBegIdx, out _); - Assert.Equal(Math.Round(this.TALIB[this.TALIB.Length - outBegIdx - 1], 8), Math.Round(QL.Last().v, 8)); - Assert.Equal(Math.Round(macdSignal[macdSignal.Length - outBegIdx - 1], 8), Math.Round(QL.Signal.Last().v, 8)); + Assert.Equal(Math.Round(this.TALIB[this.TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero)); + Assert.Equal(Math.Round(macdSignal[macdSignal.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Signal.Last().v, 6, MidpointRounding.AwayFromZero)); } [Fact] @@ -211,9 +229,9 @@ public class TA_LIB double[] outLower = new double[this.bars.Count]; BBANDS_Series QL = new(this.bars.Close, period:26, multiplier:2.0, false); Core.Bbands(this.inclose, 0, this.bars.Count - 1, outRealUpperBand: outUpper, outRealMiddleBand: outMiddle, outRealLowerBand: outLower, out int outBegIdx, out _, optInTimePeriod:26, optInNbDevUp:2.0, optInNbDevDn:2.0); - Assert.Equal(Math.Round(outUpper[outUpper.Length - outBegIdx - 1], 7), Math.Round(QL.Upper.Last().v, 7)); - Assert.Equal(Math.Round(outMiddle[outMiddle.Length - outBegIdx - 1], 7), Math.Round(QL.Mid.Last().v, 7)); - Assert.Equal(Math.Round(outLower[outLower.Length - outBegIdx - 1], 7), Math.Round(QL.Lower.Last().v, 7)); + Assert.Equal(Math.Round(outUpper[outUpper.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Upper.Last().v, 6, MidpointRounding.AwayFromZero)); + Assert.Equal(Math.Round(outMiddle[outMiddle.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Mid.Last().v, 6, MidpointRounding.AwayFromZero)); + Assert.Equal(Math.Round(outLower[outLower.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Lower.Last().v, 6, MidpointRounding.AwayFromZero)); } [Fact] @@ -222,7 +240,7 @@ public class TA_LIB TSeries QL = this.bars.HL2; Core.MedPrice(this.inhigh, this.inlow, 0, this.bars.Count - 1, this.TALIB, out int outBegIdx, out _); - Assert.Equal(Math.Round(this.TALIB[this.TALIB.Length - outBegIdx - 1], 8), Math.Round(QL.Last().v, 8)); + Assert.Equal(Math.Round(this.TALIB[this.TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero)); } [Fact] @@ -231,7 +249,7 @@ public class TA_LIB TSeries QL = this.bars.HLC3; Core.TypPrice(this.inhigh, this.inlow, this.inclose, 0, this.bars.Count - 1, this.TALIB, out int outBegIdx, out _); - Assert.Equal(Math.Round(this.TALIB[this.TALIB.Length - outBegIdx - 1], 8), Math.Round(QL.Last().v, 8)); + Assert.Equal(Math.Round(this.TALIB[this.TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero)); } [Fact] @@ -240,7 +258,7 @@ public class TA_LIB TSeries QL = this.bars.OHLC4; Core.AvgPrice(this.inopen, this.inhigh, this.inlow, this.inclose, 0, this.bars.Count - 1, this.TALIB, out int outBegIdx, out _); - Assert.Equal(Math.Round(this.TALIB[this.TALIB.Length - outBegIdx - 1], 8), Math.Round(QL.Last().v, 8)); + Assert.Equal(Math.Round(this.TALIB[this.TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero)); } [Fact] @@ -249,6 +267,6 @@ public class TA_LIB TSeries QL = this.bars.HLCC4; Core.WclPrice( this.inhigh, this.inlow, this.inclose, 0, this.bars.Count - 1, this.TALIB, out int outBegIdx, out _); - Assert.Equal(Math.Round(this.TALIB[this.TALIB.Length - outBegIdx - 1], 8), Math.Round(QL.Last().v, 8)); + Assert.Equal(Math.Round(this.TALIB[this.TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero)); } } diff --git a/docs/crossovers.ipynb b/docs/crossovers.ipynb index f54ef389..304d3013 100644 --- a/docs/crossovers.ipynb +++ b/docs/crossovers.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "code", - "execution_count": 51, + "execution_count": 35, "metadata": { "dotnet_interactive": { "language": "csharp" @@ -34,7 +34,7 @@ }, { "cell_type": "code", - "execution_count": 52, + "execution_count": 40, "metadata": { "dotnet_interactive": { "language": "csharp" @@ -46,14 +46,14 @@ "outputs": [], "source": [ "Yahoo_Feed data = new(Symbol: \"MSFT\", Period: 200);\n", - "ZLEMA_Series calc1 = new(data.OHLC4,20,true);\n", - "HMA_Series calc2 = new(data.OHLC4,20, true);\n", - "HEMA_Series calc3 = new(data.OHLC4,20, true);" + "ZLEMA_Series calc1 = new(data.OHLC4,20);\n", + "HMA_Series calc2 = new(data.OHLC4,20);\n", + "HEMA_Series calc3 = new(data.OHLC4,20);" ] }, { "cell_type": "code", - "execution_count": 53, + "execution_count": 41, "metadata": { "dotnet_interactive": { "language": "csharp" @@ -64,12 +64,42 @@ }, "outputs": [ { - "ename": "Error", - "evalue": "(21,5): error CS7017: Member definition, statement, or end-of-file expected", - "output_type": "error", - "traceback": [ - "(21,5): error CS7017: Member definition, statement, or end-of-file expected" - ] + "data": { + "text/html": [ + "\n", + "
\n", + "
\r\n", + "\r\n", + "\n", + " \n", + "
\n" + ] + }, + "metadata": {}, + "output_type": "display_data" } ], "source": [ diff --git a/docs/readme.md b/docs/readme.md index 1f973337..ce7c2fcf 100644 --- a/docs/readme.md +++ b/docs/readme.md @@ -37,90 +37,90 @@ See [Getting Started](https://github.com/mihakralj/QuanTAlib/blob/main/Docs/gett | **BASIC TRANSFORMS** | **QuanTAlib** | **TA-LIB** | **Skender** | |--|:--:|:--:|:--:| -| ✔️ OC2 - (Open+Close)/2 |️ `.OC2` || ️`GetBaseQuote` | -| ⭐ HL2 - Median Price | `.HL2` | `MEDPRICE` | ️`GetBaseQuote` | -| ⭐ HLC3 - Typical Price | `.HLC3` | `TYPPRICE` || +| ✔️ OC2 - (Open+Close)/2 |️ `.OC2` || ️GetBaseQuote | +| ⭐ HL2 - Median Price | `.HL2` | MEDPRICE | ️GetBaseQuote | +| ⭐ HLC3 - Typical Price | `.HLC3` | TYPPRICE || | ✔️ OHL3 - (Open+High+Low)/3 | `.OHL3` ||| -| ⭐ OHLC4 - Average Price | `.OHLC4` | `AVGPRICE` |️ `GetBaseQuote` | -| ⭐ HLCC4 - Weighted Price | `.HLCC4` | `WCLPRICE` || -| ⭐ MAX - Max value | `MAX_Series` | `MAX` || -| ⭐ MIN - Min value | `MIN_Series` | `MIN` || -| ⛔ MID - Midpoint value || `MIDPOINT` || -| ⛔ MIDP - Midpoint price || `MIDPRICE` || -| ⛔ SUM - Summation || `SUM` || -| ⭐ ADD - Addition | `ADD_Series` | `ADD` || -| ⭐ SUB - Subtraction | `SUB_Series` | `SUB` || -| ⭐ MUL - Multiplication | `MUL_Series` | `MUL` || -| ⭐ DIV - Division | `DIV_Series` | `DIV` || +| ⭐ OHLC4 - Average Price | `.OHLC4` | AVGPRICE |️ GetBaseQuote | +| ⭐ HLCC4 - Weighted Price | `.HLCC4` | WCLPRICE || +| ⭐ MAX - Max value | `MAX_Series` | MAX || +| ⭐ MIN - Min value | `MIN_Series` | MIN || +| ⛔ MID - Midpoint value || MIDPOINT || +| ⛔ MIDP - Midpoint price || MIDPRICE || +| ⛔ SUM - Summation || SUM || +| ⭐ ADD - Addition | `ADD_Series` | ADD || +| ⭐ SUB - Subtraction | `SUB_Series` | SUB || +| ⭐ MUL - Multiplication | `MUL_Series` | MUL || +| ⭐ DIV - Division | `DIV_Series` | DIV || ||||| | **STATISTICS & NUMERICAL ANALYSIS** | **QuanTAlib** | **TA-LIB** | **Skender** | -| ✔️ BIAS - Bias | BIAS_Series ||| +| ✔️ BIAS - Bias | `BIAS_Series` ||| | ⛔ CORREL - Pearson's Correlation Coefficient || CORREL | GetCorrelation | | ⛔ COVAR - Covariance ||| GetCorrelation | -| ✔️ ENTP - Entropy | ENTP_Series ||| -| ✔️ KURT - Kurtosis | KURT_Series ||| -| ⭐ LINREG - Linear Regression | LINREG_Series || GetSlope | -| ⭐ MAD - Mean Absolute Deviation | MAD_Series || GetSma | -| ⭐ MAPE - Mean Absolute Percent Error | MAPE_Series || GetSma | -| ✔️ MED - Median value | MED_Series ||| -| ✔️ MSE - Mean Squared Error | MSE_Series || GetSma | +| ✔️ ENTP - Entropy | `ENTP_Series` ||| +| ✔️ KURT - Kurtosis | `KURT_Series` ||| +| ⭐ LINREG - Linear Regression | `LINREG_Series` || GetSlope | +| ⭐ MAD - Mean Absolute Deviation | `MAD_Series` || GetSma | +| ⭐ MAPE - Mean Absolute Percent Error | `MAPE_Series` || GetSma | +| ✔️ MED - Median value | `MED_Series` ||| +| ✔️ MSE - Mean Squared Error | `MSE_Series` || GetSma | | ⛔ SKEW - Skewness |||| -| ⭐ SDEV - Standard Deviation (Volatility) | SDEV_Series | STDDEV || -| ✔️ SSDEV - Sample Standard Deviation | SSDEV_Series ||| -| ✔️ SMAPE - Symmetric Mean Absolute Percent Error | SMAPE_Series ||| -| ✔️ VAR - Population Variance | VAR_Series | VAR || -| ✔️ SVAR - Sample Variance | SVAR_Series ||| +| ⭐ SDEV - Standard Deviation (Volatility) | `SDEV_Series` | STDDEV || +| ✔️ SSDEV - Sample Standard Deviation | `SSDEV_Series` ||| +| ✔️ SMAPE - Symmetric Mean Absolute Percent Error | `SMAPE_Series` ||| +| ✔️ VAR - Population Variance | `VAR_Series` | VAR || +| ✔️ SVAR - Sample Variance | `SVAR_Series` ||| | ⛔ QUANT - Quantile |||| -| ✔️ WMAPE - Weighted Mean Absolute Percent Error | WMAPE_Series ||| +| ✔️ WMAPE - Weighted Mean Absolute Percent Error | `WMAPE_Series` ||| | ⛔ ZSCORE - Number of standard deviations from mean |||| ||||| | **TREND INDICATORS & AVERAGES** | **QuanTAlib** | **TA-LIB** | **Skender** | | ⛔ AFIRMA - Autoregressive Finite Impulse Response Moving Average |||| -| ⭐ ALMA - Arnaud Legoux Moving Average | ALMA_Series || GetAlma | +| ⭐ ALMA - Arnaud Legoux Moving Average | `ALMA_Series` || GetAlma | | ⛔ ARIMA - Autoregressive Integrated Moving Average |||| -| ⭐ DEMA - Double EMA Average | DEMA_Series | DEMA | GetDema | -| ⭐ EMA - Exponential Moving Average | EMA_Series || GetEma | +| ⭐ DEMA - Double EMA Average | `DEMA_Series` | DEMA | GetDema | +| ⭐ EMA - Exponential Moving Average | `EMA_Series` || GetEma | | ⛔ EPMA - Endpoint Moving Average ||| GetEpma | | ⛔ FRAMA - Fractal Adaptive Moving Average |||| | ⛔ FWMA - Fibonacci's Weighted Moving Average |||| | ⛔ HILO - Gann High-Low Activator |||| -| ✔️ HEMA - Hull/EMA Average | HEMA_Series ||| +| ✔️ HEMA - Hull/EMA Average | `HEMA_Series` ||| | ⛔ Hilbert Transform Instantaneous Trendline || HT_TRENDLINE | GetHtTrendline | -| ⭐ HMA - Hull Moving Average | HMA_Series || GetHma | +| ⭐ HMA - Hull Moving Average | `HMA_Series` || GetHma | | ⛔ HWMA - Holt-Winter Moving Average |||| -| ✔️ JMA - Jurik Moving Average | JMA_Series ||| -| ⭐ KAMA - Kaufman's Adaptive Moving Average | KAMA_Series | KAMA | GetKama | +| ✔️ JMA - Jurik Moving Average | `JMA_Series` ||| +| ⭐ KAMA - Kaufman's Adaptive Moving Average | `KAMA_Series` | KAMA | GetKama | | ⛔ KDJ - KDJ Indicator (trend reversal) |||| | ⛔ LSMA - Least Squares Moving Average |||| -| ⭐ MACD - Moving Average Convergence/Divergence | MACD_Series | MACD | GetMacd | +| ⭐ MACD - Moving Average Convergence/Divergence | `MACD_Series` | MACD | GetMacd | | ⛔ MAMA - MESA Adaptive Moving Average || MAMA | GetMama | | ⛔ MCGD - McGinley Dynamic |||| | ⛔ MMA - Modified Moving Average |||| | ⛔ PPMA - Pivot Point Moving Average |||| | ⛔ PWMA - Pascal's Weighted Moving Average |||| -| ✔️ RMA - WildeR's Moving Average | RMA__Series ||| +| ✔️ RMA - WildeR's Moving Average | `RMA_Series` ||| | ⛔ SINWMA - Sine Weighted Moving Average |||| -| ⭐ SMA - Simple Moving Average | SMA_Series ||| -| ⭐ SMMA - Smoothed Moving Average | SMMA_Series ||| +| ⭐ SMA - Simple Moving Average | `SMA_Series` | SMA | GetSma | +| ⭐ SMMA - Smoothed Moving Average | `SMMA_Series` ||| | ⛔ SSF - Ehler's Super Smoother Filter |||| | ⛔ SUP - Supertrend |||| | ⛔ SWMA - Symmetric Weighted Moving Average |||| | ⛔ T3 - Tillson T3 Moving Average || T3 | GetT3 | -| ⭐ TEMA - Triple EMA Average | TEMA_Series | TEMA | GetTema | -| ⛔ TRIMA - Triangular Moving Average || TRIMA || +| ⭐ TEMA - Triple EMA Average | `TEMA_Series` | TEMA | GetTema | +| ⭐ TRIMA - Triangular Moving Average | `TRIMA_Series` | TRIMA || | ⛔ TSF - Time Series Forecast || TSF || | ⛔ VIDYA - Variable Index Dynamic Average |||| | ⛔ VOR - Vortex Indicator |||| -| ⭐ WMA - Weighted Moving Average | WMA_Series | WMA | GetWma | -| ✔️ ZLEMA - Zero Lag EMA Average | ZLEMA_Series ||| +| ⭐ WMA - Weighted Moving Average | `WMA_Series` | WMA | GetWma | +| ✔️ ZLEMA - Zero Lag EMA Average | `ZLEMA_Series` ||| ||||| | **VOLATILITY INDICATORS** | **QuanTAlib** | **TA-LIB** | **Skender** | -| ⭐ ADL - Chaikin Accumulation Distribution Line | ADL_Series | AD | GetAdl | -| ⭐ ADOSC - Chaikin Accumulation Distribution Oscillator | ADOSC_Series | ADOSC| GetAdl | -| ⭐ ATR - Average True Range | ATR_Series | ATR | GetAtr | -| ⭐ ATRP - Average True Range Percent | ATRP_Series || GetAtr | +| ⭐ ADL - Chaikin Accumulation Distribution Line | `ADL_Series` | AD | GetAdl | +| ⭐ ADOSC - Chaikin Accumulation Distribution Oscillator | `ADOSC_Series` | ADOSC| GetAdl | +| ⭐ ATR - Average True Range | `ATR_Series` | ATR | GetAtr | +| ⭐ ATRP - Average True Range Percent | `ATRP_Series` || GetAtr | | ⛔ BETA - Beta coefficient || BETA | GetBeta | -| ⭐ BBANDS - Bollinger Bands® | BBANDS_Series | BBANDS | GetBollingerBands | +| ⭐ BBANDS - Bollinger Bands® | `BBANDS_Series` | BBANDS | GetBollingerBands | | ⛔ CHAND - Chandelier Exit ||| GetChandelier | | ⛔ CRSI - Connor RSI ||| GetConnorsRsi | | ⛔ DON - Donchian Channels ||| GetDonchian | @@ -130,11 +130,11 @@ See [Getting Started](https://github.com/mihakralj/QuanTAlib/blob/main/Docs/gett | ⛔ KEL - Keltner Channels ||| GetKeltner | | ⛔ NATR - Normalized Average True Range || NATR | GetAtr | | ⛔ CHN - Price Channel Indicator |||| -| ⭐ RSI - Relative Strength Index | RSI_Series | RSI | GetRsi | +| ⭐ RSI - Relative Strength Index | `RSI_Series` | RSI | GetRsi | | ⛔ SAR - Parabolic Stop and Reverse || SAR | GetParabolicSar | | ⛔ SRSI - Stochastic RSI || STOCHRSI | GetStochRsi | | ⛔ STARC - Starc Bands |||| -| ⭐ TR - True Range | TR_Series | TRANGE | GetTr | +| ⭐ TR - True Range | `TR_Series` | TRANGE | GetTr | | ⛔ UI - Ulcer Index |||| | ⛔ VSTOP - Volatility Stop |||| ||||| @@ -146,7 +146,7 @@ See [Getting Started](https://github.com/mihakralj/QuanTAlib/blob/main/Docs/gett | ⛔ APO - Absolute Price Oscillator || APO || | ⛔ AROON - Aroon oscillator || AROON | GetAroon | | ⛔ BOP - Balance of Power || BOP | GetBop | -| ⭐ CCI - Commodity Channel Index | CCI_Series | CCI | GetCci | +| ⭐ CCI - Commodity Channel Index | `CCI_Series` | CCI | GetCci | | ⛔ CFO - Chande Forcast Oscillator |||| | ⛔ CMO - Chande Momentum Oscillator || CMO | GetCmo | | ⛔ COG - Center of Gravity |||| @@ -181,7 +181,7 @@ See [Getting Started](https://github.com/mihakralj/QuanTAlib/blob/main/Docs/gett | ⛔ AOBV - Archer On-Balance Volume |||| | ⛔ CMF - Chaikin Money Flow |||| | ⛔ EOM - Ease of Movement |||| -| ⛔ OBV - On-Balance Volume || OBV | GetObv | +| ⭐ OBV - On-Balance Volume | `OBV_Series` | OBV | GetObv | | ⛔ PRS - Price Relative Strength ||| | ⛔ PVOL - Price-Volume |||| | ⛔ PVO - Percentage Volume Oscillator |||| From 9d12b7bcbe8fb5db7810249b381e3cf42d2f2425 Mon Sep 17 00:00:00 2001 From: Miha Kralj Date: Fri, 11 Nov 2022 21:15:18 -0800 Subject: [PATCH 4/4] OBV, TRIMA --- Source/QuanTAlib.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/QuanTAlib.csproj b/Source/QuanTAlib.csproj index 443980bc..c43aedcb 100644 --- a/Source/QuanTAlib.csproj +++ b/Source/QuanTAlib.csproj @@ -1,7 +1,7 @@  - 0.1.17 + 0.1.18 QuanTAlib