ホーム
/
戦略のサンプル
GitHub で見る
MA S.R.取引戦略
MA S.R.取引戦略は、オリジナルの MetaTrader アドバイザー「MA S.R Trading」から変換されたトレンド反転システムです。短い単純移動平均 (SMA) の形状を監視し、価格の勢いが局所的な上限または下限に変化する時期を検出します。 SMA がピークまたは谷になると、戦略は直ちにターンの方向に入り、直近のスイングに固定されたストップレベルでポジションを保護します。
長さの異なる複数の移動平均を比較する古典的なクロスオーバー システムとは異なり、このアプローチでは、最も最近完了した 3 つのローソク足の値を比較することによって、同じ SMA の曲率を分析します。極大値(SMA[t-1] と SMA[t-3] の両方より大きい SMA[t-2])は弱気反転のシグナルとなり、ショートエントリーをトリガーします。極小値 (両方の隣接値の下にある SMA[t-2]) は強気の反転を示し、ロングポジションをオープンします。シグナルの直後、この戦略は設定可能なルックバック ウィンドウにわたって極端な価格を保存し、それを保護ストップとして使用します。
終了ロジックは、MQL ソースからの末尾の変更を模倣します。ショートトレードの場合、ストップは、このレベルが前の終値を上回っている限り、ルックバックウィンドウ内の最高値に設定されます(そうでない場合、レベルは無視されます)。ロングポジションは同じルールに基づいて最安値を使用します。価格が後続のローソク足で保存されたレベルに達すると、この戦略は市場でのポジションをクローズし、元のエキスパートからのストップロスの更新を効果的にエミュレートします。
このシステムは、日中チャートから短期チャートで顕著なスイング動作を示す商品向けに設計されています。 SMA の短い期間 (デフォルト = 5) により、アルゴリズムは微細構造の変化に迅速に反応できます。一方、ストップ ルックバック (デフォルト = 高値と安値の両方で 5 バー) は、トレーリングレベルがどれだけ積極的に価格に追随するかを制御します。スキャルピング環境には狭いウィンドウを使用し、騒々しい市場には広い設定を使用します。
FXメジャーと流動性インデックスCFDのバックテストは、頻繁に変動するレンジ期間中に最高のパフォーマンスを示します。スムーズな下落を伴うトレンドでは、早期の反転を避けるために追加のフィルターやボラティリティの確認が必要になる場合があります。ライブで展開する場合は、戦略をより広範な市場コンテキストまたは時間フィルターと組み合わせるように検討してください。
詳細
エントリー条件
短い : SMA[t-1] < SMA[t-2] と SMA[t-3] < SMA[t-2]。最後に完成した SMA サンプルが極大値を形成します。
長い : SMA[t-1] > SMA[t-2] および SMA[t-3] > SMA[t-2]。最後に完成した SMA サンプルが極小値を形成します。
管理を停止
ショート : ストップレベル = レベルが前の終値を上回っている場合、HighLookback ローソク足以内の最高値。価格がそのレベルに達すると終了します。
ロング : ストップレベル = レベルが前の終値を下回っている場合、LowLookback ローソク足以内の最低安値。価格がそのレベルに達すると終了します。
ポジション ルール : 常に最新の信号に切り替わります。反転する場合、この戦略は既存のポジションをクローズし、前のエクスポージャーと希望のボリュームをカバーするサイズの単一成行注文で新しいポジションをオープンします。
デフォルトのパラメータ
SmaPeriod = 5。
HighLookback = 5。
LowLookback = 5。
CandleType = 30 分の時間枠。
TradeVolume = 1 ロット (開始時に Volume プロパティに適用されます)。
フィルター
カテゴリー: 逆転。
方向性:ロングとショートの両方。
インジケーター: 単純移動平均、最高/最低スイング トラッカー。
ストップ: ダイナミック、スイングベース。
時間枠: 日中からスイングまで。
複雑さ: 中。
リスクレベル:中程度(ストップは狭いが取引は頻繁)。
使用上の注意
目に見える振動がある機器で最も効果的です。誤った変動を避けるために、主要なニュースイベントの前後の取引を無効にすることを検討してください。
ターゲットのシンボルとタイムフレームの SMA 期間とルックバック ウィンドウを最適化します。設定を小さくすると感度が上がりますが、ホイップソーも上がります。
停止レベルは、新しい方向指示器が表示された場合にのみ再計算されます。ストップが無効になった場合(たとえば、前の終値を超えていない高値)、ストップは破棄され、戦略が価格に近すぎる保護レベルを設定するのを防ぎます。
エグジットは成行注文に依存しているため、速い動きではスリッページが発生する可能性があります。会場がサポートしている場合は、ブローカー側の保護命令と組み合わせてください。
この戦略は利益確定ターゲットを使用しません。それらを追加するには、追加の条件を使用して ProcessCandle のロジックを拡張します。
using System;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
public class MaSrTradingStrategy : Strategy
{
private readonly StrategyParam<int> _emaPeriod;
private readonly StrategyParam<int> _momentumPeriod;
private readonly StrategyParam<DataType> _candleType;
private decimal _prevClose; private decimal _prevEma; private bool _hasPrev;
private int _cooldown;
public int EmaPeriod { get => _emaPeriod.Value; set => _emaPeriod.Value = value; }
public int MomentumPeriod { get => _momentumPeriod.Value; set => _momentumPeriod.Value = value; }
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public MaSrTradingStrategy()
{
_emaPeriod = Param(nameof(EmaPeriod), 20).SetDisplay("EMA Period", "EMA lookback", "Indicators");
_momentumPeriod = Param(nameof(MomentumPeriod), 14).SetDisplay("Momentum", "Momentum period", "Indicators");
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(30).TimeFrame()).SetDisplay("Candle Type", "Candle timeframe", "General");
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_prevClose = default;
_prevEma = default;
_hasPrev = default;
_cooldown = default;
}
/// <inheritdoc />
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_hasPrev = false;
var ema = new ExponentialMovingAverage { Length = EmaPeriod };
var subscription = SubscribeCandles(CandleType);
subscription.Bind(ema, ProcessCandle).Start();
}
private void ProcessCandle(ICandleMessage candle, decimal ema)
{
if (candle.State != CandleStates.Finished) return;
if (!IsFormedAndOnlineAndAllowTrading()) return;
var close = candle.ClosePrice;
if (!_hasPrev) { _prevClose = close; _prevEma = ema; _hasPrev = true; return; }
if (_cooldown > 0)
{
_cooldown--;
_prevClose = close; _prevEma = ema;
return;
}
if (_prevClose <= _prevEma && close > ema && Position <= 0)
{
var volume = Volume + Math.Abs(Position);
BuyMarket(volume);
_cooldown = 6;
}
else if (_prevClose >= _prevEma && close < ema && Position >= 0)
{
var volume = Volume + Math.Abs(Position);
SellMarket(volume);
_cooldown = 6;
}
_prevClose = close; _prevEma = ema;
}
}
import clr
clr.AddReference("StockSharp.Messages")
clr.AddReference("StockSharp.Algo")
clr.AddReference("StockSharp.Algo.Indicators")
clr.AddReference("StockSharp.Algo.Strategies")
from System import TimeSpan, Math
from StockSharp.Messages import DataType, CandleStates
from StockSharp.Algo.Indicators import ExponentialMovingAverage
from StockSharp.Algo.Strategies import Strategy
class ma_sr_trading_strategy(Strategy):
def __init__(self):
super(ma_sr_trading_strategy, self).__init__()
self._ema_period = self.Param("EmaPeriod", 20).SetDisplay("EMA Period", "EMA lookback", "Indicators")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(30))).SetDisplay("Candle Type", "Candle timeframe", "General")
self._prev_close = 0.0; self._prev_ema = 0.0; self._has_prev = False; self._cooldown = 0
@property
def ema_period(self): return self._ema_period.Value
@property
def candle_type(self): return self._candle_type.Value
def OnReseted(self):
super(ma_sr_trading_strategy, self).OnReseted()
self._prev_close = 0.0; self._prev_ema = 0.0; self._has_prev = False; self._cooldown = 0
def OnStarted2(self, time):
super(ma_sr_trading_strategy, self).OnStarted2(time)
self._has_prev = False; self._cooldown = 0
ema = ExponentialMovingAverage(); ema.Length = self.ema_period
subscription = self.SubscribeCandles(self.candle_type)
subscription.Bind(ema, self.process_candle).Start()
def process_candle(self, candle, ema):
if candle.State != CandleStates.Finished: return
if not self.IsFormedAndOnlineAndAllowTrading(): return
close = float(candle.ClosePrice); ema_val = float(ema)
if not self._has_prev:
self._prev_close = close; self._prev_ema = ema_val; self._has_prev = True; return
if self._cooldown > 0:
self._cooldown -= 1; self._prev_close = close; self._prev_ema = ema_val; return
if self._prev_close <= self._prev_ema and close > ema_val and self.Position <= 0:
volume = self.Volume + abs(self.Position)
self.BuyMarket(volume); self._cooldown = 6
elif self._prev_close >= self._prev_ema and close < ema_val and self.Position >= 0:
volume = self.Volume + abs(self.Position)
self.SellMarket(volume); self._cooldown = 6
self._prev_close = close; self._prev_ema = ema_val
def CreateClone(self): return ma_sr_trading_strategy()