Diese Strategie bildet das Verhalten des MetaTrader-Expertenberaters „OsMA Four Colors Arrow“ innerhalb des StockSharp-Frameworks nach. Der ursprüngliche EA reagiert auf die farbigen Pfeile, die vom begleitenden Indikator erzeugt werden, wann immer das OsMA (MACD-Histogramm) die Phase ändert. In der StockSharp-Version wird das gleiche Verhalten durch die Überwachung von Nulldurchgängen des MACD-Histogramms modelliert: Ein bullischer Cross (das Histogramm bewegt sich von negativ nach positiv) löst Long-Einstiege aus, während ein bärischer Cross Short-Einstiege auslöst. Der optionale Umkehrmodus stellt die Logik für Absicherungs- oder Mean-Reversion-Tests auf den Kopf.
Die Vorlage funktioniert nur mit fertigen Kerzen und kann eine tägliche Handelssitzung erzwingen, ähnlich dem Zeitfilter, der von der MQL-Version angeboten wird. Das integrierte Geldmanagement umfasst ein konfigurierbares Handelsvolumen, eine Obergrenze für die Anzahl der aggregierten Positionen und einen automatischen Stop-Loss-/Take-Profit-/Trailing-Schutz, ausgedrückt in Pips.
Handelslogik
Abonnieren Sie den ausgewählten Zeitrahmen und berechnen Sie ein MACD-Histogramm (OsMA) mit konfigurierbaren schnellen, langsamen und Signallängen von EMA.
Wenn eine Kerze schließt, überprüfen Sie das Histogrammzeichen:
Histogramm kreuzt über Null → bullischer Pfeil → Kaufsignal.
Histogramm kreuzt unter Null → rückläufiger Pfeil → Verkaufssignal.
Wenden Sie optionale Funktionen an, bevor Sie eine Bestellung senden:
Richtungsfilter (nur lang, nur kurz oder beides).
Reverse-Modus zum Invertieren von Signalen.
Schließen Sie das bestehende Gegenrisiko, bevor Sie den neuen Trade eröffnen.
Beschränken Sie sich auf eine aktive Position oder akkumulieren Sie bis zur konfigurierten maximalen Belichtung.
Marktaufträge werden mit der konfigurierten Losgröße gesendet. StartProtection wandelt Pip-Eingaben in absolute Preis-Offsets um, um Stop-Loss, Take-Profit und Trailing-Management automatisch durchzuführen.
Trades werden außerhalb der zulässigen Intraday-Sitzung ignoriert, wenn der Zeitfilter aktiviert ist.
Parameter
Name
Beschreibung
CandleType
Zeitrahmen, der für Berechnungen und Signalgenerierung verwendet wird.
FastPeriod / SlowPeriod / SignalPeriod
EMA Längen für das MACD Histogramm (OsMA).
StopLossPips / TakeProfitPips
Risikoziele in Pips. Zum Deaktivieren auf Null setzen.
TrailingActivatePips
Erforderlicher Gewinn (in Pips), bevor sich der Trailing Stop bewegen kann.
TrailingStopPips
Nachlaufdistanz in Pips. Null deaktiviert das nachgestellte Modul.
TrailingStepPips
Zusätzliche Pips, die gewonnen werden müssen, bevor der Trailing Stop wieder verschärft wird.
Beschränken Sie die Signale auf Nur-Long-Signale, Nur-Short-Signale oder beides.
CloseOppositePositions
Schließen Sie alle gegenüberliegenden Belichtungen, bevor Sie auf das neue Signal reagieren.
OnlyOnePosition
Bei true wird verhindert, dass eine bereits offene Position in die gleiche Richtung erweitert wird.
UseTimeControl
Aktivieren Sie den Intraday-Handelssitzungsfilter.
StartHour, StartMinute, EndHour, EndMinute
Sitzungsgrenzen (das Ende kann früher als der Beginn liegen, um Nachtsitzungen abzudecken).
TradeVolume
Bestellvolumen in Losen.
Notizen
Trailing-Stop-Eingaben ahmen den EA nach: Trailing wird erst nach TrailingActivatePips verfügbar und bewegt sich in durch TrailingStepPips definierten Schritten.
Die Strategie erfordert, dass das Wertpapier über einen gültigen PriceStep und Decimals verfügt, um Pips in Preis-Offsets umzuwandeln. Sofern das Instrument diese nicht bereitstellt, fallen die Vorgaben auf eine absolute Preiseinheit zurück.
Wenn MaxPositions größer als eins ist, kann die Strategie durch wiederholtes Hinzufügen von TradeVolume unter Berücksichtigung des maximalen Expositionslimits schrittweise erweitert werden.
Wenn UseTimeControl aktiviert ist und die Start- und Endzeiten übereinstimmen, ist der Handel deaktiviert, um mehrdeutige Sitzungen zu vermeiden.
Die Logik wirkt nur auf geschlossene Kerzen; Es erfolgt keine Übermittlung einer Intra-Bar-Order, was dem Verhalten der Vorlage MQL 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>
/// Simplified from "OsMA Four Colors Arrow" MetaTrader expert.
/// Uses MACD histogram (OsMA) zero-crossing as entry signal.
/// Buys when histogram crosses above zero, sells when it crosses below.
/// </summary>
public class OsMaFourColorsArrowStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _fastPeriod;
private readonly StrategyParam<int> _slowPeriod;
private readonly StrategyParam<int> _signalPeriod;
private MovingAverageConvergenceDivergence _macd;
private readonly Queue<decimal> _macdHistory = new();
private decimal? _prevHistogram;
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 SignalPeriod
{
get => _signalPeriod.Value;
set => _signalPeriod.Value = value;
}
public OsMaFourColorsArrowStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(60).TimeFrame())
.SetDisplay("Candle Type", "Timeframe used for signal generation", "General");
_fastPeriod = Param(nameof(FastPeriod), 20)
.SetGreaterThanZero()
.SetDisplay("Fast EMA", "Fast EMA length for MACD", "Indicators");
_slowPeriod = Param(nameof(SlowPeriod), 50)
.SetGreaterThanZero()
.SetDisplay("Slow EMA", "Slow EMA length for MACD", "Indicators");
_signalPeriod = Param(nameof(SignalPeriod), 12)
.SetGreaterThanZero()
.SetDisplay("Signal Period", "Signal line smoothing period", "Indicators");
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_prevHistogram = null;
_macdHistory.Clear();
_macd = new MovingAverageConvergenceDivergence
{
ShortMa = { Length = FastPeriod },
LongMa = { Length = SlowPeriod },
};
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(_macd, ProcessCandle)
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, _macd);
DrawOwnTrades(area);
}
}
private void ProcessCandle(ICandleMessage candle, decimal macdValue)
{
if (candle.State != CandleStates.Finished)
return;
if (!_macd.IsFormed)
return;
// Compute signal line as SMA of MACD values
_macdHistory.Enqueue(macdValue);
if (_macdHistory.Count > SignalPeriod)
_macdHistory.Dequeue();
if (_macdHistory.Count < SignalPeriod)
{
_prevHistogram = null;
return;
}
decimal sum = 0;
var history = _macdHistory.ToArray();
foreach (var v in history)
sum += v;
var signal = sum / history.Length;
// OsMA = MACD - Signal (histogram)
var histogram = macdValue - signal;
if (_prevHistogram is null)
{
_prevHistogram = histogram;
return;
}
var volume = Volume;
if (volume <= 0)
volume = 1;
var crossUp = _prevHistogram.Value <= 0 && histogram > 0;
var crossDown = _prevHistogram.Value >= 0 && histogram < 0;
if (crossUp)
{
if (Position <= 0)
BuyMarket(Position < 0 ? Math.Abs(Position) + volume : volume);
}
else if (crossDown)
{
if (Position >= 0)
SellMarket(Position > 0 ? Math.Abs(Position) + volume : volume);
}
_prevHistogram = histogram;
}
/// <inheritdoc />
protected override void OnReseted()
{
_macd = null;
_prevHistogram = null;
_macdHistory.Clear();
base.OnReseted();
}
}