Diese Strategie repliziert den MetaTrader-Experten "Exp_SilverTrend_CrazyChart" mithilfe der StockSharp High-Level-API. Sie handelt auf beiden Marktseiten, indem sie zwei Buffer des benutzerdefinierten SilverTrend CrazyChart-Indikators vergleicht. Wenn das verzögerte Band das aktuelle Band kreuzt, wird eine Position in Richtung des dominanten Bandes eröffnet und jedes entgegengesetzte Engagement geschlossen.
Details
Einstiegskriterien:
Long: Die vorherige abgeschlossene Signalkerze zeigt das aktuelle Band über dem verzögerten Band, und auf der ausgewerteten Kerze fällt das aktuelle Band unter das verzögerte Band oder berührt es. Long-Einstiege können mit AllowBuyEntry deaktiviert werden.
Short: Die vorherige abgeschlossene Signalkerze zeigt das aktuelle Band unter dem verzögerten Band, und auf der ausgewerteten Kerze steigt das aktuelle Band über das verzögerte Band oder berührt es. Short-Einstiege können mit AllowSellEntry deaktiviert werden.
Long/Short: Beide Richtungen.
Ausstiegskriterien:
Long-Positionen werden geschlossen, wenn das verzögerte Band das aktuelle Band überholt (AllowBuyExit) oder wenn Stop-Loss/Take-Profit-Limits ausgelöst werden.
Short-Positionen werden geschlossen, wenn das aktuelle Band das verzögerte Band überholt (AllowSellExit) oder wenn Stop-Loss/Take-Profit-Limits ausgelöst werden.
Stops: Verwendet absolute Preisabstände, die durch StopLossPoints und TakeProfitPoints angegeben werden. Wenn einer der Werte auf null gesetzt ist, wird dieses Limit ignoriert.
Filter:
SignalBar legt fest, wie viele abgeschlossene Kerzen zurück die Kreuzungslogik ausgewertet wird.
CandleType steuert den Zeitrahmen, der für alle Berechnungen verwendet wird.
Parameter
CandleType – Für den Indikator verwendete Kerzenserie (Standard: 1-Stunden-Kerzen).
Length – Swing-Periode (SSP), die an den SilverTrend CrazyChart-Indikator übergeben wird.
KMin – Unterer Kanalkoeffizient, der den Abstand des verzögerten Bandes steuert.
KMax – Oberer Kanalkoeffizient, der den Abstand des aktuellen Bandes steuert.
SignalBar – Anzahl abgeschlossener Kerzen zurück für die Kreuzungsauswertung (entspricht dem originalen SignalBar).
StopLossPoints – Absoluter Preisabstand vom Einstieg für Long-Stop-Loss und Short-Take-Profit.
TakeProfitPoints – Absoluter Preisabstand vom Einstieg für Long-Take-Profit und Short-Stop-Loss.
Volume – Geerbtes Strategie-Volumen, das die Basisordergröße definiert.
Indikatorlogik
Der enthaltene SilverTrendCrazyChartIndicator reproduziert die originalen MQL-Buffer:
Length, KMin und KMax berechnen einen Swing-Kanal aus dem höchsten Hoch und niedrigsten Tief über das Lookback-Fenster.
Das "aktuelle" Band entspricht Buffer 0 in MetaTrader und reagiert sofort auf die neueste Bar.
Das "verzögerte" Band ist Buffer 1, das das aktuelle Band um Length + 1 Bars verschiebt, um der ursprünglichen Zeichnungslogik zu entsprechen.
Ein Kauf wird ausgelöst, wenn das verzögerte Band als Trendfilter das aktuelle Band von unten kreuzt, während ein Verkauf erscheint, wenn die Beziehung sich umkehrt. Der Parameter SignalBar stellt sicher, dass nur abgeschlossene Kerzen an der Entscheidung teilnehmen, was dem Verhalten des Original-Experten entspricht.
using System;
using System.Collections.Generic;
using Ecng.Common;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
/// <summary>
/// SilverTrend CrazyChart strategy (simplified).
/// Uses Highest/Lowest channel inversions for entries.
/// </summary>
public class SilverTrendCrazyChartStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _length;
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
public int Length
{
get => _length.Value;
set => _length.Value = value;
}
public SilverTrendCrazyChartStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
.SetDisplay("Candle Type", "Candles", "General");
_length = Param(nameof(Length), 14)
.SetGreaterThanZero()
.SetDisplay("Length", "Channel length", "Indicators");
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var highest = new Highest { Length = Length };
var lowest = new Lowest { Length = Length };
decimal prevHigh = 0, prevLow = 0;
bool hasPrev = false;
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(highest, lowest, (ICandleMessage candle, decimal highValue, decimal lowValue) =>
{
if (candle.State != CandleStates.Finished)
return;
if (!hasPrev)
{
prevHigh = highValue;
prevLow = lowValue;
hasPrev = true;
return;
}
if (!IsFormedAndOnlineAndAllowTrading())
{
prevHigh = highValue;
prevLow = lowValue;
return;
}
var close = candle.ClosePrice;
var mid = (highValue + lowValue) / 2m;
var prevMid = (prevHigh + prevLow) / 2m;
// Price crosses above channel midpoint
if (close > mid && candle.OpenPrice <= prevMid && Position <= 0)
{
BuyMarket();
}
// Price crosses below channel midpoint
else if (close < mid && candle.OpenPrice >= prevMid && Position >= 0)
{
SellMarket();
}
prevHigh = highValue;
prevLow = lowValue;
})
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, highest);
DrawIndicator(area, lowest);
DrawOwnTrades(area);
}
}
}
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 Highest, Lowest
from StockSharp.Algo.Strategies import Strategy
class silver_trend_crazy_chart_strategy(Strategy):
def __init__(self):
super(silver_trend_crazy_chart_strategy, self).__init__()
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(4))) \
.SetDisplay("Candle Type", "Candles", "General")
self._length = self.Param("Length", 14) \
.SetDisplay("Length", "Channel length", "Indicators")
self._prev_high = 0.0
self._prev_low = 0.0
self._has_prev = False
@property
def CandleType(self):
return self._candle_type.Value
@property
def Length(self):
return self._length.Value
def OnReseted(self):
super(silver_trend_crazy_chart_strategy, self).OnReseted()
self._prev_high = 0.0
self._prev_low = 0.0
self._has_prev = False
def OnStarted2(self, time):
super(silver_trend_crazy_chart_strategy, self).OnStarted2(time)
self._prev_high = 0.0
self._prev_low = 0.0
self._has_prev = False
highest = Highest()
highest.Length = self.Length
lowest = Lowest()
lowest.Length = self.Length
subscription = self.SubscribeCandles(self.CandleType)
subscription.Bind(highest, lowest, self._on_process).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawIndicator(area, highest)
self.DrawIndicator(area, lowest)
self.DrawOwnTrades(area)
def _on_process(self, candle, high_value, low_value):
if candle.State != CandleStates.Finished:
return
hv = float(high_value)
lv = float(low_value)
if not self._has_prev:
self._prev_high = hv
self._prev_low = lv
self._has_prev = True
return
close = float(candle.ClosePrice)
open_p = float(candle.OpenPrice)
mid = (hv + lv) / 2.0
prev_mid = (self._prev_high + self._prev_low) / 2.0
if close > mid and open_p <= prev_mid and self.Position <= 0:
self.BuyMarket()
elif close < mid and open_p >= prev_mid and self.Position >= 0:
self.SellMarket()
self._prev_high = hv
self._prev_low = lv
def CreateClone(self):
return silver_trend_crazy_chart_strategy()