66 lines
2.1 KiB
Python
66 lines
2.1 KiB
Python
import pandas as pd
|
|
import numpy as np
|
|
from backtesting import Backtest, Strategy
|
|
from backtesting.lib import crossover
|
|
from ta.momentum import rsi
|
|
from scipy.signal import savgol_filter
|
|
|
|
# Daten vorbereiten (df muss OHLCV-Daten enthalten: 'open', 'high', 'low', 'close', 'volume')
|
|
df = pd.read_csv('xauusd_5min.csv', parse_dates=['time'])
|
|
df.set_index('time', inplace=True)
|
|
|
|
# Indikatoren berechnen
|
|
def calculate_indicators(df):
|
|
df['ema21'] = df['close'].ewm(span=21).mean()
|
|
df['ema50'] = df['close'].ewm(span=50).mean()
|
|
df['rsi9'] = rsi(df['close'], length=9)
|
|
df['rsi14'] = rsi(df['close'], length=14)
|
|
df['trend'] = savgol_filter(df['close'], window_length=25, polyorder=3)
|
|
return df
|
|
|
|
df = calculate_indicators(df)
|
|
|
|
# Strategie definieren
|
|
class Gold5MinStrategy(Strategy):
|
|
def init(self):
|
|
# Indikatoren für den Plot
|
|
self.add_indicator('EMA21', self.data.ema21)
|
|
self.add_indicator('EMA50', self.data.ema50)
|
|
|
|
def next(self):
|
|
current_index = len(self.data.close) - 1
|
|
|
|
# Long-Signal (Kauf)
|
|
if (
|
|
crossover(self.data.ema21, self.data.ema50)
|
|
and self.data.rsi14[-1] < 65
|
|
and self.data.rsi9[-1] > 50
|
|
and self.data.trend[-1] > self.data.trend[-2]
|
|
and not self.position.is_long
|
|
):
|
|
self.buy(sl=self.data.low[-1] * 0.995, tp=self.data.close[-1] * 1.01) # 0.5% SL, 1% TP
|
|
|
|
# Short-Signal (Verkauf)
|
|
elif (
|
|
crossover(self.data.ema50, self.data.ema21)
|
|
and self.data.rsi14[-1] > 35
|
|
and self.data.rsi9[-1] < 50
|
|
and self.data.trend[-1] < self.data.trend[-2]
|
|
and not self.position.is_short
|
|
):
|
|
self.sell(sl=self.data.high[-1] * 1.005, tp=self.data.close[-1] * 0.99) # 0.5% SL, 1% TP
|
|
|
|
# Backtest ausführen
|
|
bt = Backtest(df, Gold5MinStrategy, commission=0.0002, margin=0.05) # 0.02% Kommission, 5% Margin
|
|
stats = bt.run()
|
|
print(stats)
|
|
|
|
# Optimierung (optional)
|
|
# stats_opt = bt.optimize(
|
|
# rsi_long_upper=[60, 65, 70],
|
|
# rsi_short_lower=[30, 35, 40],
|
|
# maximize='Return [%]'
|
|
# )
|
|
|
|
# Ergebnisse plotten
|
|
bt.plot() |