Skip to content

Commit 6ff8466

Browse files
committed
Add supertrend
1 parent cce0a0a commit 6ff8466

File tree

7 files changed

+68
-67
lines changed

7 files changed

+68
-67
lines changed

README.md

Lines changed: 45 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@ pip install pyindicators
2929
* [Weighted Moving Average (WMA)](#weighted-moving-average-wma)
3030
* [Simple Moving Average (SMA)](#simple-moving-average-sma)
3131
* [Exponential Moving Average (EMA)](#exponential-moving-average-ema)
32+
* [SuperTrend](#supertrend)
3233
* [SuperTrend Clustering](#supertrend-clustering)
33-
* [SuperTrend Basic](#supertrend-basic)
3434
* [Momentum and Oscillators](#momentum-and-oscillators)
3535
* [Moving Average Convergence Divergence (MACD)](#moving-average-convergence-divergence-macd)
3636
* [Relative Strength Index (RSI)](#relative-strength-index-rsi)
@@ -910,6 +910,50 @@ pd_df.tail(10)
910910

911911
Indicators that combine trend detection with adaptive trailing stops.
912912

913+
#### SuperTrend
914+
915+
The SuperTrend indicator uses a fixed ATR multiplier factor to create a trend-following trailing stop. When the price is above the SuperTrend line the trend is bullish; when below, bearish. Trend changes generate buy/sell signals.
916+
917+
```python
918+
def supertrend(
919+
data: Union[PdDataFrame, PlDataFrame],
920+
atr_length: int = 10,
921+
factor: float = 3.0
922+
) -> Union[PdDataFrame, PlDataFrame]:
923+
```
924+
925+
Returns the following columns:
926+
- `supertrend`: The SuperTrend trailing stop value
927+
- `supertrend_trend`: Current trend (1=bullish, 0=bearish)
928+
- `supertrend_upper`: Upper band
929+
- `supertrend_lower`: Lower band
930+
- `supertrend_signal`: 1=buy signal, -1=sell signal, 0=no signal
931+
932+
Example
933+
934+
```python
935+
from investing_algorithm_framework import download
936+
937+
from pyindicators import supertrend
938+
939+
pd_df = download(
940+
symbol="btc/eur",
941+
market="binance",
942+
time_frame="1d",
943+
start_date="2023-12-01",
944+
end_date="2023-12-25",
945+
pandas=True,
946+
save=True,
947+
storage_path="./data"
948+
)
949+
950+
# Calculate SuperTrend
951+
pd_df = supertrend(pd_df, atr_length=10, factor=3.0)
952+
pd_df.tail(10)
953+
```
954+
955+
![SUPERTREND](https://github.com/coding-kitties/PyIndicators/blob/main/static/images/indicators/supertrend.png)
956+
913957
#### SuperTrend Clustering
914958

915959
The SuperTrend Clustering indicator uses K-means clustering to optimize the ATR multiplier factor for the SuperTrend calculation. It computes multiple SuperTrend variations with different factors, evaluates their performance, and clusters them into "best", "average", and "worst" groups. The best-performing factor is then used to generate an adaptive trailing stop with buy/sell signals.
@@ -976,48 +1020,6 @@ pd_df.tail(10)
9761020

9771021
![SUPERTREND_CLUSTERING](https://github.com/coding-kitties/PyIndicators/blob/main/static/images/indicators/supertrend_clustering.png)
9781022

979-
#### SuperTrend Basic
980-
981-
The basic SuperTrend indicator uses a fixed ATR multiplier factor to create a trend-following trailing stop. When the price is above the SuperTrend line the trend is bullish; when below, bearish. Trend changes generate buy/sell signals.
982-
983-
```python
984-
def supertrend_basic(
985-
data: Union[PdDataFrame, PlDataFrame],
986-
atr_length: int = 10,
987-
factor: float = 3.0
988-
) -> Union[PdDataFrame, PlDataFrame]:
989-
```
990-
991-
Returns the following columns:
992-
- `supertrend`: The SuperTrend trailing stop value
993-
- `supertrend_trend`: Current trend (1=bullish, 0=bearish)
994-
- `supertrend_upper`: Upper band
995-
- `supertrend_lower`: Lower band
996-
- `supertrend_signal`: 1=buy signal, -1=sell signal, 0=no signal
997-
998-
Example
999-
1000-
```python
1001-
from investing_algorithm_framework import download
1002-
1003-
from pyindicators import supertrend_basic
1004-
1005-
pd_df = download(
1006-
symbol="btc/eur",
1007-
market="binance",
1008-
time_frame="1d",
1009-
start_date="2023-12-01",
1010-
end_date="2023-12-25",
1011-
pandas=True,
1012-
save=True,
1013-
storage_path="./data"
1014-
)
1015-
1016-
# Calculate basic SuperTrend
1017-
pd_df = supertrend_basic(pd_df, atr_length=10, factor=3.0)
1018-
pd_df.tail(10)
1019-
```
1020-
10211023
### Support and Resistance
10221024

10231025
Indicators that help identify potential support and resistance levels in the market.

pyindicators/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
market_structure_choch_bos, choch_bos_signal, get_choch_bos_stats,
2020
momentum_confluence, momentum_confluence_signal,
2121
get_momentum_confluence_stats,
22-
supertrend_clustering, supertrend_basic, supertrend_signal,
22+
supertrend_clustering, supertrend, supertrend_signal,
2323
get_supertrend_stats,
2424
nadaraya_watson_envelope
2525
)
@@ -106,7 +106,7 @@ def get_version():
106106
'momentum_confluence_signal',
107107
'get_momentum_confluence_stats',
108108
'supertrend_clustering',
109-
'supertrend_basic',
109+
'supertrend',
110110
'supertrend_signal',
111111
'get_supertrend_stats',
112112
'nadaraya_watson_envelope'

pyindicators/indicators/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141
get_momentum_confluence_stats
4242
)
4343
from .supertrend import (
44-
supertrend_clustering, supertrend_basic, supertrend_signal,
44+
supertrend_clustering, supertrend, supertrend_signal,
4545
get_supertrend_stats
4646
)
4747
from .nadaraya_watson_envelope import nadaraya_watson_envelope
@@ -111,7 +111,7 @@
111111
'momentum_confluence_signal',
112112
'get_momentum_confluence_stats',
113113
'supertrend_clustering',
114-
'supertrend_basic',
114+
'supertrend',
115115
'supertrend_signal',
116116
'get_supertrend_stats',
117117
'nadaraya_watson_envelope'

pyindicators/indicators/supertrend.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -380,7 +380,7 @@ def supertrend_clustering(
380380
return df
381381

382382

383-
def supertrend_basic(
383+
def supertrend(
384384
data: Union[PdDataFrame, PlDataFrame],
385385
atr_length: int = 10,
386386
factor: float = 3.0
161 KB
Loading
163 KB
Loading

tests/indicators/test_supertrend.py

Lines changed: 18 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import pandas as pd
33
import numpy as np
44

5-
from pyindicators import supertrend_ai, supertrend_basic, get_supertrend_stats
5+
from pyindicators import supertrend_ai, supertrend, get_supertrend_stats
66

77

88
class TestSuperTrend(unittest.TestCase):
@@ -31,14 +31,14 @@ def setUp(self):
3131
'Close': close
3232
})
3333

34-
def test_supertrend_basic_returns_dataframe(self):
35-
"""Test that supertrend_basic returns a DataFrame."""
36-
result = supertrend_basic(self.df.copy())
34+
def test_supertrend_returns_dataframe(self):
35+
"""Test that supertrend returns a DataFrame."""
36+
result = supertrend(self.df.copy())
3737
self.assertIsInstance(result, pd.DataFrame)
3838

39-
def test_supertrend_basic_columns(self):
40-
"""Test that supertrend_basic adds expected columns."""
41-
result = supertrend_basic(self.df.copy())
39+
def test_supertrend_columns(self):
40+
"""Test that supertrend adds expected columns."""
41+
result = supertrend(self.df.copy())
4242

4343
expected_columns = [
4444
'supertrend', 'supertrend_trend',
@@ -47,23 +47,23 @@ def test_supertrend_basic_columns(self):
4747
for col in expected_columns:
4848
self.assertIn(col, result.columns)
4949

50-
def test_supertrend_basic_trend_values(self):
50+
def test_supertrend_trend_values(self):
5151
"""Test that trend values are 0 or 1."""
52-
result = supertrend_basic(self.df.copy())
52+
result = supertrend(self.df.copy())
5353
unique_trends = result['supertrend_trend'].unique()
5454
for trend in unique_trends:
5555
self.assertIn(trend, [0, 1])
5656

57-
def test_supertrend_basic_signal_values(self):
57+
def test_supertrend_signal_values(self):
5858
"""Test that signal values are -1, 0, or 1."""
59-
result = supertrend_basic(self.df.copy())
59+
result = supertrend(self.df.copy())
6060
unique_signals = result['supertrend_signal'].unique()
6161
for signal in unique_signals:
6262
self.assertIn(signal, [-1, 0, 1])
6363

64-
def test_supertrend_basic_custom_parameters(self):
65-
"""Test supertrend_basic with custom parameters."""
66-
result = supertrend_basic(self.df.copy(), atr_length=14, factor=2.0)
64+
def test_supertrend_custom_parameters(self):
65+
"""Test supertrend with custom parameters."""
66+
result = supertrend(self.df.copy(), atr_length=14, factor=2.0)
6767
self.assertIn('supertrend', result.columns)
6868

6969
def test_supertrend_ai_returns_dataframe(self):
@@ -115,7 +115,7 @@ def test_supertrend_ai_invalid_factor_range(self):
115115

116116
def test_get_supertrend_stats(self):
117117
"""Test statistics function."""
118-
result = supertrend_basic(self.df.copy())
118+
result = supertrend(self.df.copy())
119119
stats = get_supertrend_stats(result)
120120

121121
self.assertIn('buy_signals', stats)
@@ -133,7 +133,7 @@ def test_get_supertrend_stats_ai(self):
133133

134134
def test_supertrend_upper_lower_relationship(self):
135135
"""Test that upper band is always above lower band."""
136-
result = supertrend_basic(self.df.copy())
136+
result = supertrend(self.df.copy())
137137

138138
# After initialization period
139139
for i in range(10, len(result)):
@@ -145,12 +145,12 @@ def test_supertrend_upper_lower_relationship(self):
145145
def test_supertrend_with_minimal_data(self):
146146
"""Test SuperTrend with minimal data."""
147147
minimal_df = self.df.head(30).copy()
148-
result = supertrend_basic(minimal_df)
148+
result = supertrend(minimal_df)
149149
self.assertEqual(len(result), 30)
150150

151151
def test_supertrend_signal_on_trend_change(self):
152152
"""Test that signals occur when trend changes."""
153-
result = supertrend_basic(self.df.copy())
153+
result = supertrend(self.df.copy())
154154

155155
# Find where trend changes
156156
trend_changes = result['supertrend_trend'].diff().abs()
@@ -166,4 +166,3 @@ def test_supertrend_signal_on_trend_change(self):
166166

167167
if __name__ == '__main__':
168168
unittest.main()
169-

0 commit comments

Comments
 (0)