Color Zerolag JCCX-Strategie
Strategie inspiriert vom ColorZerolagJCCX-Indikator aus MetaTrader. Sie approximiert den originalen Oszillator mit zwei einfachen gleitenden Durchschnitten. Die Strategie geht Long, wenn der schnelle Durchschnitt den langsamen von oben nach unten kreuzt, und Short, wenn der schnelle Durchschnitt den langsamen von unten nach oben kreuzt.
Details
- Einstiegskriterien:
- Long:
Schneller MA kreuzt langsamen MA von oben nach unten - Short:
Schneller MA kreuzt langsamen MA von unten nach oben
- Long:
- Long/Short: Beide
- Ausstiegskriterien: Entgegengesetztes Signal
- Stops:
StartProtection() - Standardwerte:
FastPeriod= 8SlowPeriod= 21CandleType= 4-Stunden-Kerzen
- Filter:
- Kategorie: Trendfolge
- Richtung: Beide
- Indikatoren: Gleitender Durchschnitt
- Stops: Optional
- Komplexität: Grundlegend
- Zeitrahmen: Swing
- Saisonalität: Nein
- Neuronale Netze: Nein
- Divergenz: Nein
- Risikolevel: Mittel
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>
/// Simple crossover strategy inspired by ColorZerolagJCCX indicator.
/// Uses two moving averages and trades on crossovers.
/// </summary>
public class ColorZerolagJccxStrategy : Strategy
{
private readonly StrategyParam<int> _fastPeriod;
private readonly StrategyParam<int> _slowPeriod;
private readonly StrategyParam<DataType> _candleType;
private bool _initialized;
private decimal _prevFast;
private decimal _prevSlow;
public int FastPeriod { get => _fastPeriod.Value; set => _fastPeriod.Value = value; }
public int SlowPeriod { get => _slowPeriod.Value; set => _slowPeriod.Value = value; }
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public ColorZerolagJccxStrategy()
{
_fastPeriod = Param(nameof(FastPeriod), 8)
.SetGreaterThanZero()
.SetDisplay("Fast MA", "Fast moving average period", "Moving Average");
_slowPeriod = Param(nameof(SlowPeriod), 21)
.SetGreaterThanZero()
.SetDisplay("Slow MA", "Slow moving average period", "Moving Average");
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
.SetDisplay("Candle Type", "Timeframe for calculation", "General");
}
/// <inheritdoc />
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
{
return [(Security, CandleType)];
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_initialized = false;
_prevFast = default;
_prevSlow = default;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var fastMa = new ExponentialMovingAverage { Length = FastPeriod };
var slowMa = new ExponentialMovingAverage { Length = SlowPeriod };
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(fastMa, slowMa, ProcessCandle)
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, fastMa);
DrawIndicator(area, slowMa);
DrawOwnTrades(area);
}
}
private void ProcessCandle(ICandleMessage candle, decimal fast, decimal slow)
{
if (candle.State != CandleStates.Finished)
return;
if (!_initialized)
{
_prevFast = fast;
_prevSlow = slow;
_initialized = true;
return;
}
var wasFastAbove = _prevFast > _prevSlow;
var isFastAbove = fast > slow;
if (!wasFastAbove && isFastAbove && Position <= 0)
{
if (Position < 0) BuyMarket();
BuyMarket();
}
else if (wasFastAbove && !isFastAbove && Position >= 0)
{
if (Position > 0) SellMarket();
SellMarket();
}
_prevFast = fast;
_prevSlow = slow;
}
}
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 ExponentialMovingAverage
from StockSharp.Algo.Strategies import Strategy
class color_zerolag_jccx_strategy(Strategy):
def __init__(self):
super(color_zerolag_jccx_strategy, self).__init__()
self._fast_period = self.Param("FastPeriod", 8) \
.SetDisplay("Fast MA", "Fast moving average period", "Moving Average")
self._slow_period = self.Param("SlowPeriod", 21) \
.SetDisplay("Slow MA", "Slow moving average period", "Moving Average")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(4))) \
.SetDisplay("Candle Type", "Timeframe for calculation", "General")
self._initialized = False
self._prev_fast = 0.0
self._prev_slow = 0.0
@property
def fast_period(self):
return self._fast_period.Value
@property
def slow_period(self):
return self._slow_period.Value
@property
def candle_type(self):
return self._candle_type.Value
def OnReseted(self):
super(color_zerolag_jccx_strategy, self).OnReseted()
self._initialized = False
self._prev_fast = 0.0
self._prev_slow = 0.0
def OnStarted2(self, time):
super(color_zerolag_jccx_strategy, self).OnStarted2(time)
fast_ma = ExponentialMovingAverage()
fast_ma.Length = self.fast_period
slow_ma = ExponentialMovingAverage()
slow_ma.Length = self.slow_period
subscription = self.SubscribeCandles(self.candle_type)
subscription.Bind(fast_ma, slow_ma, self.process_candle).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawIndicator(area, fast_ma)
self.DrawIndicator(area, slow_ma)
self.DrawOwnTrades(area)
def process_candle(self, candle, fast, slow):
if candle.State != CandleStates.Finished:
return
fast = float(fast)
slow = float(slow)
if not self._initialized:
self._prev_fast = fast
self._prev_slow = slow
self._initialized = True
return
was_fast_above = self._prev_fast > self._prev_slow
is_fast_above = fast > slow
if not was_fast_above and is_fast_above and self.Position <= 0:
if self.Position < 0:
self.BuyMarket()
self.BuyMarket()
elif was_fast_above and not is_fast_above and self.Position >= 0:
if self.Position > 0:
self.SellMarket()
self.SellMarket()
self._prev_fast = fast
self._prev_slow = slow
def CreateClone(self):
return color_zerolag_jccx_strategy()