ホーム
/
戦略のサンプル
GitHub で見る
4 SMA 戦略
概要
4 SMA 戦略は、MetaTrader エキスパート アドバイザ 4 SMA.mq4 を複製します。中央価格で計算された 30 分足のローソク足で動作し、4 つの単純移動平均 (5、20、40、60 期間) を比較して勢いのブレイクアウトを検出します。 StockSharp ポートは、元のコードの単一ポジションの動作を維持し、市場参入とリスク管理に高レベルの API ヘルパーを使用します。
取引ロジック
完成した各ローソクの中央価格 (high + low) / 2 を計算し、それを 4 つの SMA に供給します。
ロングエントリー は、速い SMA が中程度の SMA を上回り、中程度の SMA が遅い SMA を上回り、遅い SMA が非常に遅い SMA を少なくとも 1 価格ステップ上回っており、前の遅い SMA が非常に遅い SMA 以下である場合に発生します。一度にアクティブにできるロングポジションは 1 つだけです。
ショートエントリー はミラー条件です。速いSMAは中程度のSMAを下回り、中くらいのSMAは遅いSMAを下回っています。非常に遅いSMAは遅いSMAを少なくとも1価格ステップ上回っており、前の遅いSMAは非常に遅いSMA以上でした。一度にアクティブにできるショートポジションは 1 つだけです。
ポジション管理
この戦略は、遅い SMA が非常に遅い SMA を下抜けたときにロングを閉じ、遅い SMA が非常に遅い SMA を超えたときにショートを閉じます。
保護レベルは各エントリ後に事前に計算されます。ストップロスとテイクプロフィットの距離は元のポイントベースの設定に従い、証券価格ステップに依存します。
設定されたトレーリング距離を超えて価格が変動すると、トレーリングストップが有効になります。ストップはローソクごとに追従され、緩むことはありません。
パラメーター
名前
説明
デフォルト
キャンドルの種類
計算に使用されるローソク足シリーズ (デフォルトでは 30 分)。
M30 の時間枠
テイクプロフィット
テイクプロフィット距離(ポイント単位)。
50
ストップロス
ポイント単位のストップロス距離。
50
トレーリングストップ
トレーリングストップの距離 (ポイント単位)。
11
速い長さ
高速 SMA の長さ。
5
中程度の長さ
メディアの長さ SMA。
20
遅い長さ
低速の SMA の長さ。
40
非常に遅い長さ
非常に遅い SMA の長さ。
60
すべての数値パラメータは、StockSharp パラメータ UI を介して最適化のために公開されます。
MQL バージョンとの違い
元のトレーリング ストップは MT4 注文を直接操作しました。ポートはエグジット価格を再計算し、レベルを突破すると成行注文を発行します。
価格ステップを意識した計算により、外国為替以外のティック サイズの商品でも戦略を動作させることができます。
StockSharp の実装は、高レベルの SubscribeCandles バインディングと戦略パラメータに依存しており、フレームワークのベスト プラクティスに準拠しています。
using System;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
public class FourSmaStrategy : Strategy
{
private readonly StrategyParam<int> _fastPeriod;
private readonly StrategyParam<int> _slowPeriod;
private readonly StrategyParam<int> _cooldownCandles;
private readonly StrategyParam<DataType> _candleType;
private decimal _prevFast;
private decimal _prevSlow;
private bool _hasPrev;
private int _cooldownRemaining;
public int FastPeriod { get => _fastPeriod.Value; set => _fastPeriod.Value = value; }
public int SlowPeriod { get => _slowPeriod.Value; set => _slowPeriod.Value = value; }
public int CooldownCandles { get => _cooldownCandles.Value; set => _cooldownCandles.Value = value; }
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public FourSmaStrategy()
{
_fastPeriod = Param(nameof(FastPeriod), 20).SetDisplay("Fast EMA", "Fast EMA period", "Indicators");
_slowPeriod = Param(nameof(SlowPeriod), 80).SetDisplay("Slow EMA", "Slow EMA period", "Indicators");
_cooldownCandles = Param(nameof(CooldownCandles), 100).SetDisplay("Cooldown", "Candles between signals", "General");
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(5).TimeFrame()).SetDisplay("Candle Type", "Candle timeframe", "General");
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_prevFast = default;
_prevSlow = default;
_hasPrev = default;
_cooldownRemaining = default;
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_prevFast = 0;
_prevSlow = 0;
_hasPrev = false;
_cooldownRemaining = 0;
var fast = new ExponentialMovingAverage { Length = FastPeriod };
var slow = new ExponentialMovingAverage { Length = SlowPeriod };
var subscription = SubscribeCandles(CandleType);
subscription.Bind(fast, slow, ProcessCandle).Start();
}
private void ProcessCandle(ICandleMessage candle, decimal fast, decimal slow)
{
if (candle.State != CandleStates.Finished) return;
if (!_hasPrev) { _prevFast = fast; _prevSlow = slow; _hasPrev = true; return; }
if (_cooldownRemaining > 0)
{
_cooldownRemaining--;
_prevFast = fast;
_prevSlow = slow;
return;
}
if (_prevFast <= _prevSlow && fast > slow && Position <= 0)
{
if (Position < 0) BuyMarket();
BuyMarket();
_cooldownRemaining = CooldownCandles;
}
else if (_prevFast >= _prevSlow && fast < slow && Position >= 0)
{
if (Position > 0) SellMarket();
SellMarket();
_cooldownRemaining = CooldownCandles;
}
_prevFast = fast;
_prevSlow = slow;
}
}
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 four_sma_strategy(Strategy):
def __init__(self):
super(four_sma_strategy, self).__init__()
self._fast_period = self.Param("FastPeriod", 20).SetDisplay("Fast EMA", "Fast EMA period", "Indicators")
self._slow_period = self.Param("SlowPeriod", 80).SetDisplay("Slow EMA", "Slow EMA period", "Indicators")
self._cooldown_candles = self.Param("CooldownCandles", 100).SetDisplay("Cooldown", "Candles between signals", "General")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(5))).SetDisplay("Candle Type", "Candle timeframe", "General")
self._prev_fast = 0.0
self._prev_slow = 0.0
self._has_prev = False
self._cooldown_remaining = 0
@property
def fast_period(self): return self._fast_period.Value
@property
def slow_period(self): return self._slow_period.Value
@property
def cooldown_candles(self): return self._cooldown_candles.Value
@property
def candle_type(self): return self._candle_type.Value
def OnReseted(self):
super(four_sma_strategy, self).OnReseted()
self._prev_fast = 0.0
self._prev_slow = 0.0
self._has_prev = False
self._cooldown_remaining = 0
def OnStarted2(self, time):
super(four_sma_strategy, self).OnStarted2(time)
self._prev_fast = 0.0
self._prev_slow = 0.0
self._has_prev = False
self._cooldown_remaining = 0
fast = ExponentialMovingAverage()
fast.Length = self.fast_period
slow = ExponentialMovingAverage()
slow.Length = self.slow_period
subscription = self.SubscribeCandles(self.candle_type)
subscription.Bind(fast, slow, self.process_candle).Start()
def process_candle(self, candle, fast, slow):
if candle.State != CandleStates.Finished:
return
fast_val = float(fast)
slow_val = float(slow)
if not self._has_prev:
self._prev_fast = fast_val
self._prev_slow = slow_val
self._has_prev = True
return
if self._cooldown_remaining > 0:
self._cooldown_remaining -= 1
self._prev_fast = fast_val
self._prev_slow = slow_val
return
if self._prev_fast <= self._prev_slow and fast_val > slow_val and self.Position <= 0:
if self.Position < 0:
self.BuyMarket()
self.BuyMarket()
self._cooldown_remaining = self.cooldown_candles
elif self._prev_fast >= self._prev_slow and fast_val < slow_val and self.Position >= 0:
if self.Position > 0:
self.SellMarket()
self.SellMarket()
self._cooldown_remaining = self.cooldown_candles
self._prev_fast = fast_val
self._prev_slow = slow_val
def CreateClone(self):
return four_sma_strategy()