GitHub で見る
同期チャートの確認戦略
この戦略は、同じ金融商品の 2 つのローソク足フィードを監視することにより、元の MQL の「SyncCharts」ユーティリティのアイデアを反映しています。
両方のストリームが同じトレンド方向を確認した場合にのみ取引の決定を下します。マスター シリーズは参照チャートとして機能します
(トレーダーが通常監視するもの)、フォロワー シリーズは補助チャート (たとえば、より速いタイムフレームや
代替集計)。市場に参入する前に両方のストリームを強制的に一致させることにより、システムは次のようなノイズをフィルタリングして除去します。
チャート間隔間の一時的な非同期。
この設定は、指数先物や流動的な通貨ペアなど、複数の時間枠のトレンド構造を示す商品で最も効果的に機能します。
取引が行われる前に両方のチャートが同時に動く必要があるため、誤ったシグナルが減少し、戦略が自然に制限されます。
時間枠が一致しない、または新しいローソク足が異なる瞬間に印刷される、混沌とした市場段階でのエクスポージャ。
詳細
- エントリー基準:
- ロング: マスターとフォロワーの両方の単純移動平均 (SMA) は、直近の完成したローソク足で上向きに傾斜しています。
これらのローソク足のタイムスタンプの差は同期許容値未満です。
- 短い: 両方の SMA は下向きに傾斜しており、タイムスタンプの差は許容範囲内にあります。
- 終了基準:
- 時間の非同期: 最新のローソク足が許容誤差を超えて離れている場合、ポジションはフラット化されます。
- トレンドの不一致: 一方の SMA が上昇し、他方が下落した場合、オープンポジションは直ちにクローズされます。
- ストップ: 暗黙的なフラット化ロジックはソフト ストップとして機能します。個別のハード ストップは送信されません。
- ロング/ショート: 両側が取引されます。
- デフォルト値:
- マスターキャンドル:5分のタイムフレーム。
- フォロワーキャンドル:1分のタイムフレーム。
- SMA 長さ: 両方のストリームで 20 ピリオド。
- 同期許容範囲: ローソク足のオープン時間間の間隔は 15 秒です。
- フィルター:
- カテゴリ: トレンド確認/マルチタイムフレーム。
- 方向: 双方向。
- インジケーター: SMA (デュアル ストリーム)。
- ストップ: 固定ストップはなく、チャートが発散すると自動的にフラット化されます。
- 複雑さ: 中 (同期チェックを伴うマルチサブスクリプション)。
- 時間枠: 設定可能 (デフォルトは日中)。
- 季節性:なし。
- ニューラルネットワーク: いいえ。
- ダイバージェンス: 時間枠のダイバージェンスをフィルターとして使用します (価格のダイバージェンスではなく、合意が必要です)。
- リスクレベル:確認が必要なため中程度。
仕組み
- 2 つのローソク足サブスクリプションが高レベルの StockSharp API 経由で作成されます。1 つはマスター チャート用、もう 1 つはフォロワー用です。
- 各フィードは同じ長さの SMA によって処理され、トレンド方向フラグ (SMA の値が上昇した場合は
up) が生成されます。
前のローソク足、それ以外の場合は down)。
- 両方のローソク足が終了するたびに、戦略はそれらのタイムスタンプが十分に近いこと (絶対差が以下のものであること) を検証します。
設定された許容値)。
- チャートが同期し、両方のトレンドが上を向いている場合、戦略は買いになります (空売りを最初に閉じる)。両方のトレンドが下向きの場合、
空売りします(ロングがあれば最初にクローズします)。
- 同期の喪失やトレンドの不一致が発生した場合は、アカウントをチャートと一致させるために即座にフラット化がトリガーされます。
トレーダーの時計。
推奨される使用方法
- 通常は相関する 2 つの異なる時間枠で同じ商品に適用します (例: 5 分と 1 分、または 1 時間と 1 時間)。
15分)。
- わずかな遅延を伴うローソク足を出力する特殊なデータ ソースを使用する場合は、同期許容値を増やします。
- ライブ取引に導入する場合は、外部リスクマネージャーまたはアドオン停止モジュールと組み合わせてください。
namespace StockSharp.Samples.Strategies;
using System;
using Ecng.Common;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.Messages;
/// <summary>
/// Sync Charts Confirmation strategy: dual SMA trend confirmation.
/// Uses fast and slow SMAs to confirm trend direction.
/// Buys when both SMAs trend up, sells when both trend down.
/// </summary>
public class SyncChartsConfirmationStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _fastPeriod;
private readonly StrategyParam<int> _slowPeriod;
private readonly StrategyParam<int> _signalCooldownCandles;
private bool _wasBullish;
private bool _hasPrevTrend;
private int _candlesSinceTrade;
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public int FastPeriod { get => _fastPeriod.Value; set => _fastPeriod.Value = value; }
public int SlowPeriod { get => _slowPeriod.Value; set => _slowPeriod.Value = value; }
public int SignalCooldownCandles { get => _signalCooldownCandles.Value; set => _signalCooldownCandles.Value = value; }
public SyncChartsConfirmationStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(5).TimeFrame())
.SetDisplay("Candle Type", "Candle timeframe", "General");
_fastPeriod = Param(nameof(FastPeriod), 10)
.SetGreaterThanZero()
.SetDisplay("Fast Period", "Fast SMA period", "Indicators");
_slowPeriod = Param(nameof(SlowPeriod), 40)
.SetGreaterThanZero()
.SetDisplay("Slow Period", "Slow SMA period", "Indicators");
_signalCooldownCandles = Param(nameof(SignalCooldownCandles), 6)
.SetGreaterThanZero()
.SetDisplay("Signal Cooldown", "Bars to wait between signals", "Trading");
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_wasBullish = false;
_hasPrevTrend = false;
_candlesSinceTrade = SignalCooldownCandles;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_hasPrevTrend = false;
_candlesSinceTrade = SignalCooldownCandles;
var fast = new SimpleMovingAverage { Length = FastPeriod };
var slow = new SimpleMovingAverage { 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 (_candlesSinceTrade < SignalCooldownCandles)
_candlesSinceTrade++;
var isBullish = fast > slow;
if (_hasPrevTrend && isBullish != _wasBullish && _candlesSinceTrade >= SignalCooldownCandles)
{
if (isBullish && Position <= 0)
{
BuyMarket();
_candlesSinceTrade = 0;
}
else if (!isBullish && Position >= 0)
{
SellMarket();
_candlesSinceTrade = 0;
}
}
_wasBullish = isBullish;
_hasPrevTrend = true;
}
}
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
from datatype_extensions import *
from indicator_extensions import *
class sync_charts_confirmation_strategy(Strategy):
"""Dual SMA trend confirmation with cooldown."""
def __init__(self):
super(sync_charts_confirmation_strategy, self).__init__()
self._fast_period = self.Param("FastPeriod", 10).SetGreaterThanZero().SetDisplay("Fast Period", "Fast SMA period", "Indicators")
self._slow_period = self.Param("SlowPeriod", 40).SetGreaterThanZero().SetDisplay("Slow Period", "Slow SMA period", "Indicators")
self._cooldown = self.Param("SignalCooldownCandles", 6).SetGreaterThanZero().SetDisplay("Signal Cooldown", "Bars to wait between signals", "Trading")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(5))).SetDisplay("Candle Type", "Candle timeframe", "General")
@property
def CandleType(self): return self._candle_type.Value
@CandleType.setter
def CandleType(self, value): self._candle_type.Value = value
def OnReseted(self):
super(sync_charts_confirmation_strategy, self).OnReseted()
self._was_bullish = False
self._has_prev = False
self._candles_since_trade = self._cooldown.Value
def OnStarted2(self, time):
super(sync_charts_confirmation_strategy, self).OnStarted2(time)
self._was_bullish = False
self._has_prev = False
self._candles_since_trade = self._cooldown.Value
fast = SimpleMovingAverage()
fast.Length = self._fast_period.Value
slow = SimpleMovingAverage()
slow.Length = self._slow_period.Value
sub = self.SubscribeCandles(self.CandleType)
sub.Bind(fast, slow, self.OnProcess).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, sub)
self.DrawIndicator(area, fast)
self.DrawIndicator(area, slow)
self.DrawOwnTrades(area)
def OnProcess(self, candle, fast, slow):
if candle.State != CandleStates.Finished:
return
if self._candles_since_trade < self._cooldown.Value:
self._candles_since_trade += 1
is_bullish = fast > slow
if self._has_prev and is_bullish != self._was_bullish and self._candles_since_trade >= self._cooldown.Value:
if is_bullish and self.Position <= 0:
self.BuyMarket()
self._candles_since_trade = 0
elif not is_bullish and self.Position >= 0:
self.SellMarket()
self._candles_since_trade = 0
self._was_bullish = is_bullish
self._has_prev = True
def CreateClone(self):
return sync_charts_confirmation_strategy()