Strategie Elder Impulse
Strategie basierend auf Elders Impulssystem
Tests zeigen eine durchschnittliche jährliche Rendite von etwa 106%. Sie funktioniert am besten am Aktienmarkt.
Elder Impulse kombiniert die EMA-Richtung mit der Farbe des MACD-Histogramms. Grüne Balken oberhalb der EMA signalisieren Long-Positionen, rote Balken darunter Short-Positionen, und neutrale Balken signalisieren Ausstiege.
Durch die Kombination von Trendrichtung und Momentum hält dieser Ansatz Trader auf der richtigen Seite starker Bewegungen. Ausstiege sind unkompliziert und basieren auf dem Farbwechsel des Histogramms oder der Umkehr der EMA-Steigung.
Details
- Einstiegskriterien: Signale basierend auf MACD.
- Long/Short: Beide Richtungen.
- Ausstiegskriterien: Gegensätzliches Signal oder Stop.
- Stops: Ja.
- Standardwerte:
EmaPeriod= 13MacdFastPeriod= 12MacdSlowPeriod= 26MacdSignalPeriod= 9StopLossPercent= 2mCandleType= TimeSpan.FromMinutes(5)
- Filter:
- Kategorie: Trend
- Richtung: Beide
- Indikatoren: MACD
- Stops: Ja
- Komplexität: Grundlegend
- Zeitrahmen: Intraday (5m)
- Saisonalität: Nein
- Neuronale Netze: Nein
- Divergenz: Nein
- Risikolevel: Mittel
using System;
using System.Collections.Generic;
using Ecng.Common;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
/// <summary>
/// Strategy based on Elder's Impulse System.
/// Uses EMA direction and MACD histogram to determine impulse.
/// Green (bullish): EMA rising + MACD histogram rising -> buy
/// Red (bearish): EMA falling + MACD histogram falling -> sell
/// </summary>
public class ElderImpulseStrategy : Strategy
{
private readonly StrategyParam<int> _emaPeriod;
private readonly StrategyParam<DataType> _candleType;
private decimal _prevEma;
private decimal _prevHistogram;
private bool _hasPrevValues;
private int _prevImpulse; // 1=green, -1=red, 0=neutral
private int _cooldown;
/// <summary>
/// EMA period.
/// </summary>
public int EmaPeriod
{
get => _emaPeriod.Value;
set => _emaPeriod.Value = value;
}
/// <summary>
/// Candle type.
/// </summary>
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
/// <summary>
/// Initializes a new instance of the <see cref="ElderImpulseStrategy"/>.
/// </summary>
public ElderImpulseStrategy()
{
_emaPeriod = Param(nameof(EmaPeriod), 13)
.SetDisplay("EMA Period", "Period for EMA calculation", "Indicators")
.SetOptimize(8, 21, 3);
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(5).TimeFrame())
.SetDisplay("Candle Type", "Type of candles to use", "General");
}
/// <inheritdoc />
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
{
return [(Security, CandleType)];
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_prevEma = default;
_prevHistogram = default;
_hasPrevValues = default;
_prevImpulse = default;
_cooldown = default;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var ema = new ExponentialMovingAverage { Length = EmaPeriod };
var macdSignal = new MovingAverageConvergenceDivergenceSignal();
var subscription = SubscribeCandles(CandleType);
subscription
.BindEx(ema, macdSignal, ProcessCandle)
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, ema);
DrawIndicator(area, macdSignal);
DrawOwnTrades(area);
}
}
private void ProcessCandle(ICandleMessage candle, IIndicatorValue emaValue, IIndicatorValue macdValue)
{
if (candle.State != CandleStates.Finished)
return;
if (!IsFormedAndOnlineAndAllowTrading())
return;
if (emaValue.IsEmpty)
return;
var emaDec = emaValue.GetValue<decimal>();
if (emaDec == 0)
return;
var macdTyped = (IMovingAverageConvergenceDivergenceSignalValue)macdValue;
if (macdTyped.Macd is not decimal macd || macdTyped.Signal is not decimal signal)
return;
var histogram = macd - signal;
if (!_hasPrevValues)
{
_hasPrevValues = true;
_prevEma = emaDec;
_prevHistogram = histogram;
return;
}
var emaRising = emaDec > _prevEma;
var histogramRising = histogram > _prevHistogram;
// Determine current impulse
int impulse;
if (emaRising && histogramRising)
impulse = 1; // Green bar
else if (!emaRising && !histogramRising && emaDec != _prevEma)
impulse = -1; // Red bar
else
impulse = 0; // Neutral (blue bar)
if (_cooldown > 0)
{
_cooldown--;
_prevEma = emaDec;
_prevHistogram = histogram;
_prevImpulse = impulse;
return;
}
// Trade only on impulse change
if (impulse == 1 && _prevImpulse != 1 && Position <= 0)
{
var volume = Volume + Math.Abs(Position);
BuyMarket(volume);
_cooldown = 65;
}
else if (impulse == -1 && _prevImpulse != -1 && Position >= 0)
{
var volume = Volume + Math.Abs(Position);
SellMarket(volume);
_cooldown = 65;
}
_prevEma = emaDec;
_prevHistogram = histogram;
_prevImpulse = impulse;
}
}
import clr
clr.AddReference("StockSharp.Messages")
clr.AddReference("StockSharp.Algo")
clr.AddReference("StockSharp.Algo.Indicators")
clr.AddReference("StockSharp.Algo.Strategies")
from System import TimeSpan, Math
from StockSharp.Messages import DataType, CandleStates
from StockSharp.Algo.Indicators import ExponentialMovingAverage, MovingAverageConvergenceDivergenceSignal
from StockSharp.Algo.Strategies import Strategy
class elder_impulse_strategy(Strategy):
"""
Strategy based on Elder's Impulse System.
Uses EMA direction and MACD histogram to determine impulse.
Green (bullish): EMA rising + MACD histogram rising -> buy
Red (bearish): EMA falling + MACD histogram falling -> sell
"""
def __init__(self):
super(elder_impulse_strategy, self).__init__()
self._ema_period = self.Param("EmaPeriod", 13) \
.SetDisplay("EMA Period", "Period for EMA calculation", "Indicators")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(5))) \
.SetDisplay("Candle Type", "Type of candles to use", "General")
self._prev_ema = 0.0
self._prev_histogram = 0.0
self._has_prev_values = False
self._prev_impulse = 0
self._cooldown = 0
@property
def candle_type(self):
return self._candle_type.Value
def OnReseted(self):
super(elder_impulse_strategy, self).OnReseted()
self._prev_ema = 0.0
self._prev_histogram = 0.0
self._has_prev_values = False
self._prev_impulse = 0
self._cooldown = 0
def OnStarted2(self, time):
super(elder_impulse_strategy, self).OnStarted2(time)
ema = ExponentialMovingAverage()
ema.Length = self._ema_period.Value
macd_signal = MovingAverageConvergenceDivergenceSignal()
subscription = self.SubscribeCandles(self.candle_type)
subscription.BindEx(ema, macd_signal, self._process_candle).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawIndicator(area, ema)
self.DrawIndicator(area, macd_signal)
self.DrawOwnTrades(area)
def _process_candle(self, candle, ema_value, macd_value):
if candle.State != CandleStates.Finished:
return
if ema_value.IsEmpty:
return
ema_dec = float(ema_value)
if ema_dec == 0.0:
return
macd_line = macd_value.Macd
signal_line = macd_value.Signal
if macd_line is None or signal_line is None:
return
macd_f = float(macd_line)
signal_f = float(signal_line)
histogram = macd_f - signal_f
if not self._has_prev_values:
self._has_prev_values = True
self._prev_ema = ema_dec
self._prev_histogram = histogram
return
ema_rising = ema_dec > self._prev_ema
histogram_rising = histogram > self._prev_histogram
if ema_rising and histogram_rising:
impulse = 1
elif not ema_rising and not histogram_rising and ema_dec != self._prev_ema:
impulse = -1
else:
impulse = 0
if self._cooldown > 0:
self._cooldown -= 1
self._prev_ema = ema_dec
self._prev_histogram = histogram
self._prev_impulse = impulse
return
if impulse == 1 and self._prev_impulse != 1 and self.Position <= 0:
self.BuyMarket(self.Volume + abs(self.Position))
self._cooldown = 65
elif impulse == -1 and self._prev_impulse != -1 and self.Position >= 0:
self.SellMarket(self.Volume + abs(self.Position))
self._cooldown = 65
self._prev_ema = ema_dec
self._prev_histogram = histogram
self._prev_impulse = impulse
def CreateClone(self):
return elder_impulse_strategy()