Port des MetaTrader 5-Experten MySystem.mq5 in MQL/22016.
Erkennt Momentum-Umkehrungen durch Mittelung der Elder Bulls Power und Bears Power Werte, die aus Kerzenextremen und einer EMA berechnet werden.
Tritt long ein, wenn der Durchschnitt steigt, während er noch unter null liegt (bärischer Druck lässt nach), und short, wenn der Durchschnitt sinkt, während er noch über null liegt (bullischer Druck lässt nach).
Für jeweils eine offene Position konzipiert; Stop-Loss und Take-Profit sind optional und in Pips ausgedrückt.
Indikatorlogik
Komponente
Beschreibung
Exponential Moving Average (EMA)
Auf Kerzenschlusskurse angewendet. Der Parameter MaPeriod steuert das Glättungsfenster (Standard 5).
Bulls Power (abgeleitet)
Berechnet als High - EMA. Misst die bullische Stärke relativ zur EMA.
Bears Power (abgeleitet)
Berechnet als Low - EMA. Misst die bärische Stärke relativ zur EMA.
Durchschnittliche Kraft
(Bulls Power + Bears Power) / 2. Dieser synthetische Oszillator wird mit seinem vorherigen Wert verglichen, um Momentum-Änderungen zu erkennen.
Die Strategie bewertet die letzten zwei fertigen Kerzen. Neue Trades werden nur bewertet, wenn eine Kerze vollständig abgeschlossen ist, um Intrabar-Rauschen zu vermeiden.
Einstiegsregeln
Warten, bis die EMA vollständig gebildet ist (d.h. mindestens MaPeriod Kerzen verarbeitet hat).
Bulls Power und Bears Power für die gerade geschlossene Kerze unter Verwendung ihres Hochs/Tiefs und des EMA-Werts berechnen.
Beide Kräfte mitteln, um die aktuelle Oszillatorlesing zu erhalten.
Mit dem vorherigen Durchschnitt vergleichen:
Long-Setup: vorheriger Durchschnitt < aktueller Durchschnitt und aktueller Durchschnitt < 0. Long einsteigen, wenn keine bestehende Position vorhanden.
Short-Setup: vorheriger Durchschnitt > aktueller Durchschnitt und aktueller Durchschnitt > 0. Short einsteigen, wenn flat.
Nach dem Einstieg auf optionale Schutzorders oder manuelle Verwaltung verlassen. Der Algorithmus generiert keine Ausstiegssignale außer Stop-Loss/Take-Profit.
Risikomanagement
StopLossPips: Optionaler absoluter Stop-Abstand in Pips (0 deaktiviert den Stop). Umgerechnet mit dem PriceStep des Instruments.
TakeProfitPips: Optionales absolutes Gewinnziel in Pips (0 deaktiviert das Ziel).
Schutzorders werden registriert, sobald die Position über StartProtection mit Marktausführung eröffnet wird.
Parameter
Name
Standard
Beschreibung
OrderVolume
0.1
Ordergröße für Markteinstiege.
StopLossPips
15
Stop-Loss-Abstand in Pips. Auf 0 setzen zum Deaktivieren.
TakeProfitPips
95
Take-Profit-Abstand in Pips. Auf 0 setzen zum Deaktivieren.
MaPeriod
5
EMA-Länge für die Bulls/Bears Power Berechnung.
CandleType
1-Stunden-Zeitrahmen
Kerzenserie für alle Berechnungen (ändern, um Ihrem Datenfeed zu entsprechen).
Verwendungshinweise
Die Strategie einem Instrument zuordnen und sicherstellen, dass CandleType dem beabsichtigten Zeitrahmen entspricht.
OrderVolume, StopLossPips und TakeProfitPips an die Broker-Anforderungen anpassen.
Die Strategie starten; sie abonniert automatisch Kerzen, aktualisiert die EMA und gibt Marktorders bei qualifizierenden Signalen aus.
Es kann jeweils nur eine Position existieren. Wenn ein Trade aktiv ist, werden neue Signale ignoriert, bis die Schutzorders die Position schließen oder sie manuell geschlossen wird.
Da die ursprüngliche MQL-Version InpBarCurrent = 1 verwendete, arbeitet dieser Port immer auf vollständig geschlossenen Kerzen und vergleicht aufeinanderfolgende Werte; keine Intrabar-Neuberechnung wird durchgeführt.
Unterschiede zum Original-MQL-Experten
Verwendet die StockSharp High-Level Strategy-API mit Kerzenabonnements und Indikatorbindung statt manuellem Buffer-Zugriff.
Leitet Pips automatisch von PriceStep ab anstatt manuelle Ziffernanpassungen.
Überspringt das ursprünglich auskommentierte Order-Management und verlässt sich auf eingebauten Positionsschutz.
Behält die Einzelpositions-Einschränkung der Quelle bei, indem Signale ignoriert werden, während eine Position existiert.
Testempfehlungen
Backtest auf dem beabsichtigten Symbol/Zeitrahmen mit historischen Daten, die Hoch-/Tief-Preise für genaue Bulls/Bears-Berechnung beinhalten.
Schutzorder-Verhalten mit Ihrer Broker-Tick-Größe und Volumen-Schritt validieren, bevor live ausgeführt wird.
Mit verschiedenen MaPeriod-Werten experimentieren, um die Sensitivität an die Instrumentvolatilität anzupassen.
using System;
using System.Collections.Generic;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
/// <summary>
/// Bulls Bears Power Average strategy. Uses EMA with bulls/bears power crossover.
/// </summary>
public class BullsBearsPowerAverageStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _emaPeriod;
private decimal? _prevPower;
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public int EmaPeriod { get => _emaPeriod.Value; set => _emaPeriod.Value = value; }
public BullsBearsPowerAverageStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(1).TimeFrame()).SetDisplay("Candle Type", "Timeframe", "General");
_emaPeriod = Param(nameof(EmaPeriod), 13).SetGreaterThanZero().SetDisplay("EMA Period", "EMA lookback for power calc", "Indicators");
}
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities() => [(Security, CandleType)];
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_prevPower = null;
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_prevPower = null;
var ema = new ExponentialMovingAverage { Length = EmaPeriod };
var subscription = SubscribeCandles(CandleType);
subscription.Bind(ema, ProcessCandle).Start();
var area = CreateChartArea();
if (area != null) { DrawCandles(area, subscription); DrawIndicator(area, ema); DrawOwnTrades(area); }
}
private void ProcessCandle(ICandleMessage candle, decimal emaVal)
{
if (candle.State != CandleStates.Finished) return;
var bullsPower = candle.HighPrice - emaVal;
var bearsPower = candle.LowPrice - emaVal;
var avgPower = (bullsPower + bearsPower) / 2m;
if (!IsFormedAndOnlineAndAllowTrading()) { _prevPower = avgPower; return; }
if (_prevPower == null) { _prevPower = avgPower; return; }
if (_prevPower.Value < 0m && avgPower >= 0m && Position <= 0) { if (Position < 0) BuyMarket(); BuyMarket(); }
else if (_prevPower.Value > 0m && avgPower <= 0m && Position >= 0) { if (Position > 0) SellMarket(); SellMarket(); }
_prevPower = avgPower;
}
}
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 bulls_bears_power_average_strategy(Strategy):
"""
Bulls Bears Power Average strategy. Uses EMA with bulls/bears power crossover.
"""
def __init__(self):
super(bulls_bears_power_average_strategy, self).__init__()
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(1))) \
.SetDisplay("Candle Type", "Timeframe", "General")
self._ema_period = self.Param("EmaPeriod", 13) \
.SetDisplay("EMA Period", "EMA lookback for power calc", "Indicators")
self._prev_power = None
@property
def candle_type(self):
return self._candle_type.Value
@candle_type.setter
def candle_type(self, value):
self._candle_type.Value = value
@property
def ema_period(self):
return self._ema_period.Value
@ema_period.setter
def ema_period(self, value):
self._ema_period.Value = value
def OnReseted(self):
super(bulls_bears_power_average_strategy, self).OnReseted()
self._prev_power = None
def OnStarted2(self, time):
super(bulls_bears_power_average_strategy, self).OnStarted2(time)
self._prev_power = None
ema = ExponentialMovingAverage()
ema.Length = self.ema_period
subscription = self.SubscribeCandles(self.candle_type)
subscription.Bind(ema, self.on_process).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawIndicator(area, ema)
self.DrawOwnTrades(area)
def on_process(self, candle, ema_val):
if candle.State != CandleStates.Finished:
return
bulls_power = candle.HighPrice - ema_val
bears_power = candle.LowPrice - ema_val
avg_power = (bulls_power + bears_power) / 2.0
if not self.IsFormedAndOnlineAndAllowTrading():
self._prev_power = avg_power
return
if self._prev_power is None:
self._prev_power = avg_power
return
if self._prev_power < 0.0 and avg_power >= 0.0 and self.Position <= 0:
if self.Position < 0:
self.BuyMarket()
self.BuyMarket()
elif self._prev_power > 0.0 and avg_power <= 0.0 and self.Position >= 0:
if self.Position > 0:
self.SellMarket()
self.SellMarket()
self._prev_power = avg_power
def CreateClone(self):
return bulls_bears_power_average_strategy()