Gold-Handelsaufbau-Strategie
Strategie basierend auf dem Kaufman Adaptive Moving Average und SuperTrend. Verkauft, wenn AMA steigt und SuperTrend in einen Aufwärtstrend wechselt. Kauft, wenn AMA fällt und SuperTrend in einen Abwärtstrend wechselt.
Details
- Einstiegskriterien: AMA-Richtung mit SuperTrend-Wechsel.
- Long/Short: Beide Richtungen.
- Ausstiegskriterien: Feste Ziel- und Stop-Niveaus.
- Stops: Ja.
- Standardwerte:
AmaLength= 14FastLength= 2SlowLength= 30AtrPeriod= 10Factor= 3.0TargetMultiplier= 3.0RiskMultiplier= 1.0CandleType= TimeSpan.FromMinutes(5)
- Filter:
- Kategorie: Trend
- Richtung: Beide
- Indikatoren: KAMA, SuperTrend
- Stops: Ja
- Komplexität: Mittel
- Zeitrahmen: Intraday (5m)
- 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>
/// Gold trade setup strategy.
/// A Kaufman adaptive moving average (AmaLength, FastLength, SlowLength) gives the direction and a SuperTrend (AtrPeriod, Factor) the
/// flips. When the AMA is rising and the SuperTrend flips to an uptrend the strategy sells; when the AMA is falling and the SuperTrend
/// flips to a downtrend it buys. The target is TargetMultiplier ATRs and the stop RiskMultiplier ATRs from the entry.
/// </summary>
public class GoldTradeSetupStrategy : Strategy
{
private readonly StrategyParam<int> _amaLength;
private readonly StrategyParam<int> _fastLength;
private readonly StrategyParam<int> _slowLength;
private readonly StrategyParam<int> _atrPeriod;
private readonly StrategyParam<decimal> _factor;
private readonly StrategyParam<decimal> _targetMultiplier;
private readonly StrategyParam<decimal> _riskMultiplier;
private readonly StrategyParam<DataType> _candleType;
private decimal? _prevAma;
private bool? _prevUpTrend;
private decimal _stopPrice;
private decimal _takePrice;
/// <summary>
/// AMA efficiency ratio length.
/// </summary>
public int AmaLength
{
get => _amaLength.Value;
set => _amaLength.Value = value;
}
/// <summary>
/// AMA fast smoothing period.
/// </summary>
public int FastLength
{
get => _fastLength.Value;
set => _fastLength.Value = value;
}
/// <summary>
/// AMA slow smoothing period.
/// </summary>
public int SlowLength
{
get => _slowLength.Value;
set => _slowLength.Value = value;
}
/// <summary>
/// ATR period of SuperTrend and the exits.
/// </summary>
public int AtrPeriod
{
get => _atrPeriod.Value;
set => _atrPeriod.Value = value;
}
/// <summary>
/// SuperTrend ATR factor.
/// </summary>
public decimal Factor
{
get => _factor.Value;
set => _factor.Value = value;
}
/// <summary>
/// Target distance in ATRs.
/// </summary>
public decimal TargetMultiplier
{
get => _targetMultiplier.Value;
set => _targetMultiplier.Value = value;
}
/// <summary>
/// Stop distance in ATRs.
/// </summary>
public decimal RiskMultiplier
{
get => _riskMultiplier.Value;
set => _riskMultiplier.Value = value;
}
/// <summary>
/// Candle type.
/// </summary>
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
/// <summary>
/// Constructor.
/// </summary>
public GoldTradeSetupStrategy()
{
_amaLength = Param(nameof(AmaLength), 14)
.SetGreaterThanZero()
.SetDisplay("AMA Length", "AMA efficiency ratio length", "AMA");
_fastLength = Param(nameof(FastLength), 2)
.SetGreaterThanZero()
.SetDisplay("Fast Length", "AMA fast smoothing period", "AMA");
_slowLength = Param(nameof(SlowLength), 30)
.SetGreaterThanZero()
.SetDisplay("Slow Length", "AMA slow smoothing period", "AMA");
_atrPeriod = Param(nameof(AtrPeriod), 10)
.SetGreaterThanZero()
.SetDisplay("ATR Period", "ATR period of SuperTrend and the exits", "SuperTrend");
_factor = Param(nameof(Factor), 3.0m)
.SetGreaterThanZero()
.SetDisplay("Factor", "SuperTrend ATR factor", "SuperTrend");
_targetMultiplier = Param(nameof(TargetMultiplier), 3.0m)
.SetGreaterThanZero()
.SetDisplay("Target Multiplier", "Target distance in ATRs", "Risk");
_riskMultiplier = Param(nameof(RiskMultiplier), 1.0m)
.SetGreaterThanZero()
.SetDisplay("Risk Multiplier", "Stop distance in ATRs", "Risk");
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(5).TimeFrame())
.SetDisplay("Candle Type", "Type of candles to use", "General");
}
/// <inheritdoc />
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
{
return [(Security, CandleType)];
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
ResetState();
}
private void ResetState()
{
_prevAma = null;
_prevUpTrend = null;
_stopPrice = 0m;
_takePrice = 0m;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
ResetState();
var ama = new KaufmanAdaptiveMovingAverage
{
Length = AmaLength,
FastSCPeriod = FastLength,
SlowSCPeriod = SlowLength,
};
var superTrend = new SuperTrend { Length = AtrPeriod, Multiplier = Factor };
var atr = new AverageTrueRange { Length = AtrPeriod };
var subscription = SubscribeCandles(CandleType);
subscription
.BindEx(ama, superTrend, atr, ProcessCandle)
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, ama);
DrawIndicator(area, superTrend);
DrawOwnTrades(area);
}
}
private void ProcessCandle(ICandleMessage candle, IIndicatorValue amaValue, IIndicatorValue superTrendValue, IIndicatorValue atrValue)
{
if (candle.State != CandleStates.Finished)
return;
if (!amaValue.IsFormed || !superTrendValue.IsFormed || !atrValue.IsFormed || superTrendValue is not SuperTrendIndicatorValue st)
return;
var ama = amaValue.GetValue<decimal>();
var upTrend = st.IsUpTrend;
var prevAma = _prevAma;
var prevUpTrend = _prevUpTrend;
_prevAma = ama;
_prevUpTrend = upTrend;
if (ManagePosition(candle))
return;
if (prevAma is not decimal pa || prevUpTrend is not bool pu)
return;
if (!IsFormedAndOnlineAndAllowTrading() || Position != 0)
return;
var atr = atrValue.GetValue<decimal>();
var close = candle.ClosePrice;
if (ama > pa && upTrend && !pu)
{
SellMarket(Volume);
_stopPrice = close + atr * RiskMultiplier;
_takePrice = close - atr * TargetMultiplier;
}
else if (ama < pa && !upTrend && pu)
{
BuyMarket(Volume);
_stopPrice = close - atr * RiskMultiplier;
_takePrice = close + atr * TargetMultiplier;
}
}
// Returns true when the position was closed on this candle.
private bool ManagePosition(ICandleMessage candle)
{
if (Position > 0 && _takePrice > 0)
{
if (candle.LowPrice <= _stopPrice || candle.HighPrice >= _takePrice)
{
SellMarket(Position);
return true;
}
}
else if (Position < 0 && _stopPrice > 0)
{
if (candle.HighPrice >= _stopPrice || candle.LowPrice <= _takePrice)
{
BuyMarket(Math.Abs(Position));
return true;
}
}
return false;
}
}
import clr
clr.AddReference("StockSharp.Messages")
clr.AddReference("StockSharp.Algo")
clr.AddReference("StockSharp.Algo.Indicators")
clr.AddReference("StockSharp.Algo.Strategies")
from System import TimeSpan, Decimal
from StockSharp.Messages import DataType, CandleStates
from StockSharp.Algo.Indicators import KaufmanAdaptiveMovingAverage, SuperTrend, AverageTrueRange
from StockSharp.Algo.Strategies import Strategy
class gold_trade_setup_strategy(Strategy):
"""
Gold trade setup strategy.
A Kaufman adaptive moving average (AmaLength, FastLength, SlowLength) gives the direction and a SuperTrend (AtrPeriod, Factor) the
flips. When the AMA is rising and the SuperTrend flips to an uptrend the strategy sells; when the AMA is falling and the SuperTrend
flips to a downtrend it buys. The target is TargetMultiplier ATRs and the stop RiskMultiplier ATRs from the entry.
"""
def __init__(self):
super(gold_trade_setup_strategy, self).__init__()
self._ama_length = self.Param("AmaLength", 14).SetGreaterThanZero().SetDisplay("AMA Length", "AMA efficiency ratio length", "AMA")
self._fast_length = self.Param("FastLength", 2).SetGreaterThanZero().SetDisplay("Fast Length", "AMA fast smoothing period", "AMA")
self._slow_length = self.Param("SlowLength", 30).SetGreaterThanZero().SetDisplay("Slow Length", "AMA slow smoothing period", "AMA")
self._atr_period = self.Param("AtrPeriod", 10).SetGreaterThanZero().SetDisplay("ATR Period", "ATR period of SuperTrend and the exits", "SuperTrend")
self._factor = self.Param("Factor", 3.0).SetGreaterThanZero().SetDisplay("Factor", "SuperTrend ATR factor", "SuperTrend")
self._target_multiplier = self.Param("TargetMultiplier", 3.0).SetGreaterThanZero().SetDisplay("Target Multiplier", "Target distance in ATRs", "Risk")
self._risk_multiplier = self.Param("RiskMultiplier", 1.0).SetGreaterThanZero().SetDisplay("Risk Multiplier", "Stop distance in ATRs", "Risk")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(5))).SetDisplay("Candle Type", "Type of candles to use", "General")
self._reset_state()
@property
def candle_type(self):
return self._candle_type.Value
def _reset_state(self):
self._prev_ama = None
self._prev_up_trend = None
self._stop_price = Decimal(0)
self._take_price = Decimal(0)
def OnReseted(self):
super(gold_trade_setup_strategy, self).OnReseted()
self._reset_state()
def OnStarted2(self, time):
super(gold_trade_setup_strategy, self).OnStarted2(time)
self._reset_state()
ama = KaufmanAdaptiveMovingAverage()
ama.Length = self._ama_length.Value
ama.FastSCPeriod = self._fast_length.Value
ama.SlowSCPeriod = self._slow_length.Value
super_trend = SuperTrend()
super_trend.Length = self._atr_period.Value
super_trend.Multiplier = Decimal(self._factor.Value)
atr = AverageTrueRange()
atr.Length = self._atr_period.Value
subscription = self.SubscribeCandles(self.candle_type)
subscription.BindEx(ama, super_trend, atr, self._process_candle).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawIndicator(area, ama)
self.DrawIndicator(area, super_trend)
self.DrawOwnTrades(area)
def _process_candle(self, candle, ama_value, super_trend_value, atr_value):
if candle.State != CandleStates.Finished:
return
if not ama_value.IsFormed or not super_trend_value.IsFormed or not atr_value.IsFormed:
return
ama = ama_value.GetValue[Decimal](None)
up_trend = bool(super_trend_value.IsUpTrend)
prev_ama = self._prev_ama
prev_up_trend = self._prev_up_trend
self._prev_ama = ama
self._prev_up_trend = up_trend
if self._manage_position(candle):
return
if prev_ama is None or prev_up_trend is None:
return
if not self.IsFormedAndOnlineAndAllowTrading() or self.Position != 0:
return
atr = atr_value.GetValue[Decimal](None)
close = candle.ClosePrice
risk = Decimal(self._risk_multiplier.Value)
target = Decimal(self._target_multiplier.Value)
if ama > prev_ama and up_trend and not prev_up_trend:
self.SellMarket(self.Volume)
self._stop_price = close + atr * risk
self._take_price = close - atr * target
elif ama < prev_ama and not up_trend and prev_up_trend:
self.BuyMarket(self.Volume)
self._stop_price = close - atr * risk
self._take_price = close + atr * target
def _manage_position(self, candle):
if self.Position > 0 and self._take_price > 0:
if candle.LowPrice <= self._stop_price or candle.HighPrice >= self._take_price:
self.SellMarket(self.Position)
return True
elif self.Position < 0 and self._stop_price > 0:
if candle.HighPrice >= self._stop_price or candle.LowPrice <= self._take_price:
self.BuyMarket(abs(self.Position))
return True
return False
def CreateClone(self):
return gold_trade_setup_strategy()