From 3df6219de091a8b39298b8cd62b7696d6f3caea7 Mon Sep 17 00:00:00 2001 From: fff-git Date: Fri, 22 May 2020 00:09:07 +0200 Subject: [PATCH 1/5] stoch.py : change returned df columns name. Issue was : if parameters slow_k = slow_d -> column name was identical (STOCH_3 for ex) and one was lost --- pandas_ta/momentum/stoch.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/pandas_ta/momentum/stoch.py b/pandas_ta/momentum/stoch.py index eed2b26..3c87097 100644 --- a/pandas_ta/momentum/stoch.py +++ b/pandas_ta/momentum/stoch.py @@ -44,10 +44,10 @@ def stoch(high, low, close, fast_k=None, slow_k=None, slow_d=None, offset=None, slowd.fillna(method=kwargs['fill_method'], inplace=True) # Name and Categorize it - fastk.name = f"STOCHF_{fast_k}" - fastd.name = f"STOCHF_{slow_d}" - slowk.name = f"STOCH_{slow_k}" - slowd.name = f"STOCH_{slow_d}" + fastk.name = f"STOCHFK_{fast_k}" + fastd.name = f"STOCHFD_{slow_d}" + slowk.name = f"STOCHSK_{slow_k}" + slowd.name = f"STOCHSD_{slow_d}" fastk.category = fastd.category = slowk.category = slowd.category = 'momentum' # Prepare DataFrame to return @@ -98,4 +98,4 @@ Kwargs: Returns: pd.DataFrame: fastk, fastd, slowk, slowd columns. -""" \ No newline at end of file +""" From 2f7aec18eb87dec93b9e9d6472d4e50b9203f887 Mon Sep 17 00:00:00 2001 From: fff-git Date: Tue, 26 May 2020 12:56:50 +0200 Subject: [PATCH 2/5] Add Heikin Ashi ti --- pandas_ta/overlap/ha.py | 103 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 103 insertions(+) create mode 100644 pandas_ta/overlap/ha.py diff --git a/pandas_ta/overlap/ha.py b/pandas_ta/overlap/ha.py new file mode 100644 index 0000000..ea6219a --- /dev/null +++ b/pandas_ta/overlap/ha.py @@ -0,0 +1,103 @@ +# -*- coding: utf-8 -*- +import numpy as np +from pandas import DataFrame +from ..utils import get_offset, verify_series + + +def ha(open, high, low, close, offset=None, **kwargs): + # indicator : Heiken Ashi + # Validate Arguments + open = verify_series(open) + high = verify_series(high) + low = verify_series(low) + close = verify_series(close) + offset = get_offset(offset) + + # Initialization of the ha_open serie + ha_open = np.zeros(shape=(len(close))) + + # ha_open of the first element + ha_open[0] = 0.5 * (open[0] + close[0]) + + # shift open and close series by one to calculate ha_open other elements + open_shifted = np.empty_like(open) + open_shifted[:1] = np.nan + open_shifted[1:] = open[:-1] + close_shifted = np.empty_like(close) + close_shifted[:1] = np.nan + close_shifted[1:] = close[:-1] + # Calculation of ha_open except first element + ha_open[1:] = 0.5 * (open_shifted[1:] + close_shifted[1:]) + + # calculation of ha_close, ha_high, ha_low + ha_close = 0.25 * (open + high + low + close) + ha_high = np.maximum.reduce([high, ha_open, ha_close]) + ha_low = np.minimum.reduce([low, ha_open, ha_close]) + + # Prepare DataFrame to return + data = {'ha_open': ha_open, 'ha_high': ha_high, 'ha_low': ha_low, 'ha_close': ha_close} + hadf = DataFrame(data) + hadf.name = "Heiken-Ashi" + hadf.category = 'overlap' + + # Apply offset if needed + if offset != 0: + hadf = hadf.shift(offset) + + # Handle fills + if 'fillna' in kwargs: + hadf.fillna(kwargs['fillna'], inplace=True) + + if 'fill_method' in kwargs: + hadf.fillna(method=kwargs['fill_method'], inplace=True) + + return hadf + + +ha.__doc__ = \ + """Heiken Ashi (HA) + +The Heikin-Ashi technique averages price data to create a Japanese candlestick chart that filters out market noise. +Heikin-Ashi charts, developed by Munehisa Homma in the 1700s, +share some characteristics with standard candlestick charts but differ based on the values used to create each candle. +Instead of using the open, high, low, and close like standard candlestick charts, +the Heikin-Ashi technique uses a modified formula based on two-period averages. +This gives the chart a smoother appearance, making it easier to spots trends and reversals, +but also obscures gaps and some price data. + +Sources: + https://www.investopedia.com/terms/h/heikinashi.asp + +Calculation: + The Formula for the Heikin-Ashi Technique Is: + +Heikin-Ashi Close=(Open0+High0+Low0+Close0)/4 +Heikin-Ashi Open=(HA Open−1+HA Close−1)/2 +Heikin-Ashi High=Max (High0,HA Open0,HA Close0) +Heikin-Ashi Low=Min (Low0,HA Open0,HA Close0) +where:Open0 etc.=Values from the current period +Open−1 etc.=Values from the prior period +HA=Heikin-Ashi + + How to Calculate Heikin-Ashi + + Use one period to create the first Heikin-Ashi (HA) candle, using the formulas. + For example use the high, low, open, and close to create the first HA close price. + Use the open and close to create the first HA open. + The high of the period will be the first HA high, and the low will be the first HA low. + With the first HA calculated, it is now possible to continue computing the HA candles per the formulas. +​​ +Args: + open (pd.Series): Series of 'open's + high (pd.Series): Series of 'high's + low (pd.Series): Series of 'low's + close (pd.Series): Series of 'close's + + +Kwargs: + fillna (value, optional): pd.DataFrame.fillna(value) + fill_method (value, optional): Type of fill method + +Returns: + pd.DataFrame: ha_open, ha_high,ha_low, ha_close columns. +""" From 11e7eda03f9ab68abf6173ce16c67d9b8785a1d9 Mon Sep 17 00:00:00 2001 From: fff-git Date: Thu, 28 May 2020 17:50:26 +0200 Subject: [PATCH 3/5] Add 2 TI : Heikin-Ashi and supertrend --- __init__.py | 0 pandas_ta/Untitled.ipynb | 667 +++++++++++++++++++++++++++++ pandas_ta/core.py | 23 + pandas_ta/trend/__init__.py | 2 + pandas_ta/{overlap => trend}/ha.py | 32 +- pandas_ta/trend/supertrend.py | 101 +++++ 6 files changed, 807 insertions(+), 18 deletions(-) create mode 100644 __init__.py create mode 100644 pandas_ta/Untitled.ipynb rename pandas_ta/{overlap => trend}/ha.py (80%) create mode 100644 pandas_ta/trend/supertrend.py diff --git a/__init__.py b/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/pandas_ta/Untitled.ipynb b/pandas_ta/Untitled.ipynb new file mode 100644 index 0000000..78587a3 --- /dev/null +++ b/pandas_ta/Untitled.ipynb @@ -0,0 +1,667 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 23, + "metadata": {}, + "outputs": [], + "source": [ + "import pandas_ta as ta" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "import pandas as pd" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "df = pd.read_csv('/virt/admin/Fic_entree/Dwx-NDXH8.csv', sep=',', header=None)" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
0123456
02017.04.2000:005395.35455.35393.35401.534502
12017.04.2008:005401.85421.55399.85418.87241
22017.04.2016:005418.55455.35412.05444.321038
32017.04.2100:005442.85450.05442.55448.52181
42017.04.2108:005448.45455.35447.85448.57406
........................
23872020.05.2600:009532.49597.89509.89587.615120
23882020.05.2608:009587.89609.19542.59555.631628
23892020.05.2616:009556.19574.89378.19417.373867
23902020.05.2700:009413.59500.59380.79487.520104
23912020.05.2708:009487.29513.09391.79395.533445
\n", + "

2392 rows × 7 columns

\n", + "
" + ], + "text/plain": [ + " 0 1 2 3 4 5 6\n", + "0 2017.04.20 00:00 5395.3 5455.3 5393.3 5401.5 34502\n", + "1 2017.04.20 08:00 5401.8 5421.5 5399.8 5418.8 7241\n", + "2 2017.04.20 16:00 5418.5 5455.3 5412.0 5444.3 21038\n", + "3 2017.04.21 00:00 5442.8 5450.0 5442.5 5448.5 2181\n", + "4 2017.04.21 08:00 5448.4 5455.3 5447.8 5448.5 7406\n", + "... ... ... ... ... ... ... ...\n", + "2387 2020.05.26 00:00 9532.4 9597.8 9509.8 9587.6 15120\n", + "2388 2020.05.26 08:00 9587.8 9609.1 9542.5 9555.6 31628\n", + "2389 2020.05.26 16:00 9556.1 9574.8 9378.1 9417.3 73867\n", + "2390 2020.05.27 00:00 9413.5 9500.5 9380.7 9487.5 20104\n", + "2391 2020.05.27 08:00 9487.2 9513.0 9391.7 9395.5 33445\n", + "\n", + "[2392 rows x 7 columns]" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "df.columns=['date', 'time', 'open', 'high', 'low', 'close', 'ticks']" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
STOCHFk_14STOCHFd_3STOCHk_3STOCHd_3
0NaNNaNNaNNaN
1NaNNaNNaNNaN
282.258065NaNNaNNaN
387.747748NaNNaNNaN
484.29561284.76714184.767141NaN
...............
238793.09878295.82045095.82045096.319133
238846.12286078.47530778.47530790.117018
238916.96969752.06378052.06378075.453179
239047.35930736.81728836.81728855.785458
23918.84595824.39165424.39165437.757574
\n", + "

2392 rows × 4 columns

\n", + "
" + ], + "text/plain": [ + " STOCHFk_14 STOCHFd_3 STOCHk_3 STOCHd_3\n", + "0 NaN NaN NaN NaN\n", + "1 NaN NaN NaN NaN\n", + "2 82.258065 NaN NaN NaN\n", + "3 87.747748 NaN NaN NaN\n", + "4 84.295612 84.767141 84.767141 NaN\n", + "... ... ... ... ...\n", + "2387 93.098782 95.820450 95.820450 96.319133\n", + "2388 46.122860 78.475307 78.475307 90.117018\n", + "2389 16.969697 52.063780 52.063780 75.453179\n", + "2390 47.359307 36.817288 36.817288 55.785458\n", + "2391 8.845958 24.391654 24.391654 37.757574\n", + "\n", + "[2392 rows x 4 columns]" + ] + }, + "execution_count": 18, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df.ta.stoch(df['high'], df['low'], df['close'], 14,3,3, append = True)" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Index(['date', 'time', 'open', 'high', 'low', 'close', 'ticks', 'STOCHFk_14',\n", + " 'STOCHFd_3', 'STOCHk_3', 'STOCHd_3'],\n", + " dtype='object')" + ] + }, + "execution_count": 19, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df.columns" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
datetimeopenhighlowcloseticksSTOCHFk_14STOCHFd_3STOCHk_3STOCHd_3
02017.04.2000:005395.35455.35393.35401.534502NaNNaNNaNNaN
12017.04.2008:005401.85421.55399.85418.87241NaNNaNNaNNaN
22017.04.2016:005418.55455.35412.05444.32103882.258065NaNNaNNaN
32017.04.2100:005442.85450.05442.55448.5218187.747748NaNNaNNaN
42017.04.2108:005448.45455.35447.85448.5740684.29561284.76714184.767141NaN
....................................
23872020.05.2600:009532.49597.89509.89587.61512093.09878295.82045095.82045096.319133
23882020.05.2608:009587.89609.19542.59555.63162846.12286078.47530778.47530790.117018
23892020.05.2616:009556.19574.89378.19417.37386716.96969752.06378052.06378075.453179
23902020.05.2700:009413.59500.59380.79487.52010447.35930736.81728836.81728855.785458
23912020.05.2708:009487.29513.09391.79395.5334458.84595824.39165424.39165437.757574
\n", + "

2392 rows × 11 columns

\n", + "
" + ], + "text/plain": [ + " date time open high low close ticks STOCHFk_14 \\\n", + "0 2017.04.20 00:00 5395.3 5455.3 5393.3 5401.5 34502 NaN \n", + "1 2017.04.20 08:00 5401.8 5421.5 5399.8 5418.8 7241 NaN \n", + "2 2017.04.20 16:00 5418.5 5455.3 5412.0 5444.3 21038 82.258065 \n", + "3 2017.04.21 00:00 5442.8 5450.0 5442.5 5448.5 2181 87.747748 \n", + "4 2017.04.21 08:00 5448.4 5455.3 5447.8 5448.5 7406 84.295612 \n", + "... ... ... ... ... ... ... ... ... \n", + "2387 2020.05.26 00:00 9532.4 9597.8 9509.8 9587.6 15120 93.098782 \n", + "2388 2020.05.26 08:00 9587.8 9609.1 9542.5 9555.6 31628 46.122860 \n", + "2389 2020.05.26 16:00 9556.1 9574.8 9378.1 9417.3 73867 16.969697 \n", + "2390 2020.05.27 00:00 9413.5 9500.5 9380.7 9487.5 20104 47.359307 \n", + "2391 2020.05.27 08:00 9487.2 9513.0 9391.7 9395.5 33445 8.845958 \n", + "\n", + " STOCHFd_3 STOCHk_3 STOCHd_3 \n", + "0 NaN NaN NaN \n", + "1 NaN NaN NaN \n", + "2 NaN NaN NaN \n", + "3 NaN NaN NaN \n", + "4 84.767141 84.767141 NaN \n", + "... ... ... ... \n", + "2387 95.820450 95.820450 96.319133 \n", + "2388 78.475307 78.475307 90.117018 \n", + "2389 52.063780 52.063780 75.453179 \n", + "2390 36.817288 36.817288 55.785458 \n", + "2391 24.391654 24.391654 37.757574 \n", + "\n", + "[2392 rows x 11 columns]" + ] + }, + "execution_count": 20, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": {}, + "outputs": [ + { + "ename": "AttributeError", + "evalue": "module 'pandas_ta' has no attribute 'ha'", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mAttributeError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mhelp\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mta\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mha\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", + "\u001b[0;31mAttributeError\u001b[0m: module 'pandas_ta' has no attribute 'ha'" + ] + } + ], + "source": [ + "help(ta.ha)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.3" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/pandas_ta/core.py b/pandas_ta/core.py index 9b43848..e77bf8c 100644 --- a/pandas_ta/core.py +++ b/pandas_ta/core.py @@ -881,6 +881,17 @@ class AnalysisIndicators(BasePandasObject): self._append(result, **kwargs) return result + def ha(self, open=None, high=None, low=None, close=None, offset=None, **kwargs): + open = self._get_column(open, 'open') + high = self._get_column(high, 'high') + low = self._get_column(low, 'low') + close = self._get_column(close, 'close') + + result = ha(open=open, high=high, low=low, close=close, offset=offset, **kwargs) + self._add_prefix_suffix(result, **kwargs) + self._append(result, **kwargs) + return result + def increasing(self, close=None, length=None, asint=True, offset=None, **kwargs): close = self._get_column(close, 'close') @@ -939,6 +950,18 @@ class AnalysisIndicators(BasePandasObject): self._append(result, **kwargs) return result + def supertrend(self, high=None, low=None, close=None, period=None, multiplier=None, mamode=None, drift=None, + offset=None, **kwargs): + high = self._get_column(high, 'high') + low = self._get_column(low, 'low') + close = self._get_column(close, 'close') + + result = supertrend(high=high, low=low, close=close, period=period, multiplier=multiplier, mamode=mamode, drift=drift, offset=offset, **kwargs) + self._add_prefix_suffix(result, **kwargs) + self._append(result, **kwargs) + return result + + def vortex(self, high=None, low=None, close=None, drift=None, offset=None, **kwargs): high = self._get_column(high, 'high') low = self._get_column(low, 'low') diff --git a/pandas_ta/trend/__init__.py b/pandas_ta/trend/__init__.py index dbdce91..f98b9da 100644 --- a/pandas_ta/trend/__init__.py +++ b/pandas_ta/trend/__init__.py @@ -6,10 +6,12 @@ from .chop import chop from .cksp import cksp from .decreasing import decreasing from .dpo import dpo +from .ha import ha from .increasing import increasing from .linear_decay import linear_decay from .long_run import long_run from .psar import psar from .qstick import qstick from .short_run import short_run +from .supertrend import supertrend from .vortex import vortex \ No newline at end of file diff --git a/pandas_ta/overlap/ha.py b/pandas_ta/trend/ha.py similarity index 80% rename from pandas_ta/overlap/ha.py rename to pandas_ta/trend/ha.py index ea6219a..dc41edb 100644 --- a/pandas_ta/overlap/ha.py +++ b/pandas_ta/trend/ha.py @@ -1,11 +1,11 @@ # -*- coding: utf-8 -*- import numpy as np from pandas import DataFrame -from ..utils import get_offset, verify_series +from pandas_ta.utils import get_offset, verify_series def ha(open, high, low, close, offset=None, **kwargs): - # indicator : Heiken Ashi + # indicator : Heikin Ashi # Validate Arguments open = verify_series(open) high = verify_series(high) @@ -13,32 +13,28 @@ def ha(open, high, low, close, offset=None, **kwargs): close = verify_series(close) offset = get_offset(offset) - # Initialization of the ha_open serie + #calculate ha_close + ha_close = 0.25 * (open + high + low + close) + + # Initialization of the ha_open array ha_open = np.zeros(shape=(len(close))) # ha_open of the first element ha_open[0] = 0.5 * (open[0] + close[0]) - # shift open and close series by one to calculate ha_open other elements - open_shifted = np.empty_like(open) - open_shifted[:1] = np.nan - open_shifted[1:] = open[:-1] - close_shifted = np.empty_like(close) - close_shifted[:1] = np.nan - close_shifted[1:] = close[:-1] - # Calculation of ha_open except first element - ha_open[1:] = 0.5 * (open_shifted[1:] + close_shifted[1:]) + #calculate ha_open. Based on previous ha_open & ha_close + for i in range (1, len(close)): + ha_open[i] = 0.5 * (ha_open[i-1] + ha_close[i-1]) - # calculation of ha_close, ha_high, ha_low - ha_close = 0.25 * (open + high + low + close) + # calculation of ha_high & ha_low ha_high = np.maximum.reduce([high, ha_open, ha_close]) ha_low = np.minimum.reduce([low, ha_open, ha_close]) # Prepare DataFrame to return data = {'ha_open': ha_open, 'ha_high': ha_high, 'ha_low': ha_low, 'ha_close': ha_close} hadf = DataFrame(data) - hadf.name = "Heiken-Ashi" - hadf.category = 'overlap' + hadf.name = "Heikin-Ashi" + hadf.category = 'trend' # Apply offset if needed if offset != 0: @@ -55,7 +51,7 @@ def ha(open, high, low, close, offset=None, **kwargs): ha.__doc__ = \ - """Heiken Ashi (HA) + """Heikin Ashi (HA) The Heikin-Ashi technique averages price data to create a Japanese candlestick chart that filters out market noise. Heikin-Ashi charts, developed by Munehisa Homma in the 1700s, @@ -69,7 +65,7 @@ Sources: https://www.investopedia.com/terms/h/heikinashi.asp Calculation: - The Formula for the Heikin-Ashi Technique Is: + The Formula for the Heikin-Ashi technique is: Heikin-Ashi Close=(Open0+High0+Low0+Close0)/4 Heikin-Ashi Open=(HA Open−1+HA Close−1)/2 diff --git a/pandas_ta/trend/supertrend.py b/pandas_ta/trend/supertrend.py new file mode 100644 index 0000000..f32b315 --- /dev/null +++ b/pandas_ta/trend/supertrend.py @@ -0,0 +1,101 @@ +# -*- coding: utf-8 -*- +import numpy as np +from pandas import DataFrame +from ..utils import get_offset, verify_series +from ..volatility import atr + +def supertrend(high, low, close, period=None, multiplier=None, mamode=None, drift=None, offset=None, **kwargs): + # indicator : supertrend + # Validate Arguments + high = verify_series(high) + low = verify_series(low) + close = verify_series(close) + offset = get_offset(offset) + period = int(period) if period and period > 0 else 10 + multiplier = float(multiplier) if multiplier and multiplier > 0 else 1.5 + min_periods = int(kwargs['min_periods']) if 'min_periods' in kwargs and kwargs[ + 'min_periods'] is not None else period + + st_updown = np.zeros(shape=(len(close))) + strend = np.zeros(shape=(len(close))) + + # Bands initial calculation + midrange = 0.5 * (high + low) + distance = multiplier * atr(high, low, close, period, mamode, drift, offset, min_periods=min_periods) + lowerband = midrange - distance + upperband = midrange + distance + + # final calculation loop + for i in range(1, len(close)): + if close[i] > upperband[i-1]: + st_updown[i] = 1 + elif close[i] < lowerband[i-1]: + st_updown[i] = -1 + else: + st_updown[i] = st_updown[i-1] + if st_updown[i] > 0 and lowerband[i] < lowerband[i-1]: + lowerband[i] = lowerband[i-1] + if st_updown[i] < 0 and upperband[i] > upperband[i-1]: + upperband[i] = upperband[i-1] + if st_updown[i] < 0 and st_updown[i-1] > 0: + upperband = midrange + distance + if st_updown[i] > 0 and st_updown[i-1] < 0: + lowerband = midrange - distance + if st_updown[i] < 0 : + strend[i] = upperband[i] + else: + strend[i] = lowerband[i] + + + # Prepare DataFrame to return + data = {f"supertrend_{period}_{multiplier}": strend, f"st_updown_{period}_{multiplier}": st_updown} + supertrend_df = DataFrame(data) + supertrend_df.name = f"supertrend_{period}_{multiplier}" + supertrend_df.category = 'trend' + + + + # Apply offset if needed + if offset != 0: + supertrend_df = supertrend_df.shift(offset) + + # Handle fills + if 'fillna' in kwargs: + supertrend_df.fillna(kwargs['fillna'], inplace=True) + + if 'fill_method' in kwargs: + supertrend_df.fillna(method=kwargs['fill_method'], inplace=True) + + + + return supertrend_df + +supertrend.__doc__ = \ +"""Supertrend (supertrend) + +Supertrend is a trend indicator. It was created by Olivier Seban + +Sources: +https://www.abcbourse.com/apprendre/11_le_supertrend.html +(in french, but many other can be found using a search engine) + +Calculation: + Default Inputs: + period = 10 + multiplier = 1.5 + + +Args: + high (pd.Series): Series of 'high's + low (pd.Series): Series of 'low's + close (pd.Series): Series of 'close's + + offset (int): How many periods to offset the result. Default: 0 + +Kwargs: + fillna (value, optional): pd.DataFrame.fillna(value) + fill_method (value, optional): Type of fill method + +Returns: + pd.DataFrame: supertrend, st_updown, slowk, slowd columns. +""" \ No newline at end of file From 64f1b3563c08fece6a466dd361b8360cc7a2d154 Mon Sep 17 00:00:00 2001 From: fff-git Date: Thu, 28 May 2020 17:51:13 +0200 Subject: [PATCH 4/5] Add 2 TI : Heikin-Ashi and supertrend --- pandas_ta/Untitled.ipynb | 667 --------------------------------------- 1 file changed, 667 deletions(-) delete mode 100644 pandas_ta/Untitled.ipynb diff --git a/pandas_ta/Untitled.ipynb b/pandas_ta/Untitled.ipynb deleted file mode 100644 index 78587a3..0000000 --- a/pandas_ta/Untitled.ipynb +++ /dev/null @@ -1,667 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": 23, - "metadata": {}, - "outputs": [], - "source": [ - "import pandas_ta as ta" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [], - "source": [ - "import pandas as pd" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [], - "source": [ - "df = pd.read_csv('/virt/admin/Fic_entree/Dwx-NDXH8.csv', sep=',', header=None)" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
0123456
02017.04.2000:005395.35455.35393.35401.534502
12017.04.2008:005401.85421.55399.85418.87241
22017.04.2016:005418.55455.35412.05444.321038
32017.04.2100:005442.85450.05442.55448.52181
42017.04.2108:005448.45455.35447.85448.57406
........................
23872020.05.2600:009532.49597.89509.89587.615120
23882020.05.2608:009587.89609.19542.59555.631628
23892020.05.2616:009556.19574.89378.19417.373867
23902020.05.2700:009413.59500.59380.79487.520104
23912020.05.2708:009487.29513.09391.79395.533445
\n", - "

2392 rows × 7 columns

\n", - "
" - ], - "text/plain": [ - " 0 1 2 3 4 5 6\n", - "0 2017.04.20 00:00 5395.3 5455.3 5393.3 5401.5 34502\n", - "1 2017.04.20 08:00 5401.8 5421.5 5399.8 5418.8 7241\n", - "2 2017.04.20 16:00 5418.5 5455.3 5412.0 5444.3 21038\n", - "3 2017.04.21 00:00 5442.8 5450.0 5442.5 5448.5 2181\n", - "4 2017.04.21 08:00 5448.4 5455.3 5447.8 5448.5 7406\n", - "... ... ... ... ... ... ... ...\n", - "2387 2020.05.26 00:00 9532.4 9597.8 9509.8 9587.6 15120\n", - "2388 2020.05.26 08:00 9587.8 9609.1 9542.5 9555.6 31628\n", - "2389 2020.05.26 16:00 9556.1 9574.8 9378.1 9417.3 73867\n", - "2390 2020.05.27 00:00 9413.5 9500.5 9380.7 9487.5 20104\n", - "2391 2020.05.27 08:00 9487.2 9513.0 9391.7 9395.5 33445\n", - "\n", - "[2392 rows x 7 columns]" - ] - }, - "execution_count": 4, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "df" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": {}, - "outputs": [], - "source": [ - "df.columns=['date', 'time', 'open', 'high', 'low', 'close', 'ticks']" - ] - }, - { - "cell_type": "code", - "execution_count": 18, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
STOCHFk_14STOCHFd_3STOCHk_3STOCHd_3
0NaNNaNNaNNaN
1NaNNaNNaNNaN
282.258065NaNNaNNaN
387.747748NaNNaNNaN
484.29561284.76714184.767141NaN
...............
238793.09878295.82045095.82045096.319133
238846.12286078.47530778.47530790.117018
238916.96969752.06378052.06378075.453179
239047.35930736.81728836.81728855.785458
23918.84595824.39165424.39165437.757574
\n", - "

2392 rows × 4 columns

\n", - "
" - ], - "text/plain": [ - " STOCHFk_14 STOCHFd_3 STOCHk_3 STOCHd_3\n", - "0 NaN NaN NaN NaN\n", - "1 NaN NaN NaN NaN\n", - "2 82.258065 NaN NaN NaN\n", - "3 87.747748 NaN NaN NaN\n", - "4 84.295612 84.767141 84.767141 NaN\n", - "... ... ... ... ...\n", - "2387 93.098782 95.820450 95.820450 96.319133\n", - "2388 46.122860 78.475307 78.475307 90.117018\n", - "2389 16.969697 52.063780 52.063780 75.453179\n", - "2390 47.359307 36.817288 36.817288 55.785458\n", - "2391 8.845958 24.391654 24.391654 37.757574\n", - "\n", - "[2392 rows x 4 columns]" - ] - }, - "execution_count": 18, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "df.ta.stoch(df['high'], df['low'], df['close'], 14,3,3, append = True)" - ] - }, - { - "cell_type": "code", - "execution_count": 19, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "Index(['date', 'time', 'open', 'high', 'low', 'close', 'ticks', 'STOCHFk_14',\n", - " 'STOCHFd_3', 'STOCHk_3', 'STOCHd_3'],\n", - " dtype='object')" - ] - }, - "execution_count": 19, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "df.columns" - ] - }, - { - "cell_type": "code", - "execution_count": 20, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
datetimeopenhighlowcloseticksSTOCHFk_14STOCHFd_3STOCHk_3STOCHd_3
02017.04.2000:005395.35455.35393.35401.534502NaNNaNNaNNaN
12017.04.2008:005401.85421.55399.85418.87241NaNNaNNaNNaN
22017.04.2016:005418.55455.35412.05444.32103882.258065NaNNaNNaN
32017.04.2100:005442.85450.05442.55448.5218187.747748NaNNaNNaN
42017.04.2108:005448.45455.35447.85448.5740684.29561284.76714184.767141NaN
....................................
23872020.05.2600:009532.49597.89509.89587.61512093.09878295.82045095.82045096.319133
23882020.05.2608:009587.89609.19542.59555.63162846.12286078.47530778.47530790.117018
23892020.05.2616:009556.19574.89378.19417.37386716.96969752.06378052.06378075.453179
23902020.05.2700:009413.59500.59380.79487.52010447.35930736.81728836.81728855.785458
23912020.05.2708:009487.29513.09391.79395.5334458.84595824.39165424.39165437.757574
\n", - "

2392 rows × 11 columns

\n", - "
" - ], - "text/plain": [ - " date time open high low close ticks STOCHFk_14 \\\n", - "0 2017.04.20 00:00 5395.3 5455.3 5393.3 5401.5 34502 NaN \n", - "1 2017.04.20 08:00 5401.8 5421.5 5399.8 5418.8 7241 NaN \n", - "2 2017.04.20 16:00 5418.5 5455.3 5412.0 5444.3 21038 82.258065 \n", - "3 2017.04.21 00:00 5442.8 5450.0 5442.5 5448.5 2181 87.747748 \n", - "4 2017.04.21 08:00 5448.4 5455.3 5447.8 5448.5 7406 84.295612 \n", - "... ... ... ... ... ... ... ... ... \n", - "2387 2020.05.26 00:00 9532.4 9597.8 9509.8 9587.6 15120 93.098782 \n", - "2388 2020.05.26 08:00 9587.8 9609.1 9542.5 9555.6 31628 46.122860 \n", - "2389 2020.05.26 16:00 9556.1 9574.8 9378.1 9417.3 73867 16.969697 \n", - "2390 2020.05.27 00:00 9413.5 9500.5 9380.7 9487.5 20104 47.359307 \n", - "2391 2020.05.27 08:00 9487.2 9513.0 9391.7 9395.5 33445 8.845958 \n", - "\n", - " STOCHFd_3 STOCHk_3 STOCHd_3 \n", - "0 NaN NaN NaN \n", - "1 NaN NaN NaN \n", - "2 NaN NaN NaN \n", - "3 NaN NaN NaN \n", - "4 84.767141 84.767141 NaN \n", - "... ... ... ... \n", - "2387 95.820450 95.820450 96.319133 \n", - "2388 78.475307 78.475307 90.117018 \n", - "2389 52.063780 52.063780 75.453179 \n", - "2390 36.817288 36.817288 55.785458 \n", - "2391 24.391654 24.391654 37.757574 \n", - "\n", - "[2392 rows x 11 columns]" - ] - }, - "execution_count": 20, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "df" - ] - }, - { - "cell_type": "code", - "execution_count": 24, - "metadata": {}, - "outputs": [ - { - "ename": "AttributeError", - "evalue": "module 'pandas_ta' has no attribute 'ha'", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mAttributeError\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mhelp\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mta\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mha\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", - "\u001b[0;31mAttributeError\u001b[0m: module 'pandas_ta' has no attribute 'ha'" - ] - } - ], - "source": [ - "help(ta.ha)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.7.3" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} From d4285cdecacb1f754f4704589955ad97faa42f61 Mon Sep 17 00:00:00 2001 From: fff-git Date: Fri, 29 May 2020 16:34:30 +0200 Subject: [PATCH 5/5] =?UTF-8?q?Sur=20la=20branche=20nv=5Fit=20Modification?= =?UTF-8?q?s=20qui=20seront=20valid=C3=A9es=20:=20=09modifi=C3=A9=C2=A0:?= =?UTF-8?q?=20=20=20=20=20=20=20=20=20ha.py=20=09modifi=C3=A9=C2=A0:=20=20?= =?UTF-8?q?=20=20=20=20=20=20=20supertrend.py=20=09modifi=C3=A9=C2=A0:=20?= =?UTF-8?q?=20=20=20=20=20=20=20=20../volatility/atr.py?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pandas_ta/trend/ha.py | 16 +++---- pandas_ta/trend/supertrend.py | 79 ++++++++++++++++++----------------- pandas_ta/volatility/atr.py | 1 + 3 files changed, 50 insertions(+), 46 deletions(-) diff --git a/pandas_ta/trend/ha.py b/pandas_ta/trend/ha.py index dc41edb..d72e4ce 100644 --- a/pandas_ta/trend/ha.py +++ b/pandas_ta/trend/ha.py @@ -7,23 +7,23 @@ from pandas_ta.utils import get_offset, verify_series def ha(open, high, low, close, offset=None, **kwargs): # indicator : Heikin Ashi # Validate Arguments - open = verify_series(open) + open_ = verify_series(open) high = verify_series(high) low = verify_series(low) close = verify_series(close) offset = get_offset(offset) - #calculate ha_close - ha_close = 0.25 * (open + high + low + close) + # calculate ha_close + ha_close = 0.25 * (open_ + high + low + close) # Initialization of the ha_open array ha_open = np.zeros(shape=(len(close))) # ha_open of the first element - ha_open[0] = 0.5 * (open[0] + close[0]) + ha_open[0] = 0.5 * (open_[0] + close[0]) - #calculate ha_open. Based on previous ha_open & ha_close - for i in range (1, len(close)): + # calculate ha_open. Based on previous ha_open & ha_close + for i in range(1, len(close)): ha_open[i] = 0.5 * (ha_open[i-1] + ha_close[i-1]) # calculation of ha_high & ha_low @@ -51,7 +51,7 @@ def ha(open, high, low, close, offset=None, **kwargs): ha.__doc__ = \ - """Heikin Ashi (HA) +"""Heikin Ashi (HA) The Heikin-Ashi technique averages price data to create a Japanese candlestick chart that filters out market noise. Heikin-Ashi charts, developed by Munehisa Homma in the 1700s, @@ -84,7 +84,7 @@ HA=Heikin-Ashi With the first HA calculated, it is now possible to continue computing the HA candles per the formulas. ​​ Args: - open (pd.Series): Series of 'open's + open_ (pd.Series): Series of 'open's high (pd.Series): Series of 'high's low (pd.Series): Series of 'low's close (pd.Series): Series of 'close's diff --git a/pandas_ta/trend/supertrend.py b/pandas_ta/trend/supertrend.py index f32b315..bf5ccee 100644 --- a/pandas_ta/trend/supertrend.py +++ b/pandas_ta/trend/supertrend.py @@ -4,57 +4,51 @@ from pandas import DataFrame from ..utils import get_offset, verify_series from ..volatility import atr -def supertrend(high, low, close, period=None, multiplier=None, mamode=None, drift=None, offset=None, **kwargs): + +def supertrend(high, low, close, length=None, multiplier=None, mamode=None, drift=None, offset=None, **kwargs): # indicator : supertrend # Validate Arguments high = verify_series(high) low = verify_series(low) close = verify_series(close) offset = get_offset(offset) - period = int(period) if period and period > 0 else 10 - multiplier = float(multiplier) if multiplier and multiplier > 0 else 1.5 + length = int(length) if length and length > 0 else 10 + multiplier = float(multiplier) if multiplier and multiplier > 0 else 3 min_periods = int(kwargs['min_periods']) if 'min_periods' in kwargs and kwargs[ - 'min_periods'] is not None else period + 'min_periods'] is not None else length - st_updown = np.zeros(shape=(len(close))) + supertrend_dir = np.zeros(shape=(len(close))) strend = np.zeros(shape=(len(close))) # Bands initial calculation midrange = 0.5 * (high + low) - distance = multiplier * atr(high, low, close, period, mamode, drift, offset, min_periods=min_periods) + distance = multiplier * atr(high, low, close, length, mamode, drift, offset, min_periods=min_periods) lowerband = midrange - distance upperband = midrange + distance # final calculation loop for i in range(1, len(close)): - if close[i] > upperband[i-1]: - st_updown[i] = 1 - elif close[i] < lowerband[i-1]: - st_updown[i] = -1 + if close[i] > upperband[i - 1]: + supertrend_dir[i] = 1 + elif close[i] < lowerband[i - 1]: + supertrend_dir[i] = -1 else: - st_updown[i] = st_updown[i-1] - if st_updown[i] > 0 and lowerband[i] < lowerband[i-1]: - lowerband[i] = lowerband[i-1] - if st_updown[i] < 0 and upperband[i] > upperband[i-1]: - upperband[i] = upperband[i-1] - if st_updown[i] < 0 and st_updown[i-1] > 0: - upperband = midrange + distance - if st_updown[i] > 0 and st_updown[i-1] < 0: - lowerband = midrange - distance - if st_updown[i] < 0 : + supertrend_dir[i] = supertrend_dir[i - 1] + if supertrend_dir[i] > 0 and lowerband[i] < lowerband[i - 1]: + lowerband[i] = lowerband[i - 1] + if supertrend_dir[i] < 0 and upperband[i] > upperband[i - 1]: + upperband[i] = upperband[i - 1] + if supertrend_dir[i] < 0: strend[i] = upperband[i] else: strend[i] = lowerband[i] - # Prepare DataFrame to return - data = {f"supertrend_{period}_{multiplier}": strend, f"st_updown_{period}_{multiplier}": st_updown} + data = {f"supertrend_{length}_{multiplier}": strend, f"supertrend_dir_{length}_{multiplier}": supertrend_dir} supertrend_df = DataFrame(data) - supertrend_df.name = f"supertrend_{period}_{multiplier}" + supertrend_df.name = f"supertrend_{length}_{multiplier}" supertrend_df.category = 'trend' - - # Apply offset if needed if offset != 0: supertrend_df = supertrend_df.shift(offset) @@ -66,36 +60,45 @@ def supertrend(high, low, close, period=None, multiplier=None, mamode=None, drif if 'fill_method' in kwargs: supertrend_df.fillna(method=kwargs['fill_method'], inplace=True) - - return supertrend_df + supertrend.__doc__ = \ -"""Supertrend (supertrend) + """Supertrend (supertrend) -Supertrend is a trend indicator. It was created by Olivier Seban +Supertrend is a trend indicator. It is usually used to help identify trend direction, setting stop loss, +identify support and resistance, and / or generate buy & sell signals. +Calculation is in 2 steps : first a multiple of ATR is added and substracted to the middle of the high - low range. +This gives the upperband and lowerband. +The direction of the trend is then calculated : if close > previous upperband or < previous lowerband, +then trend direction is changed, else it is the same as previous value. +If trend direction is unchanged and down, upperband is set to minimum between current and previous value +If trend direction is unchanged and up, lowerband is set to maximum between current and previous value. -Sources: -https://www.abcbourse.com/apprendre/11_le_supertrend.html -(in french, but many other can be found using a search engine) +The final band is then choosen according to the direction of the trend : upperband if trend is downward, +lowerband if trend is upward. +Returned values are : float for final band level, int (1 : upward trend, -1 : downward trend) for trend direction Calculation: Default Inputs: - period = 10 - multiplier = 1.5 - + length = 10 + multiplier = 3 Args: high (pd.Series): Series of 'high's low (pd.Series): Series of 'low's close (pd.Series): Series of 'close's - + length (int) : length for ATR calculation. Default : 10 + multiplier : coefficient for upper and lower band distance to midrange. Default : 3 + mamode: parameter used for ATR calculation. See ATR documentation. Default : None (= ema) + drift : parameter used for ATR calculation. See ATR documentation. Default : None (= 1) offset (int): How many periods to offset the result. Default: 0 Kwargs: fillna (value, optional): pd.DataFrame.fillna(value) fill_method (value, optional): Type of fill method + min_periods (int, optional) : parameter used for ATR calculation. See ATR documentation. Default : length Returns: - pd.DataFrame: supertrend, st_updown, slowk, slowd columns. -""" \ No newline at end of file + pd.DataFrame: supertrend (float), supertrend_dir (int) columns. +""" diff --git a/pandas_ta/volatility/atr.py b/pandas_ta/volatility/atr.py index c6474da..bd2ab80 100644 --- a/pandas_ta/volatility/atr.py +++ b/pandas_ta/volatility/atr.py @@ -75,6 +75,7 @@ Args: Kwargs: fillna (value, optional): pd.DataFrame.fillna(value) fill_method (value, optional): Type of fill method + min_periods (int, optional) : Minimum number of periods before calculating ATR. Default : length Returns: pd.Series: New feature generated.