From 11e7eda03f9ab68abf6173ce16c67d9b8785a1d9 Mon Sep 17 00:00:00 2001 From: fff-git Date: Thu, 28 May 2020 17:50:26 +0200 Subject: [PATCH] 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