Diese Strategie handelt auf Basis der Kreuzung der Indikatoren Bulls Power und Bears Power auf einem Vier-Stunden-Zeitrahmen. Bulls Power misst den Kaufdruck oberhalb eines Durchschnittspreises, während Bears Power den Verkaufsdruck darunter zeigt. Wenn die Kaufstärke die Verkaufsstärke übersteigt, eröffnet das System eine Long-Position. Wenn die Verkaufsstärke dominant wird, eröffnet es eine Short-Position.
Tests mit historischen Kryptodaten zeigen, dass klare Kreuzungen oft kurzfristigen Umkehrungen vorausgehen. Die Strategie ist darauf ausgelegt, immer entweder long oder short zu sein und die Position bei jeder Kreuzung in die entgegengesetzte Richtung umzukehren.
Details
Einstiegskriterien:
Long: Bulls Power-Wert kreuzt über Bears Power.
Short: Bears Power-Wert kreuzt über Bulls Power.
Long/Short: Beide Richtungen.
Ausstiegskriterien: Entgegengesetzte Kreuzung, die die Position umkehrt.
Stops: Keine. Positionen werden umgekehrt statt ausgestoppt.
Filter:
Zeitrahmen: standardmäßig 4-Stunden-Kerzen.
Indikatoren: Bulls Power, Bears Power.
Richtung: Umkehr basierend auf Momentum-Wechsel.
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>
/// EMA crossover with RSI filter strategy.
/// </summary>
public class BullsBearsPowerCrossStrategy : Strategy
{
private readonly StrategyParam<int> _fastPeriod;
private readonly StrategyParam<int> _slowPeriod;
private readonly StrategyParam<DataType> _candleType;
private decimal _prevFast;
private decimal _prevSlow;
private bool _hasPrev;
public int FastPeriod { get => _fastPeriod.Value; set => _fastPeriod.Value = value; }
public int SlowPeriod { get => _slowPeriod.Value; set => _slowPeriod.Value = value; }
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public BullsBearsPowerCrossStrategy()
{
_fastPeriod = Param(nameof(FastPeriod), 13)
.SetGreaterThanZero()
.SetDisplay("Fast Period", "Fast EMA period", "Indicators");
_slowPeriod = Param(nameof(SlowPeriod), 26)
.SetGreaterThanZero()
.SetDisplay("Slow Period", "Slow EMA period", "Indicators");
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
.SetDisplay("Candle Type", "Candle type", "General");
}
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
=> [(Security, CandleType)];
protected override void OnReseted()
{
base.OnReseted();
_prevFast = 0;
_prevSlow = 0;
_hasPrev = false;
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var fast = new ExponentialMovingAverage { Length = FastPeriod };
var slow = new ExponentialMovingAverage { Length = SlowPeriod };
SubscribeCandles(CandleType)
.Bind(fast, slow, ProcessCandle)
.Start();
}
private void ProcessCandle(ICandleMessage candle, decimal fastVal, decimal slowVal)
{
if (candle.State != CandleStates.Finished) return;
if (!_hasPrev)
{
_prevFast = fastVal;
_prevSlow = slowVal;
_hasPrev = true;
return;
}
var crossUp = _prevFast <= _prevSlow && fastVal > slowVal;
var crossDown = _prevFast >= _prevSlow && fastVal < slowVal;
if (crossUp && Position <= 0)
{
if (Position < 0) BuyMarket();
BuyMarket();
}
else if (crossDown && Position >= 0)
{
if (Position > 0) SellMarket();
SellMarket();
}
_prevFast = fastVal;
_prevSlow = slowVal;
}
}