Xit 三重 MA クロスストラテジー
このストラテジーは MetaTrader 5 エキスパートアドバイザー XIT_THREE_MA_CROSS.mq5 の StockSharp 再現です。3本の移動平均を整列させ、MACD モメンタムの乖離を確認し、ATR ベースのリスク制限からポジションをサイジングします。この手法はモメンタム確認を伴うトレンドフォローであり、流動性の高い通貨ペアまたは指数での中期スイングを狙います。
概要
- マーケットレジーム: 選択した時間軸で複数のローソク足にわたってトレンドする銘柄に最も適しています。
- インジケーター:
- 取引時間軸で評価される低速、中間、高速の移動平均(ユーザー選択可能なタイプ)。
- モメンタム方向と MACD ラインとシグナルラインの間の距離のための MACD(EMA ベース)。
- ストップロスとテイクプロフィットの距離を投影するために使用される2つの ATR 計算(同じ長さ、独立した時間軸)。
- 注文方向: 双方向。エンジンはロングとショートの両方の取引を開くことができます。
- ポジションサイジング: 設定されたリスクパーセントと ATR ベースのストップ距離から計算されます。インストゥルメントのメタデータが不完全な場合、ストラテジーはデフォルトの
Volume プロパティにフォールバックします。
トレーディングロジック
ロングエントリー
以下のすべての条件が完成したローソク足で真の場合にロングポジションが開かれます:
- MACD ラインが前のバーと比較して増加する(
MACD[t] > MACD[t-1])。
- MACD シグナルラインが前のバーと比較して増加する。
- MACD ラインがシグナルラインを少なくとも
MacdTriggerPoints * PriceStep 超える。
- 中間移動平均が前の値に対して上昇する。
- 高速移動平均が前の値に対して上昇する。
- 中間 MA が低速 MA の上にある。
- 高速 MA が中間 MA の上にある。
- 両方の ATR 値がストップと目標距離を定義するために利用可能である。
ショートエントリー
ショートサイドのルールは反転した比較でロング設定を反映します:
- MACD ラインが前のバーと比較して減少する。
- MACD シグナルラインが前のバーと比較して減少する。
- シグナルラインが MACD ラインより少なくとも
MacdTriggerPoints * PriceStep 大きい。
- 中間 MA が前のローソク足と比較して下落する。
- 高速 MA が前のローソク足と比較して下落する。
- 中間 MA が低速 MA の下にある。
- 高速 MA が中間 MA の下にある。
- 両方の ATR シリーズが完成した値を提供した。
エグジットロジック
- ロングポジションは高速 MA が中間 MA を下回るか、価格が ATR ベースのストップ/テイクプロフィットレベルに達したときにクローズされます。
- ショートポジションは高速 MA が中間 MA を上抜けするか、ATR の制限に触れたときにクローズされます。
- ポジションをクローズした後、アルゴリズムは新しいエントリーを評価する前に次のローソク足を待ち、元の EA の動作に一致します。
リスク管理
- ストップロス: 距離は
AtrStopCandleType の最新の ATR 値に等しい。ロングのストップ価格は Entry - ATR、ショートは Entry + ATR。
- テイクプロフィット: 距離は
AtrTakeCandleType の ATR 値に等しい。ターゲットはエントリー価格に対して反転されます。
- リスクパーセント: ストラテジーはストップ距離からユニットあたりの金銭的損失を推定します。
PriceStep と PriceStepCost が既知の場合、契約あたりのリスクはティック評価を使用します。そうでなければ、生の価格距離が使用されます。ポジションサイズは現在のポートフォリオ価値の RiskPercent% をユニットあたりのリスクで割り、最も近い VolumeStep に切り捨てたものです。
パラメーター
| 名前 |
説明 |
デフォルト |
CandleType |
移動平均と MACD 計算の主要時間軸。 |
1時間ローソク足 |
SlowMaLength / IntermediateMaLength / FastMaLength |
移動平均の期間。 |
60 / 14 / 4 |
SlowMaType, IntermediateMaType, FastMaType |
移動平均ファミリー(単純、指数、平滑化、加重)。 |
単純 |
MacdFastLength, MacdSlowLength, MacdSignalLength |
MACD 高速、低速、シグナル EMA の長さ。 |
12 / 26 / 9 |
MacdTriggerPoints |
MACD とそのシグナルの間の最小距離、インストゥルメントポイントで測定。PriceStep を使用して変換。 |
7 |
AtrLength |
両方の ATR インジケーターの期間。 |
14 |
AtrTakeCandleType / AtrStopCandleType |
テイクプロフィットとストップロス ATR シリーズの時間軸。 |
4時間ローソク足 |
RiskPercent |
各取引でリスクにさらされる現在のポートフォリオ価値のパーセント。 |
10% |
使用上の注意
- 正確な
PriceStep、PriceStepCost、VolumeStep を持つ証券にストラテジーをアタッチして、正確なポジションサイジングを得ます。
- サブスクライブされた各時間軸(
CandleType、AtrTakeCandleType、AtrStopCandleType)に対して過去データが利用可能であることを確認します。ATR 値が欠けていると、エントリーが延期されます。
- アルゴリズムは完全に閉じたローソク足で動作し、イントラバーの変動を無視し、現在と前のインジケーターバッファを取得する元の MetaTrader ロジックを反映します。
- ターゲット市場がより滑らかなまたはより速いフィルターを好む場合は、移動平均タイプを変更してください。
ファイル
CS/XitThreeMaCrossStrategy.cs – ATR サブスクリプションとリスクサイジングを含む StockSharp 高レベル API を使用した C# 実装。
README_ru.md – ストラテジーのロシア語説明。
README_zh.md – ドキュメントの中国語翻訳。
using System;
using System.Collections.Generic;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
/// <summary>
/// Triple MA alignment strategy.
/// </summary>
public class XitThreeMaCrossStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _fastPeriod;
private readonly StrategyParam<int> _midPeriod;
private readonly StrategyParam<int> _slowPeriod;
private decimal? _prevFast;
private decimal? _prevMid;
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
public int FastPeriod
{
get => _fastPeriod.Value;
set => _fastPeriod.Value = value;
}
public int MidPeriod
{
get => _midPeriod.Value;
set => _midPeriod.Value = value;
}
public int SlowPeriod
{
get => _slowPeriod.Value;
set => _slowPeriod.Value = value;
}
public XitThreeMaCrossStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(1).TimeFrame())
.SetDisplay("Candle Type", "Timeframe", "General");
_fastPeriod = Param(nameof(FastPeriod), 5)
.SetGreaterThanZero()
.SetDisplay("Fast Period", "Fast MA period", "Indicators");
_midPeriod = Param(nameof(MidPeriod), 20)
.SetGreaterThanZero()
.SetDisplay("Mid Period", "Medium MA period", "Indicators");
_slowPeriod = Param(nameof(SlowPeriod), 50)
.SetGreaterThanZero()
.SetDisplay("Slow Period", "Slow MA (trend filter)", "Indicators");
Volume = 0.1m;
}
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
{
return [(Security, CandleType)];
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_prevFast = null;
_prevMid = null;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_prevFast = null;
_prevMid = null;
var fast = new SimpleMovingAverage { Length = FastPeriod };
var mid = new SimpleMovingAverage { Length = MidPeriod };
var slow = new SimpleMovingAverage { Length = SlowPeriod };
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(fast, mid, slow, ProcessCandle)
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, fast);
DrawIndicator(area, mid);
DrawIndicator(area, slow);
DrawOwnTrades(area);
}
}
private void ProcessCandle(ICandleMessage candle, decimal fastVal, decimal midVal, decimal slowVal)
{
if (candle.State != CandleStates.Finished)
return;
if (_prevFast == null || _prevMid == null)
{
_prevFast = fastVal;
_prevMid = midVal;
return;
}
var buySignal = fastVal > midVal && midVal > slowVal;
var sellSignal = fastVal < midVal && midVal < slowVal;
if (buySignal && Position <= 0)
{
if (Position < 0)
BuyMarket(Math.Abs(Position));
BuyMarket(Volume);
}
else if (sellSignal && Position >= 0)
{
if (Position > 0)
SellMarket(Position);
SellMarket(Volume);
}
_prevFast = fastVal;
_prevMid = midVal;
}
}
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 SimpleMovingAverage
from StockSharp.Algo.Strategies import Strategy
class xit_three_ma_cross_strategy(Strategy):
def __init__(self):
super(xit_three_ma_cross_strategy, self).__init__()
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(1))) \
.SetDisplay("Candle Type", "Timeframe", "General")
self._fast_period = self.Param("FastPeriod", 5) \
.SetDisplay("Fast Period", "Fast MA period", "Indicators")
self._mid_period = self.Param("MidPeriod", 20) \
.SetDisplay("Mid Period", "Medium MA period", "Indicators")
self._slow_period = self.Param("SlowPeriod", 50) \
.SetDisplay("Slow Period", "Slow MA (trend filter)", "Indicators")
self._prev_fast = None
self._prev_mid = None
@property
def CandleType(self):
return self._candle_type.Value
@property
def FastPeriod(self):
return self._fast_period.Value
@property
def MidPeriod(self):
return self._mid_period.Value
@property
def SlowPeriod(self):
return self._slow_period.Value
def OnReseted(self):
super(xit_three_ma_cross_strategy, self).OnReseted()
self._prev_fast = None
self._prev_mid = None
def OnStarted2(self, time):
super(xit_three_ma_cross_strategy, self).OnStarted2(time)
self._prev_fast = None
self._prev_mid = None
fast = SimpleMovingAverage()
fast.Length = self.FastPeriod
mid = SimpleMovingAverage()
mid.Length = self.MidPeriod
slow = SimpleMovingAverage()
slow.Length = self.SlowPeriod
subscription = self.SubscribeCandles(self.CandleType)
subscription.Bind(fast, mid, slow, self._on_process).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawIndicator(area, fast)
self.DrawIndicator(area, mid)
self.DrawIndicator(area, slow)
self.DrawOwnTrades(area)
def _on_process(self, candle, fast_value, mid_value, slow_value):
if candle.State != CandleStates.Finished:
return
fv = float(fast_value)
mv = float(mid_value)
sv = float(slow_value)
if self._prev_fast is None or self._prev_mid is None:
self._prev_fast = fv
self._prev_mid = mv
return
buy_signal = fv > mv and mv > sv
sell_signal = fv < mv and mv < sv
if buy_signal and self.Position <= 0:
if self.Position < 0:
self.BuyMarket()
self.BuyMarket()
elif sell_signal and self.Position >= 0:
if self.Position > 0:
self.SellMarket()
self.SellMarket()
self._prev_fast = fv
self._prev_mid = mv
def CreateClone(self):
return xit_three_ma_cross_strategy()