Diese Strategie ist ein StockSharp-Port des MetaTrader 5-Expertenberaters "Fractals at Close prices" von Vladimir Karputov. Sie analysiert fünf aufeinanderfolgende Schlusspreise, um Fraktale im Stil von Bill Williams zu erkennen, die streng auf Schlusskursen statt auf Hochs oder Tiefs aufgebaut werden. Die beiden jüngsten bullischen und bärischen Fraktale werden verglichen, um den aktiven Trend zu bestimmen. Wenn das neueste bullische Fraktal über dem vorherigen erscheint, eröffnet die Strategie eine Long-Position. Wenn das neueste bärische Fraktal unter dem vorherigen entsteht, wird eine Short-Position eröffnet. Entgegengesetzte Positionen werden immer geschlossen, bevor ein neuer Trade eingegangen wird, sodass die Strategie jederzeit höchstens in einer Richtung aktiv ist.
Trades sind nur zwischen der konfigurierbaren Start- und Endstunde erlaubt. Wenn die aktuelle Stunde außerhalb dieses Fensters liegt, werden alle offenen Positionen sofort geschlossen, was das Verhalten des ursprünglichen EA repliziert. Der Zeitfilter unterstützt Intraday-Fenster (Start < Ende), nächtliche Sitzungen, die Mitternacht überschreiten (Start > Ende), und ganztägigen Handel (Start == Ende).
Indikatorlogik
Jede abgeschlossene Kerze wird einer rollierenden Fünf-Element-Warteschlange von Schlusspreisen hinzugefügt.
Sobald fünf Werte verfügbar sind, wird der mittlere Schluss (zwei Kerzen zurück) bewertet:
Ein bullisches Fraktal wird registriert, wenn der mittlere Schluss streng größer als die beiden älteren Schlüsse und größer oder gleich den beiden neueren Schlüssen ist.
Ein bärisches Fraktal wird registriert, wenn der mittlere Schluss streng kleiner als die beiden älteren Schlüsse und kleiner oder gleich den beiden neueren Schlüssen ist.
Die neuesten und vorherigen bullischen Fraktale sowie die neuesten und vorherigen bärischen Fraktale werden für den späteren Vergleich gespeichert.
Ein bullischer Trend wird erkannt, wenn das neueste bullische Fraktal höher als das vorherige ist. Ein bärischer Trend wird erkannt, wenn das neueste bärische Fraktal niedriger als das vorherige ist.
Handelsregeln
Long-Einträge
Alle aktiven Short-Positionen zum Marktpreis schließen.
Wenn keine Long-Position offen ist, OrderVolume zum Marktpreis am Schluss kaufen, der die bullische Fraktal-Sequenz bestätigt hat.
Short-Einträge
Alle aktiven Long-Positionen zum Marktpreis schließen.
Wenn keine Short-Position offen ist, OrderVolume zum Marktpreis verkaufen, wenn eine bärische Fraktal-Sequenz bestätigt wird.
Sitzungssteuerung
Vor der Anwendung von Signalen überprüft die Strategie, ob candle.OpenTime.Hour innerhalb des Handelsfensters liegt. Falls nicht, wird CloseAllPositions aufgerufen und die Bar ignoriert.
Risikomanagement
Stop-Loss- und Take-Profit-Abstände werden in Pips ausgedrückt. Die Implementierung reproduziert den MT5-Ansatz: Der Symbolpunkt wird mit zehn multipliziert, wenn das Instrument 3 oder 5 Dezimalstellen hat. Der resultierende Pip-Wert wird dann mit den konfigurierten Abständen multipliziert.
Beim Eingehen einer Position werden die anfänglichen Stop-Loss- und Take-Profit-Levels intern gespeichert. Da StockSharp MT5-Schutzaufträge nicht automatisch verwaltet, überwacht die Strategie abgeschlossene Kerzen und schließt zum Marktpreis, wenn deren Preisspanne das gespeicherte Level berührt.
Trailing Stops folgen den ursprünglichen EA-Regeln. Ein neuer Stop wird als close ± TrailingStop berechnet, sobald der Gewinn TrailingStop + TrailingStep übersteigt. Der Trailing Stop wird nur vorgerückt, wenn die Bewegung vom vorherigen Stop mindestens TrailingStep beträgt.
Wenn die Handelszeiten enden, werden alle Positionen unabhängig vom Trailing-Status geschlossen. Dies repliziert das EA-Verhalten, das CloseAllPositions außerhalb der erlaubten Sitzung aufruft.
Parameter
Name
Beschreibung
Standard
OrderVolume
Volumen für jeden Marktauftrag.
0.1
StartHour
Stunde (0-23), ab der der Handel aktiv wird. Wenn gleich EndHour, läuft die Strategie den ganzen Tag.
10
EndHour
Stunde (0-23), ab der keine neuen Signale mehr akzeptiert werden.
22
StopLossPips
Stop-Loss-Abstand in Pips. 0 deaktiviert den Stop.
30
TakeProfitPips
Take-Profit-Abstand in Pips. 0 deaktiviert den Take.
50
TrailingStopPips
Basis-Trailing-Stop-Abstand in Pips. 0 deaktiviert das Trailing.
15
TrailingStepPips
Zusätzlicher Gewinn (in Pips), der erforderlich ist, bevor der Trailing Stop vorgerückt wird.
5
CandleType
Kerzen-Datentyp, der von der Strategie abonniert wird. Standard ist 1-Stunden-Zeitrahmen-Kerzen.
1 hour TimeFrame
Implementierungshinweise
Die Strategie verwendet SubscribeCandles mit der High-Level-API und registriert keine Indikatoren manuell, gemäß den Projektrichtlinien.
Schutzzausgänge (Stop, Take-Profit, Trailing Stop) werden durch das Senden von Marktaufträgen nach Beendigung einer Kerze ausgeführt, da StockSharp MT5-Schutzaufträge nicht automatisch verwaltet.
Sitzungsfilterung, Fraktal-Erkennung und Trailing-Logik folgen streng der EA-Struktur, einschließlich des Schließens aller Positionen, wenn der Stundenfilter nicht erfüllt ist.
Die Pip-Skalierungslogik spiegelt die MT5-Implementierung wider, indem der Symbolpunkt bei 3- oder 5-dezimalen Instrumenten mit zehn multipliziert wird, um äquivalente Preisabstände sicherzustellen.
Verwendungstipps
Strategie einem Symbol zuordnen und OrderVolume auf die bevorzugte Lotgröße setzen.
Einen Kerzentyp wählen, der dem in MetaTrader 5 verwendeten Zeitrahmen entspricht (der ursprüngliche EA funktioniert auf jedem Zeitrahmen).
Das Handelsfenster an die Broker-Sitzung oder die gewünschten Stunden anpassen.
Die pip-basierten Abstände entsprechend der Instrument-Volatilität einstellen. Größere TrailingStepPips reduzieren die Trailing-Häufigkeit, während kleinere Werte den Stop näher am Preis halten.
Logs auf Ein- und Ausstiege überwachen; die Strategie zeichnet Trades im optionalen Diagrammbereich zur schnellen visuellen Überprüfung.
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>
/// Strategy converted from the MT5 "Fractals at Close prices" expert advisor.
/// Detects bullish and bearish fractal sequences built on close prices and trades trend reversals.
/// Includes configurable trading hours and manual risk management with trailing stops.
/// </summary>
public class FractalsAtClosePricesStrategy : Strategy
{
private readonly StrategyParam<decimal> _orderVolume;
private readonly StrategyParam<int> _startHour;
private readonly StrategyParam<int> _endHour;
private readonly StrategyParam<int> _stopLossPips;
private readonly StrategyParam<int> _takeProfitPips;
private readonly StrategyParam<int> _trailingStopPips;
private readonly StrategyParam<int> _trailingStepPips;
private readonly StrategyParam<DataType> _candleType;
private readonly List<decimal> _closeWindow = new(6);
private decimal? _lastUpperFractal;
private decimal? _previousUpperFractal;
private decimal? _lastLowerFractal;
private decimal? _previousLowerFractal;
private decimal _pipValue;
private decimal _stopLossDistance;
private decimal _takeProfitDistance;
private decimal _trailingStopDistance;
private decimal _trailingStepDistance;
private decimal? _entryPrice;
private decimal? _longStop;
private decimal? _longTake;
private decimal? _shortStop;
private decimal? _shortTake;
/// <summary>
/// Trading volume used for every market order.
/// </summary>
public decimal OrderVolume
{
get => _orderVolume.Value;
set => _orderVolume.Value = value;
}
/// <summary>
/// Hour when the strategy can start opening positions.
/// </summary>
public int StartHour
{
get => _startHour.Value;
set => _startHour.Value = value;
}
/// <summary>
/// Hour when the strategy stops opening positions.
/// </summary>
public int EndHour
{
get => _endHour.Value;
set => _endHour.Value = value;
}
/// <summary>
/// Stop-loss size expressed in pips.
/// </summary>
public int StopLossPips
{
get => _stopLossPips.Value;
set => _stopLossPips.Value = value;
}
/// <summary>
/// Take-profit size expressed in pips.
/// </summary>
public int TakeProfitPips
{
get => _takeProfitPips.Value;
set => _takeProfitPips.Value = value;
}
/// <summary>
/// Trailing stop distance expressed in pips.
/// </summary>
public int TrailingStopPips
{
get => _trailingStopPips.Value;
set => _trailingStopPips.Value = value;
}
/// <summary>
/// Minimum price improvement required before moving the trailing stop.
/// </summary>
public int TrailingStepPips
{
get => _trailingStepPips.Value;
set => _trailingStepPips.Value = value;
}
/// <summary>
/// Candle type used by the strategy.
/// </summary>
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
/// <summary>
/// Initializes <see cref="FractalsAtClosePricesStrategy"/> parameters.
/// </summary>
public FractalsAtClosePricesStrategy()
{
_orderVolume = Param(nameof(OrderVolume), 0.1m)
.SetGreaterThanZero()
.SetDisplay("Order Volume", "Volume used for entries", "General")
;
_startHour = Param(nameof(StartHour), 0)
.SetRange(0, 23)
.SetDisplay("Start Hour", "Hour when trading can start (0-23)", "Trading Hours");
_endHour = Param(nameof(EndHour), 0)
.SetRange(0, 23)
.SetDisplay("End Hour", "Hour when trading stops (0-23)", "Trading Hours");
_stopLossPips = Param(nameof(StopLossPips), 200)
.SetRange(0, 1000)
.SetDisplay("Stop Loss (pips)", "Stop-loss distance in pips", "Risk Management")
;
_takeProfitPips = Param(nameof(TakeProfitPips), 400)
.SetRange(0, 1000)
.SetDisplay("Take Profit (pips)", "Take-profit distance in pips", "Risk Management")
;
_trailingStopPips = Param(nameof(TrailingStopPips), 15)
.SetRange(0, 1000)
.SetDisplay("Trailing Stop (pips)", "Base distance for the trailing stop", "Risk Management")
;
_trailingStepPips = Param(nameof(TrailingStepPips), 5)
.SetRange(0, 1000)
.SetDisplay("Trailing Step (pips)", "Additional move required before trailing", "Risk Management")
;
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
.SetDisplay("Candle Type", "Type of candles processed by the strategy", "General");
}
/// <inheritdoc />
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
{
return [(Security, CandleType)];
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_closeWindow.Clear();
_lastUpperFractal = null;
_previousUpperFractal = null;
_lastLowerFractal = null;
_previousLowerFractal = null;
_pipValue = 0m;
_stopLossDistance = 0m;
_takeProfitDistance = 0m;
_trailingStopDistance = 0m;
_trailingStepDistance = 0m;
_entryPrice = null;
ResetRiskLevels();
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var priceStep = Security?.PriceStep ?? 1m;
var decimals = Security?.Decimals ?? 0;
_pipValue = priceStep;
if (decimals == 3 || decimals == 5)
{
// MT5 version multiplies point value by 10 when the symbol uses 3 or 5 decimals.
_pipValue *= 10m;
}
_stopLossDistance = StopLossPips == 0 ? 0m : StopLossPips * _pipValue;
_takeProfitDistance = TakeProfitPips == 0 ? 0m : TakeProfitPips * _pipValue;
_trailingStopDistance = TrailingStopPips == 0 ? 0m : TrailingStopPips * _pipValue;
_trailingStepDistance = TrailingStepPips == 0 ? 0m : TrailingStepPips * _pipValue;
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;
}
UpdateFractals(candle);
if (!IsWithinTradingHours(candle.OpenTime))
{
CloseAllPositions();
return;
}
ApplyRiskManagement(candle);
// no bound indicators, skip IsFormedAndOnlineAndAllowTrading()
ExecuteEntries(candle);
}
private void UpdateFractals(ICandleMessage candle)
{
// Maintain a rolling window of the five most recent closes.
_closeWindow.Add(candle.ClosePrice);
while (_closeWindow.Count > 5)
_closeWindow.RemoveAt(0);
if (_closeWindow.Count < 5)
{
return;
}
var window = _closeWindow;
var center = window[2];
var isUpper = center > window[0]
&& center > window[1]
&& center >= window[3]
&& center >= window[4];
if (isUpper)
{
_previousUpperFractal = _lastUpperFractal;
_lastUpperFractal = center;
}
var isLower = center < window[0]
&& center < window[1]
&& center <= window[3]
&& center <= window[4];
if (isLower)
{
_previousLowerFractal = _lastLowerFractal;
_lastLowerFractal = center;
}
}
private bool IsWithinTradingHours(DateTimeOffset time)
{
var hour = time.Hour;
if (StartHour == EndHour)
{
// Trade the entire day when start and end hours are equal.
return true;
}
if (StartHour < EndHour)
{
return hour >= StartHour && hour < EndHour;
}
return hour >= StartHour || hour < EndHour;
}
private void ApplyRiskManagement(ICandleMessage candle)
{
if (Position > 0)
{
if (_longStop is decimal stop && candle.LowPrice <= stop)
{
// Close the long position if the stop-loss level is breached.
SellMarket(Position);
ResetRiskLevels();
return;
}
if (_longTake is decimal take && candle.HighPrice >= take)
{
// Close the long position when the take-profit level is hit.
SellMarket(Position);
ResetRiskLevels();
return;
}
UpdateLongTrailingStop(candle);
}
else if (Position < 0)
{
if (_shortStop is decimal stop && candle.HighPrice >= stop)
{
// Cover the short position if the stop-loss level is breached.
BuyMarket(Math.Abs(Position));
ResetRiskLevels();
return;
}
if (_shortTake is decimal take && candle.LowPrice <= take)
{
// Cover the short position when the take-profit level is hit.
BuyMarket(Math.Abs(Position));
ResetRiskLevels();
return;
}
UpdateShortTrailingStop(candle);
}
}
private void UpdateLongTrailingStop(ICandleMessage candle)
{
if (_trailingStopDistance <= 0m || _entryPrice is not decimal entry)
{
return;
}
var profitDistance = candle.ClosePrice - entry;
if (profitDistance <= _trailingStopDistance + _trailingStepDistance)
{
return;
}
var targetStop = candle.ClosePrice - _trailingStopDistance;
if (_longStop is decimal currentStop && currentStop >= candle.ClosePrice - (_trailingStopDistance + _trailingStepDistance))
{
// Skip updates until price improved by the trailing step.
return;
}
_longStop = targetStop;
}
private void UpdateShortTrailingStop(ICandleMessage candle)
{
if (_trailingStopDistance <= 0m || _entryPrice is not decimal entry)
{
return;
}
var profitDistance = entry - candle.ClosePrice;
if (profitDistance <= _trailingStopDistance + _trailingStepDistance)
{
return;
}
var targetStop = candle.ClosePrice + _trailingStopDistance;
if (_shortStop is decimal currentStop && currentStop <= candle.ClosePrice + (_trailingStopDistance + _trailingStepDistance))
{
// Skip updates until price improved by the trailing step.
return;
}
_shortStop = targetStop;
}
private void ExecuteEntries(ICandleMessage candle)
{
// Only trade when flat to avoid too frequent reversals.
if (Position != 0)
return;
var bullishTrend = _lastLowerFractal is decimal lastLow
&& _previousLowerFractal is decimal prevLow
&& prevLow < lastLow;
if (bullishTrend && OrderVolume > 0m)
{
BuyMarket(OrderVolume);
_entryPrice = candle.ClosePrice;
_longStop = _stopLossDistance > 0m ? candle.ClosePrice - _stopLossDistance : null;
_longTake = _takeProfitDistance > 0m ? candle.ClosePrice + _takeProfitDistance : null;
_shortStop = null;
_shortTake = null;
return;
}
var bearishTrend = _lastUpperFractal is decimal lastUp
&& _previousUpperFractal is decimal prevUp
&& prevUp > lastUp;
if (bearishTrend && OrderVolume > 0m)
{
SellMarket(OrderVolume);
_entryPrice = candle.ClosePrice;
_shortStop = _stopLossDistance > 0m ? candle.ClosePrice + _stopLossDistance : null;
_shortTake = _takeProfitDistance > 0m ? candle.ClosePrice - _takeProfitDistance : null;
_longStop = null;
_longTake = null;
}
}
private void CloseAllPositions()
{
if (Position > 0)
{
SellMarket(Position);
}
else if (Position < 0)
{
BuyMarket(Math.Abs(Position));
}
ResetRiskLevels();
}
private void CloseLongPosition()
{
if (Position > 0)
{
SellMarket(Position);
ResetRiskLevels();
}
}
private void CloseShortPosition()
{
if (Position < 0)
{
BuyMarket(Math.Abs(Position));
ResetRiskLevels();
}
}
private void ResetRiskLevels()
{
_longStop = null;
_longTake = null;
_shortStop = null;
_shortTake = null;
_entryPrice = null;
}
}
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 fractals_at_close_prices_strategy(Strategy):
def __init__(self):
super(fractals_at_close_prices_strategy, self).__init__()
self._start_hour = self.Param("StartHour", 0)
self._end_hour = self.Param("EndHour", 0)
self._stop_loss_pips = self.Param("StopLossPips", 200)
self._take_profit_pips = self.Param("TakeProfitPips", 400)
self._trailing_stop_pips = self.Param("TrailingStopPips", 15)
self._trailing_step_pips = self.Param("TrailingStepPips", 5)
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(4)))
self._close_window = []
self._last_upper_fractal = None
self._prev_upper_fractal = None
self._last_lower_fractal = None
self._prev_lower_fractal = None
self._pip_value = 0.0
self._sl_dist = 0.0
self._tp_dist = 0.0
self._trail_dist = 0.0
self._trail_step = 0.0
self._entry_price = None
self._long_stop = None
self._long_take = None
self._short_stop = None
self._short_take = None
@property
def CandleType(self):
return self._candle_type.Value
@CandleType.setter
def CandleType(self, value):
self._candle_type.Value = value
@property
def StartHour(self):
return self._start_hour.Value
@property
def EndHour(self):
return self._end_hour.Value
@property
def StopLossPips(self):
return self._stop_loss_pips.Value
@property
def TakeProfitPips(self):
return self._take_profit_pips.Value
@property
def TrailingStopPips(self):
return self._trailing_stop_pips.Value
@property
def TrailingStepPips(self):
return self._trailing_step_pips.Value
def OnStarted2(self, time):
super(fractals_at_close_prices_strategy, self).OnStarted2(time)
sec = self.Security
price_step = float(sec.PriceStep) if sec is not None and sec.PriceStep is not None else 1.0
decimals = sec.Decimals if sec is not None and sec.Decimals is not None else 0
self._pip_value = price_step
if decimals == 3 or decimals == 5:
self._pip_value *= 10.0
self._sl_dist = self.StopLossPips * self._pip_value if self.StopLossPips != 0 else 0.0
self._tp_dist = self.TakeProfitPips * self._pip_value if self.TakeProfitPips != 0 else 0.0
self._trail_dist = self.TrailingStopPips * self._pip_value if self.TrailingStopPips != 0 else 0.0
self._trail_step = self.TrailingStepPips * self._pip_value if self.TrailingStepPips != 0 else 0.0
self._close_window = []
self._last_upper_fractal = None
self._prev_upper_fractal = None
self._last_lower_fractal = None
self._prev_lower_fractal = None
self._entry_price = None
self._reset_risk_levels()
subscription = self.SubscribeCandles(self.CandleType)
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
self._update_fractals(candle)
if not self._is_within_trading_hours(candle.OpenTime):
self._close_all()
return
self._apply_risk_management(candle)
self._execute_entries(candle)
def _update_fractals(self, candle):
self._close_window.append(float(candle.ClosePrice))
while len(self._close_window) > 5:
self._close_window.pop(0)
if len(self._close_window) < 5:
return
w = self._close_window
center = w[2]
is_upper = (center > w[0] and center > w[1] and
center >= w[3] and center >= w[4])
if is_upper:
self._prev_upper_fractal = self._last_upper_fractal
self._last_upper_fractal = center
is_lower = (center < w[0] and center < w[1] and
center <= w[3] and center <= w[4])
if is_lower:
self._prev_lower_fractal = self._last_lower_fractal
self._last_lower_fractal = center
def _is_within_trading_hours(self, time):
hour = time.Hour
if self.StartHour == self.EndHour:
return True
if self.StartHour < self.EndHour:
return hour >= self.StartHour and hour < self.EndHour
return hour >= self.StartHour or hour < self.EndHour
def _apply_risk_management(self, candle):
high = float(candle.HighPrice)
low = float(candle.LowPrice)
close = float(candle.ClosePrice)
if self.Position > 0:
if self._long_stop is not None and low <= self._long_stop:
self.SellMarket()
self._reset_risk_levels()
return
if self._long_take is not None and high >= self._long_take:
self.SellMarket()
self._reset_risk_levels()
return
self._update_long_trailing(candle)
elif self.Position < 0:
if self._short_stop is not None and high >= self._short_stop:
self.BuyMarket()
self._reset_risk_levels()
return
if self._short_take is not None and low <= self._short_take:
self.BuyMarket()
self._reset_risk_levels()
return
self._update_short_trailing(candle)
def _update_long_trailing(self, candle):
if self._trail_dist <= 0 or self._entry_price is None:
return
close = float(candle.ClosePrice)
profit_dist = close - self._entry_price
if profit_dist <= self._trail_dist + self._trail_step:
return
target_stop = close - self._trail_dist
if self._long_stop is not None and self._long_stop >= close - (self._trail_dist + self._trail_step):
return
self._long_stop = target_stop
def _update_short_trailing(self, candle):
if self._trail_dist <= 0 or self._entry_price is None:
return
close = float(candle.ClosePrice)
profit_dist = self._entry_price - close
if profit_dist <= self._trail_dist + self._trail_step:
return
target_stop = close + self._trail_dist
if self._short_stop is not None and self._short_stop <= close + (self._trail_dist + self._trail_step):
return
self._short_stop = target_stop
def _execute_entries(self, candle):
if self.Position != 0:
return
close = float(candle.ClosePrice)
bullish_trend = (self._last_lower_fractal is not None and
self._prev_lower_fractal is not None and
self._prev_lower_fractal < self._last_lower_fractal)
if bullish_trend:
self.BuyMarket()
self._entry_price = close
self._long_stop = close - self._sl_dist if self._sl_dist > 0 else None
self._long_take = close + self._tp_dist if self._tp_dist > 0 else None
self._short_stop = None
self._short_take = None
return
bearish_trend = (self._last_upper_fractal is not None and
self._prev_upper_fractal is not None and
self._prev_upper_fractal > self._last_upper_fractal)
if bearish_trend:
self.SellMarket()
self._entry_price = close
self._short_stop = close + self._sl_dist if self._sl_dist > 0 else None
self._short_take = close - self._tp_dist if self._tp_dist > 0 else None
self._long_stop = None
self._long_take = None
def _close_all(self):
if self.Position > 0:
self.SellMarket()
elif self.Position < 0:
self.BuyMarket()
self._reset_risk_levels()
def _reset_risk_levels(self):
self._long_stop = None
self._long_take = None
self._short_stop = None
self._short_take = None
self._entry_price = None
def OnReseted(self):
super(fractals_at_close_prices_strategy, self).OnReseted()
self._close_window = []
self._last_upper_fractal = None
self._prev_upper_fractal = None
self._last_lower_fractal = None
self._prev_lower_fractal = None
self._pip_value = 0.0
self._sl_dist = 0.0
self._tp_dist = 0.0
self._trail_dist = 0.0
self._trail_step = 0.0
self._entry_price = None
self._reset_risk_levels()
def CreateClone(self):
return fractals_at_close_prices_strategy()