Strategie zur Bestätigung von Diagrammen synchronisieren
Die Strategie spiegelt die Idee des ursprünglichen MQL-Dienstprogramms „SyncCharts“ wider, indem sie zwei Kerzen-Feeds desselben Instruments überwacht und
Handelsentscheidungen nur dann treffen, wenn beide Ströme die gleiche Trendrichtung bestätigen. Als Referenzchart dient die Masterserie
(diejenige, die ein Händler normalerweise beobachtet), während die Follower-Reihe ein Hilfsdiagramm darstellt (z. B. einen schnelleren Zeitrahmen oder).
eine alternative Aggregation). Indem das System beide Streams dazu zwingt, vor dem Markteintritt zuzustimmen, filtert es das von ihnen ausgehende Rauschen heraus
vorübergehende Desynchronisation zwischen Diagrammintervallen.
Das Setup funktioniert am besten bei Instrumenten, die eine Trendstruktur mit mehreren Zeitrahmen aufweisen, wie z. B. Index-Futures und liquide Währungspaare.
Da sich beide Charts gemeinsam bewegen müssen, bevor ein Trade getätigt wird, werden Fehlsignale reduziert und die Strategie wird auf natürliche Weise eingeschränkt
Engagement in chaotischen Marktphasen, wenn die Zeitrahmen nicht übereinstimmen oder neue Kerzen zu unterschiedlichen Zeitpunkten gedruckt werden.
Einzelheiten
Eintrittskriterien:
Long: Sowohl die einfachen gleitenden Durchschnitte (SMAs) des Masters als auch des Followers steigen bei ihren letzten abgeschlossenen Kerzen an und
Die Zeitstempel dieser Kerzen unterscheiden sich um weniger als die Synchronisierungstoleranz.
Kurz: Beide SMAs fallen ab und die Zeitstempeldifferenz liegt innerhalb des Toleranzfensters.
Ausstiegskriterien:
Zeitliche Desynchronisierung: Wenn die letzten Kerzen um mehr als die zulässige Toleranz voneinander entfernt sind, wird die Position abgeflacht.
Trendunstimmigkeit: Wenn ein SMA nach oben zeigt, während der andere nach unten zeigt, wird die offene Position sofort geschlossen.
Stoppt: Die implizite Flatten-Logik fungiert als sanfter Stopp. Es wird kein separater Hardstop übermittelt.
Long/Short: Es wird auf beiden Seiten gehandelt.
Standardwerte:
Master-Kerze: 5-Minuten-Zeitrahmen.
Folgekerze: 1 Minute Zeitrahmen.
SMA Länge: 20 Perioden in beiden Streams.
Synchronisationstoleranz: 15 Sekunden zwischen den Kerzenöffnungszeiten.
Filter:
Kategorie: Trendbestätigung / Multi-Timeframe.
Richtung: Bidirektional.
Indikatoren: SMA (Dual-Stream).
Stopps: Kein fester Stopp, automatische Abflachung bei Divergenz der Charts.
Komplexität: Mittel (Mehrfachabonnement mit Synchronisierungsprüfungen).
Zeitrahmen: Konfigurierbar (Standard Intraday).
Saisonalität: Keine.
Neuronale Netze: Nein.
Divergenz: Verwendet Zeitrahmendivergenz als Filter (erfordert Vereinbarung, keine Preisdivergenz).
Risikostufe: Moderat aufgrund der Bestätigungspflicht.
Wie es funktioniert
Über den High-Level StockSharp API werden zwei Kerzenabonnements erstellt: eines für das Master-Chart und eines für den Follower.
Jeder Feed wird von einem SMA mit der gleichen Länge verarbeitet, was ein Trendrichtungsflag (up ergibt, wenn der Wert von SMA im Vergleich zu steigt
vorherige Kerze, andernfalls down).
Immer wenn beide Kerzen enden, überprüft die Strategie, ob ihre Zeitstempel nahe genug beieinander liegen (absolute Differenz unter dem
konfigurierte Toleranz).
Wenn die Diagramme synchronisiert sind und beide Trends nach oben zeigen, kauft die Strategie (alle Short-Positionen werden zuerst geschlossen). Wenn beide Trends nach unten zeigen,
es wird leerverkauft (alle Long-Positionen werden zuerst geschlossen).
Jeder Synchronisationsverlust oder jede Trendabweichung löst eine sofortige Abflachung aus, um das Konto an den Diagrammen auszurichten
Händleruhren.
Empfohlene Verwendung
Auf dasselbe Instrument in zwei verschiedenen Zeitrahmen anwenden, die normalerweise korrelieren (z. B. 5 Minuten und 1 Minute oder stündlich und).
15 Minuten).
Erhöhen Sie die Synchronisierungstoleranz, wenn Sie mit exotischen Datenquellen arbeiten, die Kerzen mit geringfügigen Verzögerungen drucken.
Kombinieren Sie es mit einem externen Risikomanager oder einem Add-on-Stopp-Modul, wenn Sie es für den Live-Handel einsetzen.
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()