# Python如何實現SuperTrend V.1超級趨勢線系統
## 目錄
1. [什么是SuperTrend指標](#什么是supertrend指標)
2. [數學原理與計算公式](#數學原理與計算公式)
3. [Python實現步驟詳解](#python實現步驟詳解)
4. [可視化與策略回測](#可視化與策略回測)
5. [參數優化與注意事項](#參數優化與注意事項)
6. [完整代碼實現](#完整代碼實現)
7. [實際應用案例](#實際應用案例)
8. [總結與延伸](#總結與延伸)
---
## 什么是SuperTrend指標
SuperTrend(超級趨勢線)是由Olivier Seban開發的一種趨勢跟蹤指標,它結合了**平均真實波幅(ATR)**和**價格中位數**的概念,通過動態調整上下軌來識別市場趨勢方向。
### 核心特點
- 趨勢可視化:直觀顯示當前趨勢方向(綠色為上漲,紅色為下跌)
- 自適應波動:通過ATR自動調整通道寬度
- 信號明確:突破SuperTrend線即產生交易信號
- 適用于多種時間框架:從分鐘線到周線均可使用
---
## 數學原理與計算公式
### 關鍵組成部分
1. **平均真實波幅(ATR)**
計算周期內價格波動幅度的平均值:
TR = max(high - low, abs(high - prev_close), abs(low - prev_close)) ATR = SMA(TR, period)
2. **基礎線計算**
中線 = (最高價 + 最低價) / 2 上軌 = 中線 + multiplier × ATR 下軌 = 中線 - multiplier × ATR
3. **動態調整規則**
- 當收盤價 > 前上軌 → 上軌 = max(當前上軌, 前上軌)
- 當收盤價 < 前下軌 → 下軌 = min(當前下軌, 前下軌)
---
## Python實現步驟詳解
### 1. 準備環境
```python
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import yfinance as yf # 用于獲取行情數據
plt.style.use('seaborn')
def calculate_atr(df, period=14):
high_low = df['High'] - df['Low']
high_close = np.abs(df['High'] - df['Close'].shift())
low_close = np.abs(df['Low'] - df['Close'].shift())
tr = pd.concat([high_low, high_close, low_close], axis=1).max(axis=1)
atr = tr.rolling(period).mean()
return atr
def supertrend(df, period=10, multiplier=3):
df['ATR'] = calculate_atr(df, period)
df['中線'] = (df['High'] + df['Low']) / 2
df['上軌'] = df['中線'] + multiplier * df['ATR']
df['下軌'] = df['中線'] - multiplier * df['ATR']
# 初始化SuperTrend列
df['SuperTrend'] = np.nan
df['方向'] = np.nan # 1表示上漲,-1表示下跌
for i in range(1, len(df)):
# 上漲邏輯
if df['Close'].iloc[i] > df['上軌'].iloc[i-1]:
df.loc[df.index[i], 'SuperTrend'] = df['下軌'].iloc[i]
df.loc[df.index[i], '方向'] = 1
# 下跌邏輯
elif df['Close'].iloc[i] < df['下軌'].iloc[i-1]:
df.loc[df.index[i], 'SuperTrend'] = df['上軌'].iloc[i]
df.loc[df.index[i], '方向'] = -1
# 延續前一日趨勢
else:
df.loc[df.index[i], 'SuperTrend'] = df['SuperTrend'].iloc[i-1]
df.loc[df.index[i], '方向'] = df['方向'].iloc[i-1]
# 動態調整上下軌
if df['方向'].iloc[i] == 1:
df.loc[df.index[i], '上軌'] = min(df['上軌'].iloc[i], df['上軌'].iloc[i-1])
else:
df.loc[df.index[i], '下軌'] = max(df['下軌'].iloc[i], df['下軌'].iloc[i-1])
return df
def plot_supertrend(df, start_date=None, end_date=None):
plt.figure(figsize=(16,8))
if start_date and end_date:
plot_df = df.loc[start_date:end_date]
else:
plot_df = df[-500:] # 默認顯示最近500個周期
plt.plot(plot_df['Close'], label='收盤價', alpha=0.5)
# 繪制SuperTrend線
plt.plot(plot_df['SuperTrend'],
label='SuperTrend',
color='green',
linewidth=1.5)
# 標記趨勢轉折點
turning_points = plot_df[plot_df['方向'] != plot_df['方向'].shift(1)]
for date, row in turning_points.iterrows():
color = 'green' if row['方向'] == 1 else 'red'
plt.scatter(date, row['SuperTrend'], color=color, s=100)
plt.title('SuperTrend指標')
plt.legend()
plt.show()
def backtest(df):
df['信號'] = 0
df.loc[df['方向'] == 1, '信號'] = 1 # 做多信號
df.loc[df['方向'] == -1, '信號'] = -1 # 做空信號
# 計算收益率
df['日收益率'] = df['Close'].pct_change()
df['策略收益率'] = df['信號'].shift(1) * df['日收益率']
# 累計收益率
df['累計策略收益'] = (1 + df['策略收益率']).cumprod()
df['累計市場收益'] = (1 + df['日收益率']).cumprod()
return df
參數 | 典型值范圍 | 敏感性分析 |
---|---|---|
ATR周期 | 7-20 | 周期越小對波動越敏感 |
乘數 | 1.5-4 | 乘數越大信號越保守 |
def parameter_optimization(df): results = [] for period, mult in product(range(7,21), [x*0.5 for x in range(3,9)]): temp_df = supertrend(df.copy(), period, mult) temp_df = backtest(temp_df) final_return = temp_df[‘累計策略收益’].iloc[-1] results.append((period, mult, final_return))
return pd.DataFrame(results, columns=['Period', 'Multiplier', 'Return'])
2. **Walk-Forward分析**確保參數魯棒性
### 注意事項
- 在震蕩市中可能出現頻繁假信號
- 需結合成交量或其他指標過濾信號
- 不同品種需要單獨參數優化
---
## 完整代碼實現
```python
# 完整實現代碼(整合所有上述函數)
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import yfinance as yf
class SuperTrend:
def __init__(self, data, period=10, multiplier=3):
self.df = data.copy()
self.period = period
self.multiplier = multiplier
def calculate(self):
self._calculate_atr()
self._calculate_supertrend()
return self.df
def _calculate_atr(self):
high_low = self.df['High'] - self.df['Low']
high_close = np.abs(self.df['High'] - self.df['Close'].shift())
low_close = np.abs(self.df['Low'] - self.df['Close'].shift())
tr = pd.concat([high_low, high_close, low_close], axis=1).max(axis=1)
self.df['ATR'] = tr.rolling(self.period).mean()
def _calculate_supertrend(self):
self.df['中線'] = (self.df['High'] + self.df['Low']) / 2
self.df['上軌'] = self.df['中線'] + self.multiplier * self.df['ATR']
self.df['下軌'] = self.df['中線'] - self.multiplier * self.df['ATR']
self.df['SuperTrend'] = np.nan
self.df['方向'] = np.nan
for i in range(1, len(self.df)):
if self.df['Close'].iloc[i] > self.df['上軌'].iloc[i-1]:
self.df.loc[self.df.index[i], 'SuperTrend'] = self.df['下軌'].iloc[i]
self.df.loc[self.df.index[i], '方向'] = 1
elif self.df['Close'].iloc[i] < self.df['下軌'].iloc[i-1]:
self.df.loc[self.df.index[i], 'SuperTrend'] = self.df['上軌'].iloc[i]
self.df.loc[self.df.index[i], '方向'] = -1
else:
self.df.loc[self.df.index[i], 'SuperTrend'] = self.df['SuperTrend'].iloc[i-1]
self.df.loc[self.df.index[i], '方向'] = self.df['方向'].iloc[i-1]
if self.df['方向'].iloc[i] == 1:
self.df.loc[self.df.index[i], '上軌'] = min(self.df['上軌'].iloc[i], self.df['上軌'].iloc[i-1])
else:
self.df.loc[self.df.index[i], '下軌'] = max(self.df['下軌'].iloc[i], self.df['下軌'].iloc[i-1])
# 使用示例
if __name__ == "__main__":
data = yf.download('AAPL', start='2020-01-01', end='2023-12-31')
st = SuperTrend(data, period=10, multiplier=3)
result = st.calculate()
plot_supertrend(result)
參數:ATR周期=14,乘數=2.5
SuperTrend V.2改進點:
多時間框架分析:
# 周線趨勢作為過濾器
weekly_df = df.resample('W').agg({'Open':'first','High':'max','Low':'min','Close':'last'})
weekly_st = SuperTrend(weekly_df).calculate()
量化交易整合:
提示:實際交易前建議在歷史數據上進行充分測試,SuperTrend作為趨勢指標在單邊市中表現優異,但在震蕩市中需配合其他技術指標使用。 “`
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。