Vela Superada-Strategie
Die Vela Superada-Strategie handelt ein Zwei-Kerzen-Umkehrmuster. Ein bullisches Setup entsteht, wenn einer bearischen Kerze unmittelbar eine bullische folgt, die über dem vorherigen Eröffnungskurs schließt. Trades werden mit einem kurzfristigen EMA, RSI und MACD-Trend gefiltert, um Gegentrend-Signale zu vermeiden. Sowohl Long- als auch Short- Seiten können aktiviert werden.
Die Strategie setzt prozentuale Take-Profit- und Stop-Loss-Niveaus ein und zieht einen Trailing Stop dynamisch nach, sobald sich der Kurs günstig entwickelt. Dies ermöglicht es, ausgedehnte Bewegungen zu erfassen und gleichzeitig vor Umkehrungen zu schützen.
Details
- Einstiegskriterien:
- Long: Vorherige Kerze bearisch, aktuelle bullisch, Schlusskurs und vorheriger Schlusskurs über EMA, RSI < 65, MACD steigend.
- Short: Vorherige Kerze bullisch, aktuelle bearisch, Schlusskurs und vorheriger Schlusskurs unter EMA, RSI > 35, MACD fallend.
- Long/Short: Konfigurierbar (Long standardmäßig).
- Ausstiegskriterien:
- Trailing Stop oder entgegengesetztes Signal.
- Stops: Prozentualer Stop Loss und Take Profit.
- Standardwerte:
EmaLength= 10RsiLength= 14ShowLong= TrueShowShort= FalseTpPercent= 1.2SlPercent= 1.8
- Filter:
- Kategorie: Muster + Indikatoren
- Richtung: Beide
- Indikatoren: EMA, RSI, MACD
- Stops: Ja
- Komplexität: Mittel
- Zeitrahmen: Beliebig
- Saisonalität: Nein
- Neuronale Netze: Nein
- Divergenz: Ja
- Risikolevel: Mittel
namespace StockSharp.Samples.Strategies;
using System;
using System.Collections.Generic;
using Ecng.Common;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
/// <summary>
/// Vela Superada Strategy.
/// A bearish candle followed by a bullish one that closes above the prior open, with both closes above the EMA, RSI below 65
/// and a rising MACD line, is a long signal. The mirrored pattern below the EMA with RSI above 35 and a falling MACD line is
/// a short signal. ShowLong and ShowShort enable each side; an opposite signal closes or reverses the position. A trailing
/// SlPercent stop and a TpPercent take profit protect the trade.
/// </summary>
public class VelaSuperadaStrategy : Strategy
{
private readonly StrategyParam<int> _emaLength;
private readonly StrategyParam<int> _rsiLength;
private readonly StrategyParam<bool> _showLong;
private readonly StrategyParam<bool> _showShort;
private readonly StrategyParam<decimal> _tpPercent;
private readonly StrategyParam<decimal> _slPercent;
private readonly StrategyParam<DataType> _candleType;
private ICandleMessage _prevCandle;
private decimal? _prevMacd;
/// <summary>
/// EMA period.
/// </summary>
public int EmaLength
{
get => _emaLength.Value;
set => _emaLength.Value = value;
}
/// <summary>
/// RSI period.
/// </summary>
public int RsiLength
{
get => _rsiLength.Value;
set => _rsiLength.Value = value;
}
/// <summary>
/// Allow long trades.
/// </summary>
public bool ShowLong
{
get => _showLong.Value;
set => _showLong.Value = value;
}
/// <summary>
/// Allow short trades.
/// </summary>
public bool ShowShort
{
get => _showShort.Value;
set => _showShort.Value = value;
}
/// <summary>
/// Take profit percentage from entry price.
/// </summary>
public decimal TpPercent
{
get => _tpPercent.Value;
set => _tpPercent.Value = value;
}
/// <summary>
/// Trailing stop loss percentage.
/// </summary>
public decimal SlPercent
{
get => _slPercent.Value;
set => _slPercent.Value = value;
}
/// <summary>
/// Candle type.
/// </summary>
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
/// <summary>
/// Constructor.
/// </summary>
public VelaSuperadaStrategy()
{
_emaLength = Param(nameof(EmaLength), 10)
.SetGreaterThanZero()
.SetDisplay("EMA Length", "EMA period", "Indicators");
_rsiLength = Param(nameof(RsiLength), 14)
.SetGreaterThanZero()
.SetDisplay("RSI Length", "RSI period", "Indicators");
_showLong = Param(nameof(ShowLong), true)
.SetDisplay("Long Trades", "Allow long trades", "Trading");
_showShort = Param(nameof(ShowShort), false)
.SetDisplay("Short Trades", "Allow short trades", "Trading");
_tpPercent = Param(nameof(TpPercent), 1.2m)
.SetNotNegative()
.SetDisplay("TP %", "Take profit percentage from entry price", "Risk");
_slPercent = Param(nameof(SlPercent), 1.8m)
.SetNotNegative()
.SetDisplay("SL %", "Trailing stop loss percentage", "Risk");
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(30).TimeFrame())
.SetDisplay("Candle Type", "Type of candles to use", "General");
}
/// <inheritdoc />
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
=> [(Security, CandleType)];
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_prevCandle = null;
_prevMacd = null;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_prevCandle = null;
_prevMacd = null;
var ema = new ExponentialMovingAverage { Length = EmaLength };
var rsi = new RelativeStrengthIndex { Length = RsiLength };
var macd = new MovingAverageConvergenceDivergence();
var subscription = SubscribeCandles(CandleType);
subscription
.BindEx(ema, rsi, macd, ProcessCandle)
.Start();
StartProtection(
TpPercent > 0m ? new Unit(TpPercent, UnitTypes.Percent) : new Unit(),
SlPercent > 0m ? new Unit(SlPercent, UnitTypes.Percent) : new Unit(),
isStopTrailing: true,
useMarketOrders: true);
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, ema);
DrawOwnTrades(area);
var oscillators = CreateChartArea();
if (oscillators != null)
{
DrawIndicator(oscillators, rsi);
DrawIndicator(oscillators, macd);
}
}
}
private void ProcessCandle(ICandleMessage candle, IIndicatorValue emaValue, IIndicatorValue rsiValue, IIndicatorValue macdValue)
{
if (candle.State != CandleStates.Finished)
return;
var prevCandle = _prevCandle;
_prevCandle = candle;
if (!macdValue.IsFormed)
return;
var macd = macdValue.GetValue<decimal>();
var prevMacd = _prevMacd;
_prevMacd = macd;
if (prevCandle == null || prevMacd is not decimal previousMacd || !emaValue.IsFormed || !rsiValue.IsFormed)
return;
if (!IsFormedAndOnlineAndAllowTrading())
return;
var ema = emaValue.GetValue<decimal>();
var rsi = rsiValue.GetValue<decimal>();
var close = candle.ClosePrice;
var prevClose = prevCandle.ClosePrice;
var longSignal = prevCandle.ClosePrice < prevCandle.OpenPrice && close > candle.OpenPrice && close > prevCandle.OpenPrice
&& close > ema && prevClose > ema && rsi < 65m && macd > previousMacd;
var shortSignal = prevCandle.ClosePrice > prevCandle.OpenPrice && close < candle.OpenPrice && close < prevCandle.OpenPrice
&& close < ema && prevClose < ema && rsi > 35m && macd < previousMacd;
if (longSignal)
{
if (ShowLong && Position <= 0)
BuyMarket(Volume + Math.Abs(Position));
else if (Position < 0)
BuyMarket(-Position);
}
else if (shortSignal)
{
if (ShowShort && Position >= 0)
SellMarket(Volume + Math.Abs(Position));
else if (Position > 0)
SellMarket(Position);
}
}
}
import clr
clr.AddReference("StockSharp.Messages")
clr.AddReference("StockSharp.Algo")
clr.AddReference("StockSharp.Algo.Indicators")
clr.AddReference("StockSharp.Algo.Strategies")
from System import TimeSpan, Decimal
from StockSharp.Messages import DataType, CandleStates, Unit, UnitTypes
from StockSharp.Algo.Indicators import ExponentialMovingAverage, RelativeStrengthIndex, MovingAverageConvergenceDivergence
from StockSharp.Algo.Strategies import Strategy
class vela_superada_strategy(Strategy):
"""
Vela Superada Strategy.
A bearish candle followed by a bullish one that closes above the prior open, with both closes above the EMA, RSI below 65
and a rising MACD line, is a long signal. The mirrored pattern below the EMA with RSI above 35 and a falling MACD line is
a short signal. ShowLong and ShowShort enable each side; an opposite signal closes or reverses the position. A trailing
SlPercent stop and a TpPercent take profit protect the trade.
"""
def __init__(self):
super(vela_superada_strategy, self).__init__()
self._ema_length = self.Param("EmaLength", 10).SetGreaterThanZero().SetDisplay("EMA Length", "EMA period", "Indicators")
self._rsi_length = self.Param("RsiLength", 14).SetGreaterThanZero().SetDisplay("RSI Length", "RSI period", "Indicators")
self._show_long = self.Param("ShowLong", True).SetDisplay("Long Trades", "Allow long trades", "Trading")
self._show_short = self.Param("ShowShort", False).SetDisplay("Short Trades", "Allow short trades", "Trading")
self._tp_percent = self.Param("TpPercent", 1.2).SetNotNegative().SetDisplay("TP %", "Take profit percentage from entry price", "Risk")
self._sl_percent = self.Param("SlPercent", 1.8).SetNotNegative().SetDisplay("SL %", "Trailing stop loss percentage", "Risk")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(30))).SetDisplay("Candle Type", "Type of candles to use", "General")
self._prev_candle = None
self._prev_macd = None
@property
def candle_type(self):
return self._candle_type.Value
def OnReseted(self):
super(vela_superada_strategy, self).OnReseted()
self._prev_candle = None
self._prev_macd = None
def OnStarted2(self, time):
super(vela_superada_strategy, self).OnStarted2(time)
self._prev_candle = None
self._prev_macd = None
ema = ExponentialMovingAverage()
ema.Length = self._ema_length.Value
rsi = RelativeStrengthIndex()
rsi.Length = self._rsi_length.Value
macd = MovingAverageConvergenceDivergence()
subscription = self.SubscribeCandles(self.candle_type)
subscription.BindEx(ema, rsi, macd, self._process_candle).Start()
tp = float(self._tp_percent.Value)
sl = float(self._sl_percent.Value)
self.StartProtection(
Unit(Decimal(tp), UnitTypes.Percent) if tp > 0 else Unit(),
Unit(Decimal(sl), UnitTypes.Percent) if sl > 0 else Unit(),
isStopTrailing=True,
useMarketOrders=True)
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawIndicator(area, ema)
self.DrawOwnTrades(area)
oscillators = self.CreateChartArea()
if oscillators is not None:
self.DrawIndicator(oscillators, rsi)
self.DrawIndicator(oscillators, macd)
def _process_candle(self, candle, ema_value, rsi_value, macd_value):
if candle.State != CandleStates.Finished:
return
prev_candle = self._prev_candle
self._prev_candle = candle
if not macd_value.IsFormed:
return
macd = float(macd_value.GetValue[Decimal](None))
prev_macd = self._prev_macd
self._prev_macd = macd
if prev_candle is None or prev_macd is None or not ema_value.IsFormed or not rsi_value.IsFormed:
return
if not self.IsFormedAndOnlineAndAllowTrading():
return
ema = float(ema_value.GetValue[Decimal](None))
rsi = float(rsi_value.GetValue[Decimal](None))
open_price = float(candle.OpenPrice)
close = float(candle.ClosePrice)
prev_open = float(prev_candle.OpenPrice)
prev_close = float(prev_candle.ClosePrice)
long_signal = (prev_close < prev_open and close > open_price and close > prev_open
and close > ema and prev_close > ema and rsi < 65 and macd > prev_macd)
short_signal = (prev_close > prev_open and close < open_price and close < prev_open
and close < ema and prev_close < ema and rsi > 35 and macd < prev_macd)
if long_signal:
if self._show_long.Value and self.Position <= 0:
self.BuyMarket(self.Volume + abs(self.Position))
elif self.Position < 0:
self.BuyMarket(-self.Position)
elif short_signal:
if self._show_short.Value and self.Position >= 0:
self.SellMarket(self.Volume + abs(self.Position))
elif self.Position > 0:
self.SellMarket(self.Position)
def CreateClone(self):
return vela_superada_strategy()