Momentum-Umkehr-Strategie, adaptiert vom MQL5-Experten "e-TurboFx". Das System beobachtet eine Reihe von Kerzen, deren Körper in dieselbe Richtung wachsen. Nach mehreren bärischen Kerzen mit sich ausdehnenden Körpern kauft die Strategie und erwartet eine Gegenbewegung. Nach mehreren bullischen Kerzen mit wachsenden Körpern verkauft sie. Optionaler Stop-Loss und Take-Profit werden in rohen Preispunkten gesetzt.
Details
Einstiegskriterien:
Long: N aufeinanderfolgende bärische Kerzen und jeder Körper größer als der vorherige
Short: N aufeinanderfolgende bullische Kerzen und jeder Körper größer als der vorherige
Long/Short: Beide
Ausstiegskriterien: Stop-Loss oder Take-Profit
Stops: Punkte über StartProtection
Standardwerte:
BarsCount = 3
StopLossPoints = 700
TakeProfitPoints = 1200
CandleType = TimeSpan.FromMinutes(1).TimeFrame()
Filter:
Kategorie: Price Action
Richtung: Beide
Indikatoren: Keine
Stops: Ja
Komplexität: Grundlegend
Zeitrahmen: Intraday
Saisonalität: Nein
Neuronale Netze: Nein
Divergenz: Nein
Risikolevel: Mittel
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>
/// Reversal candle pattern strategy with EMA filter.
/// </summary>
public class ETurboFxStrategy : Strategy
{
private readonly StrategyParam<int> _emaPeriod;
private readonly StrategyParam<DataType> _candleType;
private int _bearCount;
private int _bullCount;
private decimal _prevBody;
private bool _hasPrev;
public int EmaPeriod { get => _emaPeriod.Value; set => _emaPeriod.Value = value; }
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public ETurboFxStrategy()
{
_emaPeriod = Param(nameof(EmaPeriod), 20)
.SetGreaterThanZero()
.SetDisplay("EMA Period", "EMA trend filter period", "Parameters");
_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();
_bearCount = 0;
_bullCount = 0;
_prevBody = 0;
_hasPrev = false;
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var ema = new ExponentialMovingAverage { Length = EmaPeriod };
SubscribeCandles(CandleType)
.Bind(ema, ProcessCandle)
.Start();
}
private void ProcessCandle(ICandleMessage candle, decimal emaVal)
{
if (candle.State != CandleStates.Finished) return;
var body = Math.Abs(candle.ClosePrice - candle.OpenPrice);
if (candle.ClosePrice < candle.OpenPrice)
{
_bearCount++;
if (_hasPrev && body > _prevBody)
_bearCount = Math.Min(_bearCount, 10);
else
_bearCount = 1;
_bullCount = 0;
}
else if (candle.ClosePrice > candle.OpenPrice)
{
_bullCount++;
if (_hasPrev && body > _prevBody)
_bullCount = Math.Min(_bullCount, 10);
else
_bullCount = 1;
_bearCount = 0;
}
else
{
_bearCount = 0;
_bullCount = 0;
}
_prevBody = body;
_hasPrev = true;
// Buy reversal after 3 bearish candles when price above EMA
if (_bearCount >= 3 && candle.ClosePrice > emaVal && Position <= 0)
{
if (Position < 0) BuyMarket();
BuyMarket();
}
// Sell reversal after 3 bullish candles when price below EMA
else if (_bullCount >= 3 && candle.ClosePrice < emaVal && Position >= 0)
{
if (Position > 0) SellMarket();
SellMarket();
}
}
}
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 e_turbo_fx_strategy(Strategy):
def __init__(self):
super(e_turbo_fx_strategy, self).__init__()
self._ema_period = self.Param("EmaPeriod", 20) \
.SetDisplay("EMA Period", "EMA trend filter period", "Parameters")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(4))) \
.SetDisplay("Candle Type", "Candle type", "General")
self._bear_count = 0
self._bull_count = 0
self._prev_body = 0.0
self._has_prev = False
@property
def ema_period(self):
return self._ema_period.Value
@property
def candle_type(self):
return self._candle_type.Value
def OnReseted(self):
super(e_turbo_fx_strategy, self).OnReseted()
self._bear_count = 0
self._bull_count = 0
self._prev_body = 0.0
self._has_prev = False
def OnStarted2(self, time):
super(e_turbo_fx_strategy, self).OnStarted2(time)
ema = ExponentialMovingAverage()
ema.Length = self.ema_period
self.SubscribeCandles(self.candle_type).Bind(ema, self.process_candle).Start()
def process_candle(self, candle, ema_val):
if candle.State != CandleStates.Finished:
return
body = abs(float(candle.ClosePrice) - float(candle.OpenPrice))
if float(candle.ClosePrice) < float(candle.OpenPrice):
self._bear_count += 1
if self._has_prev and body > self._prev_body:
self._bear_count = min(self._bear_count, 10)
else:
self._bear_count = 1
self._bull_count = 0
elif float(candle.ClosePrice) > float(candle.OpenPrice):
self._bull_count += 1
if self._has_prev and body > self._prev_body:
self._bull_count = min(self._bull_count, 10)
else:
self._bull_count = 1
self._bear_count = 0
else:
self._bear_count = 0
self._bull_count = 0
self._prev_body = body
self._has_prev = True
ev = float(ema_val)
close = float(candle.ClosePrice)
if self._bear_count >= 3 and close > ev and self.Position <= 0:
if self.Position < 0:
self.BuyMarket()
self.BuyMarket()
elif self._bull_count >= 3 and close < ev and self.Position >= 0:
if self.Position > 0:
self.SellMarket()
self.SellMarket()
def CreateClone(self):
return e_turbo_fx_strategy()