Die Strategie verwendet den Modified Moving Average (AMMA)-Indikator, um kurzfristige Trendwechsel zu erfassen. Sie analysiert die Richtung der AMMA-Steigung bei den letzten Kerzen und öffnet eine Position in Richtung des aufkommenden Trends, während die entgegengesetzte geschlossen wird.
Funktionsweise
Ein ModifiedMovingAverage mit einer konfigurierbaren Periode wird auf dem ausgewählten Zeitrahmen berechnet.
Bei jeder abgeschlossenen Kerze vergleicht die Strategie die letzten drei AMMA-Werte.
Wenn die Indikatorwerte eine aufsteigende Folge bilden und der neueste Wert größer als der vorherige ist, wird eine Long-Position eröffnet. Jede Short-Position wird geschlossen.
Wenn die Indikatorwerte eine absteigende Folge bilden und der neueste Wert kleiner als der vorherige ist, wird eine Short-Position eröffnet. Jede Long-Position wird geschlossen.
Parameter
CandleType – Zeitrahmen der für Berechnungen verwendeten Kerzen.
MaPeriod – Periode des modifizierten gleitenden Durchschnitts.
AllowLongEntry – Öffnen von Long-Positionen aktivieren.
AllowShortEntry – Öffnen von Short-Positionen aktivieren.
AllowLongExit – Schließen von Long-Positionen aktivieren.
AllowShortExit – Schließen von Short-Positionen aktivieren.
Hinweise
Die Strategie arbeitet nur auf abgeschlossenen Kerzen und verwendet die integrierten BuyMarket- und SellMarket-Methoden für die Orderausführung. Risikomanagement-Funktionen können extern über die Standard-Strategy-Eigenschaften hinzugefügt werden.
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>
/// AMMA Trend strategy using Modified Moving Average direction changes.
/// Buys when MMA turns up, sells when MMA turns down.
/// </summary>
public class AmmaTrendStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _maPeriod;
private decimal? _mma0;
private decimal? _mma1;
private decimal? _mma2;
private decimal? _mma3;
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public int MaPeriod { get => _maPeriod.Value; set => _maPeriod.Value = value; }
public AmmaTrendStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
.SetDisplay("Candle Type", "Type of candles to use for analysis", "General");
_maPeriod = Param(nameof(MaPeriod), 25)
.SetGreaterThanZero()
.SetDisplay("AMMA Period", "Period of the modified moving average", "Indicator");
}
/// <inheritdoc />
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
{
return [(Security, CandleType)];
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_mma0 = _mma1 = _mma2 = _mma3 = null;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var mma = new SmoothedMovingAverage { Length = MaPeriod };
var subscription = SubscribeCandles(CandleType);
subscription.Bind(mma, ProcessCandle).Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, mma);
DrawOwnTrades(area);
}
}
private void ProcessCandle(ICandleMessage candle, decimal mmaValue)
{
if (candle.State != CandleStates.Finished)
return;
_mma3 = _mma2;
_mma2 = _mma1;
_mma1 = _mma0;
_mma0 = mmaValue;
if (_mma1 is null || _mma2 is null || _mma3 is null)
return;
// Upward movement detected: MMA turned from falling to rising
if (_mma2 < _mma3 && _mma1 > _mma2 && Position <= 0)
{
if (Position < 0) BuyMarket();
BuyMarket();
}
// Downward movement detected: MMA turned from rising to falling
else if (_mma2 > _mma3 && _mma1 < _mma2 && 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 SmoothedMovingAverage
from StockSharp.Algo.Strategies import Strategy
class amma_trend_strategy(Strategy):
def __init__(self):
super(amma_trend_strategy, self).__init__()
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(4))) \
.SetDisplay("Candle Type", "Type of candles to use for analysis", "General")
self._ma_period = self.Param("MaPeriod", 25) \
.SetDisplay("AMMA Period", "Period of the modified moving average", "Indicator")
self._mma0 = None
self._mma1 = None
self._mma2 = None
self._mma3 = None
@property
def CandleType(self):
return self._candle_type.Value
@CandleType.setter
def CandleType(self, value):
self._candle_type.Value = value
@property
def MaPeriod(self):
return self._ma_period.Value
@MaPeriod.setter
def MaPeriod(self, value):
self._ma_period.Value = value
def OnStarted2(self, time):
super(amma_trend_strategy, self).OnStarted2(time)
self._mma0 = None
self._mma1 = None
self._mma2 = None
self._mma3 = None
mma = SmoothedMovingAverage()
mma.Length = self.MaPeriod
self.SubscribeCandles(self.CandleType) \
.Bind(mma, self.ProcessCandle) \
.Start()
def ProcessCandle(self, candle, mma_val):
if candle.State != CandleStates.Finished:
return
mma_f = float(mma_val)
self._mma3 = self._mma2
self._mma2 = self._mma1
self._mma1 = self._mma0
self._mma0 = mma_f
if self._mma1 is None or self._mma2 is None or self._mma3 is None:
return
if self._mma2 < self._mma3 and self._mma1 > self._mma2 and self.Position <= 0:
if self.Position < 0:
self.BuyMarket()
self.BuyMarket()
elif self._mma2 > self._mma3 and self._mma1 < self._mma2 and self.Position >= 0:
if self.Position > 0:
self.SellMarket()
self.SellMarket()
def OnReseted(self):
super(amma_trend_strategy, self).OnReseted()
self._mma0 = None
self._mma1 = None
self._mma2 = None
self._mma3 = None
def CreateClone(self):
return amma_trend_strategy()