Die Strategie reagiert auf starke bullische und bärische Kerzen und eröffnet Marktpositionen in dieselbe Richtung. Sie nutzt eine unabhängige Martingal-Sequenz für jede Seite: Long-Positionen skalieren das Volumen mit dem Bull Multiplier, Short-Positionen verwenden den Bear Multiplier. Schutzdistanzen für Stop-Loss und Take-Profit werden ebenfalls getrennt je Richtung konfiguriert, was präzise Kontrolle über das asymmetrische Verhalten des ursprünglichen MQL-Expert-Advisors ermöglicht.
Handelslogik
Den konfigurierten Kerzentyp abonnieren (Standard: 1 Minute) und nur auf abgeschlossene Kerzen warten.
Wenn keine Position offen ist:
Bullisches Setup: Wenn Close > Open und die Kerzenkörpergröße den bullischen Körperfilter überschreitet, zum Markt kaufen.
Bärisches Setup: Wenn Close < Open und die Körpergröße den bärischen Körperfilter überschreitet, zum Markt verkaufen.
Jeder Einstieg setzt Stop-Loss- und Take-Profit-Orders, die aus Pip-Distanzen in den Preisschritt des Instruments umgerechnet werden.
Wenn eine Position schließt, wird der realisierte PnL mit der vorherigen Basislinie verglichen:
Ein negatives Ergebnis multipliziert das jeweilige Martingal-Volumen.
Ein positives oder Break-even-Ergebnis setzt diese Seite auf das Anfangsvolumen zurück.
Neue Signale werden ignoriert, solange eine Position offen ist, wodurch das Single-Trade-Verhalten des Quell-EA reproduziert wird.
Geldmanagement
Long- und Short-Martingal-Zyklen werden unabhängig verfolgt, sodass eine verlierende Long-Serie den nächsten Short-Trade nicht beeinflusst und umgekehrt.
Volumen werden an VolumeStep der Security ausgerichtet, um Orderablehnungen zu vermeiden.
StartProtection(useMarketOrders: true) aktiviert StockSharps Schutzorder-Verwaltung für die angehängten Stop- und Take-Niveaus.
Parameter
Parameter
Beschreibung
Initial Volume
Basisvolumen, mit dem jeder Martingal-Zyklus für beide Richtungen startet.
Bull Multiplier
Multiplikator für den nächsten bullischen Trade nach einer verlierenden Long-Position.
Bear Multiplier
Multiplikator für den nächsten bärischen Trade nach einer verlierenden Short-Position.
Bull Stop Loss
Stop-Loss-Distanz in Pips für bullische Trades, in Preis über den Instrumentenschritt konvertiert.
Bull Take Profit
Take-Profit-Distanz in Pips für bullische Trades.
Bear Stop Loss
Stop-Loss-Distanz in Pips für bärische Trades.
Bear Take Profit
Take-Profit-Distanz in Pips für bärische Trades.
Bull Body Filter
Minimaler bullischer Kerzenkörper in Pips, der eine Kauforder auslöst.
Bear Body Filter
Minimaler bärischer Kerzenkörper in Pips, der eine Verkaufsorder auslöst.
Candle Type
Zeitrahmen für die Signalerzeugung (standardmäßig 1-Minuten-Zeitrahmen).
Nutzungshinweise
Stellen Sie sicher, dass die verbundene Security gültige PriceStep- und VolumeStep-Werte bereitstellt. Die Strategie verwendet standardmäßig 0.0001, wenn PriceStep nicht geliefert wird.
Die Martingal-Logik stützt sich auf realisierten PnL, daher aktualisiert auch manuelles Schließen von Positionen die Sequenz korrekt.
Optimierung kann sich auf Körperfilter und Multiplikator-Kombinationen konzentrieren, um Reaktionsfähigkeit gegen Drawdown auszubalancieren.
using System;
using Ecng.Common;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
/// <summary>
/// Bull/Bear Candle Martingale strategy: Bullish/bearish candle direction + EMA filter.
/// Buys after strong bullish candle when close crosses above EMA.
/// Sells after strong bearish candle when close crosses below EMA.
/// </summary>
public class BullBearCandleMartingaleStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _emaPeriod;
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
public int EmaPeriod
{
get => _emaPeriod.Value;
set => _emaPeriod.Value = value;
}
public BullBearCandleMartingaleStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(1).TimeFrame())
.SetDisplay("Candle Type", "Candle timeframe", "General");
_emaPeriod = Param(nameof(EmaPeriod), 30)
.SetGreaterThanZero()
.SetDisplay("EMA Period", "EMA period", "Indicators");
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var ema = new ExponentialMovingAverage { Length = EmaPeriod };
decimal? prevClose = null;
decimal? prevEma = null;
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(ema, (candle, emaVal) =>
{
if (candle.State != CandleStates.Finished)
return;
if (!IsFormedAndOnlineAndAllowTrading())
return;
var close = candle.ClosePrice;
var bullish = close > candle.OpenPrice;
var bearish = close < candle.OpenPrice;
var bodySize = Math.Abs(close - candle.OpenPrice);
var range = candle.HighPrice - candle.LowPrice;
// Require strong candle body (>50% of range)
var strongCandle = range > 0 && bodySize / range > 0.5m;
if (prevClose.HasValue && prevEma.HasValue && strongCandle)
{
var crossUp = prevClose.Value <= prevEma.Value && close > emaVal;
var crossDown = prevClose.Value >= prevEma.Value && close < emaVal;
if (bullish && crossUp && Position <= 0)
BuyMarket();
else if (bearish && crossDown && Position >= 0)
SellMarket();
}
prevClose = close;
prevEma = emaVal;
})
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, ema);
DrawOwnTrades(area);
}
}
}
import clr
clr.AddReference("StockSharp.Messages")
clr.AddReference("StockSharp.Algo")
clr.AddReference("StockSharp.Algo.Indicators")
clr.AddReference("StockSharp.Algo.Strategies")
from System import TimeSpan
from StockSharp.Messages import DataType, CandleStates
from StockSharp.Algo.Indicators import ExponentialMovingAverage
from StockSharp.Algo.Strategies import Strategy
class bull_bear_candle_martingale_strategy(Strategy):
def __init__(self):
super(bull_bear_candle_martingale_strategy, self).__init__()
self._ema_period = self.Param("EmaPeriod", 30) \
.SetDisplay("EMA Period", "EMA period", "Indicators")
self._ema = None
self._prev_close = None
self._prev_ema = None
@property
def ema_period(self):
return self._ema_period.Value
def OnReseted(self):
super(bull_bear_candle_martingale_strategy, self).OnReseted()
self._ema = None
self._prev_close = None
self._prev_ema = None
def OnStarted2(self, time):
super(bull_bear_candle_martingale_strategy, self).OnStarted2(time)
self._ema = ExponentialMovingAverage()
self._ema.Length = self.ema_period
subscription = self.SubscribeCandles(DataType.TimeFrame(TimeSpan.FromHours(1)))
subscription.Bind(self._ema, self._process_candle)
subscription.Start()
def _process_candle(self, candle, ema_value):
if candle.State != CandleStates.Finished:
return
if not self._ema.IsFormed:
return
close = float(candle.ClosePrice)
open_p = float(candle.OpenPrice)
high = float(candle.HighPrice)
low = float(candle.LowPrice)
ema_val = float(ema_value)
bullish = close > open_p
bearish = close < open_p
body_size = abs(close - open_p)
range_size = high - low
strong_candle = range_size > 0 and body_size / range_size > 0.5
if self._prev_close is not None and self._prev_ema is not None and strong_candle:
cross_up = self._prev_close <= self._prev_ema and close > ema_val
cross_down = self._prev_close >= self._prev_ema and close < ema_val
if bullish and cross_up and self.Position <= 0:
self.BuyMarket()
elif bearish and cross_down and self.Position >= 0:
self.SellMarket()
self._prev_close = close
self._prev_ema = ema_val
def CreateClone(self):
return bull_bear_candle_martingale_strategy()