FrakTrak XonaX ist eine Ausbruch-Strategie, die auf Fraktal-Niveaus basiert, die in einem höheren Zeitrahmen berechnet werden. Wenn der Preis das jüngste Fraktal um einen kleinen Offset überschreitet, steigt die Strategie in Richtung des Ausbruchs ein. Ein fester Take-Profit und ein Trailing-Stop verwalten die offene Position.
Parameter
Volume – Ordergröße.
Take Profit – Abstand in Punkten für das Take-Profit-Niveau.
Trailing Stop – Abstand in Punkten für den Trailing-Stop-Loss.
Trailing Correction – zusätzlicher Abstand zum Trailing-Stop.
Candle Type – Zeitrahmen zur Erstellung von Kerzen und Fraktalen.
Handelsregeln
Obere und untere Fraktale anhand der letzten abgeschlossenen Kerzen berechnen.
Kaufen, wenn der Schlusskurs das obere Fraktal plus 15 Punkte überschreitet und keine Long-Position besteht. Stop-Loss wird beim letzten unteren Fraktal gesetzt, Take-Profit über Take Profit konfiguriert.
Verkaufen, wenn der Schlusskurs unter das untere Fraktal minus 15 Punkte fällt und keine Short-Position besteht. Stop-Loss wird beim letzten oberen Fraktal gesetzt, Take-Profit über Take Profit konfiguriert.
Wenn eine Position mehr als Trailing Stop Punkte im Gewinn liegt, folgt der Stop-Loss dem Preis mit einem zusätzlichen Trailing Correction Offset.
using System;
using System.Linq;
using System.Collections.Generic;
using Ecng.Common;
using Ecng.Collections;
using Ecng.Serialization;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
/// <summary>
/// FrakTrak XonaX strategy.
/// Uses fractal breakouts to generate entry signals.
/// </summary>
public class FraktrakXonaxStrategy : Strategy
{
private readonly StrategyParam<decimal> _fractalOffset;
private readonly StrategyParam<DataType> _candleType;
private decimal _h1, _h2, _h3, _h4, _h5;
private decimal _l1, _l2, _l3, _l4, _l5;
private decimal? _upFractal;
private decimal? _downFractal;
private decimal? _lastUpFractal;
private decimal? _lastDownFractal;
/// <summary>
/// Price offset added beyond fractal for entry trigger.
/// </summary>
public decimal FractalOffset
{
get => _fractalOffset.Value;
set => _fractalOffset.Value = value;
}
/// <summary>
/// Candle type used by the strategy.
/// </summary>
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
public FraktrakXonaxStrategy()
{
_fractalOffset = Param(nameof(FractalOffset), 50m)
.SetDisplay("Fractal Offset", "Price offset beyond fractal for entry", "Signals");
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
.SetDisplay("Candle Type", "Source candles", "General");
}
/// <inheritdoc />
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
=> [(Security, CandleType)];
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_h1 = _h2 = _h3 = _h4 = _h5 = 0m;
_l1 = _l2 = _l3 = _l4 = _l5 = 0m;
_upFractal = _downFractal = _lastUpFractal = _lastDownFractal = null;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var subscription = SubscribeCandles(CandleType);
subscription.Bind(ProcessCandle).Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawOwnTrades(area);
}
}
private void ProcessCandle(ICandleMessage candle)
{
if (candle.State != CandleStates.Finished)
return;
// Shift high and low buffers
_h1 = _h2; _h2 = _h3; _h3 = _h4; _h4 = _h5; _h5 = candle.HighPrice;
_l1 = _l2; _l2 = _l3; _l3 = _l4; _l4 = _l5; _l5 = candle.LowPrice;
// Need at least 5 bars for fractal detection
if (_h1 == 0 || _l1 == 0)
return;
// Detect new fractals (bar 3 is the middle of 5 bars)
if (_h3 > _h1 && _h3 > _h2 && _h3 > _h4 && _h3 > _h5)
_upFractal = _h3;
if (_l3 < _l1 && _l3 < _l2 && _l3 < _l4 && _l3 < _l5)
_downFractal = _l3;
// Buy signal: close above up fractal + offset
if (_upFractal is decimal up && _lastUpFractal != up)
{
var trigger = up + FractalOffset;
if (candle.ClosePrice > trigger && Position <= 0)
{
BuyMarket();
_lastUpFractal = up;
}
}
// Sell signal: close below down fractal - offset
if (_downFractal is decimal low && _lastDownFractal != low)
{
var trigger = low - FractalOffset;
if (candle.ClosePrice < trigger && Position >= 0)
{
SellMarket();
_lastDownFractal = low;
}
}
}
}
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.Strategies import Strategy
class fraktrak_xonax_strategy(Strategy):
def __init__(self):
super(fraktrak_xonax_strategy, self).__init__()
self._fractal_offset = self.Param("FractalOffset", 50.0) \
.SetDisplay("Fractal Offset", "Price offset beyond fractal for entry", "Signals")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(4))) \
.SetDisplay("Candle Type", "Source candles", "General")
self._h1 = 0.0
self._h2 = 0.0
self._h3 = 0.0
self._h4 = 0.0
self._h5 = 0.0
self._l1 = 0.0
self._l2 = 0.0
self._l3 = 0.0
self._l4 = 0.0
self._l5 = 0.0
self._up_fractal = None
self._down_fractal = None
self._last_up_fractal = None
self._last_down_fractal = None
@property
def fractal_offset(self):
return self._fractal_offset.Value
@property
def candle_type(self):
return self._candle_type.Value
def OnReseted(self):
super(fraktrak_xonax_strategy, self).OnReseted()
self._h1 = self._h2 = self._h3 = self._h4 = self._h5 = 0.0
self._l1 = self._l2 = self._l3 = self._l4 = self._l5 = 0.0
self._up_fractal = None
self._down_fractal = None
self._last_up_fractal = None
self._last_down_fractal = None
def OnStarted2(self, time):
super(fraktrak_xonax_strategy, self).OnStarted2(time)
subscription = self.SubscribeCandles(self.candle_type)
subscription.Bind(self.process_candle).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawOwnTrades(area)
def process_candle(self, candle):
if candle.State != CandleStates.Finished:
return
# Shift high and low buffers
self._h1 = self._h2
self._h2 = self._h3
self._h3 = self._h4
self._h4 = self._h5
self._h5 = float(candle.HighPrice)
self._l1 = self._l2
self._l2 = self._l3
self._l3 = self._l4
self._l4 = self._l5
self._l5 = float(candle.LowPrice)
# Need at least 5 bars for fractal detection
if self._h1 == 0 or self._l1 == 0:
return
# Detect new fractals (bar 3 is the middle of 5 bars)
if self._h3 > self._h1 and self._h3 > self._h2 and self._h3 > self._h4 and self._h3 > self._h5:
self._up_fractal = self._h3
if self._l3 < self._l1 and self._l3 < self._l2 and self._l3 < self._l4 and self._l3 < self._l5:
self._down_fractal = self._l3
close = float(candle.ClosePrice)
offset = float(self.fractal_offset)
# Buy signal: close above up fractal + offset
if self._up_fractal is not None and self._last_up_fractal != self._up_fractal:
trigger = self._up_fractal + offset
if close > trigger and self.Position <= 0:
self.BuyMarket()
self._last_up_fractal = self._up_fractal
# Sell signal: close below down fractal - offset
if self._down_fractal is not None and self._last_down_fractal != self._down_fractal:
trigger = self._down_fractal - offset
if close < trigger and self.Position >= 0:
self.SellMarket()
self._last_down_fractal = self._down_fractal
def CreateClone(self):
return fraktrak_xonax_strategy()