Feinabstimmungs-MA-Strategie
Diese Strategie überwacht die Steigung eines einfachen gleitenden Durchschnitts. Nach zwei aufeinanderfolgenden Balken in eine Richtung löst eine Richtungsumkehr des gleitenden Durchschnitts einen Einstieg aus. Ein Aufwärtsschwenk nach einem Rückgang eröffnet eine Long-Position, während ein Abwärtsschwenk nach einem Anstieg eine Short-Position eröffnet. Entgegengesetzte Signale schließen bestehende Trades.
Das System wurde aus dem MQL-Expert-Advisor "Exp_FineTuningMA" konvertiert und ersetzt den originalen benutzerdefinierten Indikator durch einen standardmäßigen einfachen gleitenden Durchschnitt für mehr Übersichtlichkeit.
Details
- Einstiegskriterien: MA ändert nach zwei Balken die Richtung.
- Long/Short: Beide Richtungen.
- Ausstiegskriterien: Entgegengesetztes Signal oder Stop.
- Stops: Ja, prozentbasiert.
- Standardwerte:
MaLength = 10
TakeProfitPercent = 1
StopLossPercent = 1
CandleType = TimeSpan.FromHours(4)
- Filter:
- Kategorie: Trendfolge
- Richtung: Beide
- Indikatoren: SMA
- Stops: Ja
- Komplexität: Mittel
- Zeitrahmen: Swing / H4
- 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>
/// Fine Tuning MA strategy. Opens positions when the moving average changes direction.
/// </summary>
public class FineTuningMaStrategy : Strategy
{
private readonly StrategyParam<int> _maLength;
private readonly StrategyParam<decimal> _takeProfitPercent;
private readonly StrategyParam<decimal> _stopLossPercent;
private readonly StrategyParam<DataType> _candleType;
private decimal _prev1;
private decimal _prev2;
private int _candleCount;
public int MaLength { get => _maLength.Value; set => _maLength.Value = value; }
public decimal TakeProfitPercent { get => _takeProfitPercent.Value; set => _takeProfitPercent.Value = value; }
public decimal StopLossPercent { get => _stopLossPercent.Value; set => _stopLossPercent.Value = value; }
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public FineTuningMaStrategy()
{
_maLength = Param(nameof(MaLength), 20)
.SetGreaterThanZero()
.SetDisplay("MA Length", "Length of the moving average", "Parameters");
_takeProfitPercent = Param(nameof(TakeProfitPercent), 1m)
.SetDisplay("Take Profit, %", "Take profit level in percent", "Protection");
_stopLossPercent = Param(nameof(StopLossPercent), 1m)
.SetDisplay("Stop Loss, %", "Stop loss level in percent", "Protection");
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
.SetDisplay("Candle Type", "Type of candles for calculations", "Parameters");
}
/// <inheritdoc />
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
{
return [(Security, CandleType)];
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_prev1 = default;
_prev2 = default;
_candleCount = default;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var ma = new ExponentialMovingAverage { Length = MaLength };
var subscription = SubscribeCandles(CandleType);
subscription.Bind(ma, ProcessCandle).Start();
StartProtection(
new Unit(StopLossPercent, UnitTypes.Percent),
new Unit(TakeProfitPercent, UnitTypes.Percent));
}
private void ProcessCandle(ICandleMessage candle, decimal ma)
{
if (candle.State != CandleStates.Finished)
return;
if (!IsFormedAndOnlineAndAllowTrading())
return;
_candleCount++;
if (_candleCount <= 2)
{
_prev2 = _prev1;
_prev1 = ma;
return;
}
var wasRising = _prev1 > _prev2;
var wasFalling = _prev1 < _prev2;
if (wasRising && ma > _prev1 && Position <= 0)
{
if (Position < 0)
BuyMarket();
BuyMarket();
}
else if (wasFalling && ma < _prev1 && Position >= 0)
{
if (Position > 0)
SellMarket();
SellMarket();
}
_prev2 = _prev1;
_prev1 = ma;
}
}
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, Unit, UnitTypes
from StockSharp.Algo.Indicators import ExponentialMovingAverage
from StockSharp.Algo.Strategies import Strategy
class fine_tuning_ma_strategy(Strategy):
def __init__(self):
super(fine_tuning_ma_strategy, self).__init__()
self._ma_length = self.Param("MaLength", 20) \
.SetDisplay("MA Length", "Length of the moving average", "Parameters")
self._take_profit_percent = self.Param("TakeProfitPercent", 1.0) \
.SetDisplay("Take Profit, %", "Take profit level in percent", "Protection")
self._stop_loss_percent = self.Param("StopLossPercent", 1.0) \
.SetDisplay("Stop Loss, %", "Stop loss level in percent", "Protection")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(4))) \
.SetDisplay("Candle Type", "Type of candles for calculations", "Parameters")
self._prev1 = 0.0
self._prev2 = 0.0
self._candle_count = 0
@property
def MaLength(self):
return self._ma_length.Value
@MaLength.setter
def MaLength(self, value):
self._ma_length.Value = value
@property
def TakeProfitPercent(self):
return self._take_profit_percent.Value
@TakeProfitPercent.setter
def TakeProfitPercent(self, value):
self._take_profit_percent.Value = value
@property
def StopLossPercent(self):
return self._stop_loss_percent.Value
@StopLossPercent.setter
def StopLossPercent(self, value):
self._stop_loss_percent.Value = value
@property
def CandleType(self):
return self._candle_type.Value
@CandleType.setter
def CandleType(self, value):
self._candle_type.Value = value
def OnStarted2(self, time):
super(fine_tuning_ma_strategy, self).OnStarted2(time)
ma = ExponentialMovingAverage()
ma.Length = self.MaLength
self.SubscribeCandles(self.CandleType) \
.Bind(ma, self.ProcessCandle) \
.Start()
self.StartProtection(
stopLoss=Unit(self.StopLossPercent, UnitTypes.Percent),
takeProfit=Unit(self.TakeProfitPercent, UnitTypes.Percent)
)
def ProcessCandle(self, candle, ma_value):
if candle.State != CandleStates.Finished:
return
if not self.IsFormedAndOnlineAndAllowTrading():
return
val = float(ma_value)
self._candle_count += 1
if self._candle_count <= 2:
self._prev2 = self._prev1
self._prev1 = val
return
was_rising = self._prev1 > self._prev2
was_falling = self._prev1 < self._prev2
if was_rising and val > self._prev1 and self.Position <= 0:
if self.Position < 0:
self.BuyMarket()
self.BuyMarket()
elif was_falling and val < self._prev1 and self.Position >= 0:
if self.Position > 0:
self.SellMarket()
self.SellMarket()
self._prev2 = self._prev1
self._prev1 = val
def OnReseted(self):
super(fine_tuning_ma_strategy, self).OnReseted()
self._prev1 = 0.0
self._prev2 = 0.0
self._candle_count = 0
def CreateClone(self):
return fine_tuning_ma_strategy()