ゴールド・トレードセットアップ戦略
カウフマン適応移動平均とSuperTrendに基づく戦略。 AMAが上昇しSuperTrendが上昇トレンドに切り替わったときに売ります。 AMAが下降しSuperTrendが下降トレンドに切り替わったときに買います。
詳細
- エントリー条件: AMAの方向とSuperTrendの切り替え。
- ロング/ショート: 両方向。
- エグジット条件: 固定の目標とストップレベル。
- ストップ: はい。
- デフォルト値:
AmaLength= 14FastLength= 2SlowLength= 30AtrPeriod= 10Factor= 3.0TargetMultiplier= 3.0RiskMultiplier= 1.0CandleType= TimeSpan.FromMinutes(5)
- フィルター:
- カテゴリ: トレンド
- 方向: 両方
- インジケーター: KAMA, SuperTrend
- ストップ: はい
- 複雑さ: 中
- 時間軸: イントラデイ (5m)
- 季節性: いいえ
- ニューラルネットワーク: いいえ
- ダイバージェンス: いいえ
- リスクレベル: 中
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()