Die AbcWsCci-Strategie kombiniert zwei klassische japanische Candlestick-Umkehrmuster – Three White Soldiers und Three Black Crows – mit dem Commodity Channel Index (CCI)-Indikator zur Bestätigung. Das System scannt fertige Kerzen, misst die Körpergröße im Verhältnis zu einer gleitenden Durchschnittsbasislinie und eröffnet Geschäfte nur, wenn ein starkes Multi-Kerzen-Momentum mit CCI-Extremen übereinstimmt. Positionsausstiege werden ausgelöst, wenn der CCI die Extremzonen verlässt, was signalisiert, dass die Dynamik nachlässt.
Handelslogik
Behalten Sie einen gleitenden Durchschnitt der Kerzenkörpergrößen bei, um „lange“ Kerzen zu qualifizieren.
Erkennen Sie das Muster der drei weißen Soldaten (drei aufeinanderfolgende starke bullische Kerzen mit steigenden Mittelpunkten).
Erkennen Sie das Three Black Crows-Muster (drei aufeinanderfolgende starke bärische Kerzen mit fallenden Mittelpunkten).
Bestätigen Sie bullische Einstiege, wenn CCI unter -50 fällt, und bärische Einstiege, wenn CCI über 50 steigt.
Schließen Sie Long-Positionen, wenn CCI die Werte -80 oder 80 überschreitet, und schließen Sie Short-Positionen zu den entsprechenden Bedingungen.
Parameter
Name
Beschreibung
Standard
CciPeriod
Länge des zur Bestätigung verwendeten Indikators CCI.
37
BodyAveragePeriod
Anzahl der Kerzen im gleitenden Durchschnitt, die die minimale „starke“ Körpergröße definieren.
13
CandleType
Kerzenzeitrahmen, der zur Mustererkennung verwendet wird.
1 Stunde
Indikatoren
Commodity Channel Index (CCI): Bewertet Momentum-Extreme für Bestätigungs- und Ausstiegssignale.
Einfacher gleitender Durchschnitt der Kerzenkörper: Legt die Mindestkerzengröße fest, die für ein gültiges Muster erforderlich ist.
Positionsmanagement
Geben Sie long ein, wenn sich drei weiße Soldaten bilden und CCI unter -50 liegt, während keine Long-Position aktiv ist.
Geben Sie short ein, wenn sich Three Black Crows bilden und CCI über 50 liegt, während keine Short-Position aktiv ist.
Verlassen Sie Long-Positionen, wenn CCI das -80/80-Band verlässt, was darauf hinweist, dass der Aufwärtsimpuls erschöpft ist.
Verlassen Sie Short-Positionen, wenn CCI das +80/-80-Band verlässt, was einen rückläufigen Momentumverlust signalisiert.
Nutzungshinweise
Die Strategie ist ereignisgesteuert: Es werden nur vollständig abgeschlossene Kerzen verarbeitet.
Funktioniert am besten bei Trendinstrumenten, bei denen Multi-Candle-Momentum in Kombination mit Oszillator-Extremen zuverlässige Signale liefert.
Erwägen Sie die Kombination mit zusätzlichen Risikomanagementregeln (Stop-Loss, Positionsgrößenbestimmung), abhängig von Ihrer Handelsumgebung.
namespace StockSharp.Samples.Strategies;
using System;
using Ecng.Common;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.Messages;
/// <summary>
/// ABC WS CCI strategy: 3 white soldiers / 3 black crows pattern with CCI confirmation.
/// Buys after 3 bullish candles with CCI below 100, sells after 3 bearish candles with CCI above -100.
/// </summary>
public class AbcWsCciStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _cciPeriod;
private readonly StrategyParam<int> _signalCooldownCandles;
private int _bullCount;
private int _bearCount;
private int _candlesSinceTrade;
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public int CciPeriod { get => _cciPeriod.Value; set => _cciPeriod.Value = value; }
public int SignalCooldownCandles { get => _signalCooldownCandles.Value; set => _signalCooldownCandles.Value = value; }
public AbcWsCciStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(60).TimeFrame())
.SetDisplay("Candle Type", "Candle timeframe", "General");
_cciPeriod = Param(nameof(CciPeriod), 14)
.SetGreaterThanZero()
.SetDisplay("CCI Period", "CCI period for confirmation", "Indicators");
_signalCooldownCandles = Param(nameof(SignalCooldownCandles), 6)
.SetGreaterThanZero()
.SetDisplay("Signal Cooldown", "Bars to wait between trades", "Trading");
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_bullCount = 0;
_bearCount = 0;
_candlesSinceTrade = SignalCooldownCandles;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_bullCount = 0;
_bearCount = 0;
_candlesSinceTrade = SignalCooldownCandles;
var cci = new CommodityChannelIndex { Length = CciPeriod };
var subscription = SubscribeCandles(CandleType);
subscription.Bind(cci, ProcessCandle).Start();
}
private void ProcessCandle(ICandleMessage candle, decimal cci)
{
if (candle.State != CandleStates.Finished) return;
if (_candlesSinceTrade < SignalCooldownCandles)
_candlesSinceTrade++;
if (candle.ClosePrice > candle.OpenPrice)
{
_bullCount++;
_bearCount = 0;
}
else if (candle.ClosePrice < candle.OpenPrice)
{
_bearCount++;
_bullCount = 0;
}
else
{
_bullCount = 0;
_bearCount = 0;
}
// Exit on CCI reversal
if (Position > 0 && cci > 200 && _candlesSinceTrade >= SignalCooldownCandles)
{
SellMarket();
_candlesSinceTrade = 0;
}
else if (Position < 0 && cci < -200 && _candlesSinceTrade >= SignalCooldownCandles)
{
BuyMarket();
_candlesSinceTrade = 0;
}
// Entry on 3 soldiers/crows pattern
if (_bullCount >= 3 && cci < 100 && Position <= 0 && _candlesSinceTrade >= SignalCooldownCandles)
{
BuyMarket();
_bullCount = 0;
_candlesSinceTrade = 0;
}
else if (_bearCount >= 3 && cci > -100 && Position >= 0 && _candlesSinceTrade >= SignalCooldownCandles)
{
SellMarket();
_bearCount = 0;
_candlesSinceTrade = 0;
}
}
}
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 CommodityChannelIndex
from StockSharp.Algo.Strategies import Strategy
class abc_ws_cci_strategy(Strategy):
def __init__(self):
super(abc_ws_cci_strategy, self).__init__()
self._cci_period = self.Param("CciPeriod", 14) \
.SetDisplay("CCI Period", "CCI period for confirmation", "Indicators")
self._signal_cooldown = self.Param("SignalCooldownCandles", 6) \
.SetDisplay("Signal Cooldown", "Bars to wait between trades", "Trading")
self._cci = None
self._bull_count = 0
self._bear_count = 0
self._candles_since_trade = 0
@property
def cci_period(self):
return self._cci_period.Value
@property
def signal_cooldown(self):
return self._signal_cooldown.Value
def OnReseted(self):
super(abc_ws_cci_strategy, self).OnReseted()
self._cci = None
self._bull_count = 0
self._bear_count = 0
self._candles_since_trade = self.signal_cooldown
def OnStarted2(self, time):
super(abc_ws_cci_strategy, self).OnStarted2(time)
self._cci = CommodityChannelIndex()
self._cci.Length = self.cci_period
self._bull_count = 0
self._bear_count = 0
self._candles_since_trade = self.signal_cooldown
subscription = self.SubscribeCandles(DataType.TimeFrame(TimeSpan.FromMinutes(60)))
subscription.Bind(self._cci, self._process_candle)
subscription.Start()
def _process_candle(self, candle, cci_value):
if candle.State != CandleStates.Finished:
return
if not self._cci.IsFormed:
return
cci_val = float(cci_value)
if self._candles_since_trade < self.signal_cooldown:
self._candles_since_trade += 1
close = float(candle.ClosePrice)
open_p = float(candle.OpenPrice)
if close > open_p:
self._bull_count += 1
self._bear_count = 0
elif close < open_p:
self._bear_count += 1
self._bull_count = 0
else:
self._bull_count = 0
self._bear_count = 0
if self.Position > 0 and cci_val > 200.0 and self._candles_since_trade >= self.signal_cooldown:
self.SellMarket()
self._candles_since_trade = 0
elif self.Position < 0 and cci_val < -200.0 and self._candles_since_trade >= self.signal_cooldown:
self.BuyMarket()
self._candles_since_trade = 0
if self._bull_count >= 3 and cci_val < 100.0 and self.Position <= 0 and self._candles_since_trade >= self.signal_cooldown:
self.BuyMarket()
self._bull_count = 0
self._candles_since_trade = 0
elif self._bear_count >= 3 and cci_val > -100.0 and self.Position >= 0 and self._candles_since_trade >= self.signal_cooldown:
self.SellMarket()
self._bear_count = 0
self._candles_since_trade = 0
def CreateClone(self):
return abc_ws_cci_strategy()