Diese Strategie konvertiert den MetaTrader-Experten Exp_FrAMACandle in eine StockSharp-High-Level-Strategie.
Strategielogik
Verwendet den Fractal Adaptive Moving Average (FrAMA), der separat für die Eröffnungs- und Schlusskurse der Kerzen berechnet wird.
Ein bullisches Signal tritt auf, wenn der FrAMA des Schlusskurses über den FrAMA des Eröffnungskurses steigt. Falls der vorherige Balken nicht bullisch war, öffnet die Strategie eine Long-Position und schließt bestehende Shorts.
Ein bärisches Signal tritt auf, wenn der FrAMA des Schlusskurses unter den FrAMA des Eröffnungskurses fällt. Falls der vorherige Balken nicht bärisch war, öffnet die Strategie eine Short-Position und schließt bestehende Longs.
Signale werden nur bei abgeschlossenen Kerzen ausgewertet. Historische Farbwerte werden gespeichert, um den SignalBar-Versatz zu berücksichtigen.
Parameter
Name
Beschreibung
CandleType
Zeitrahmen für die Indikatorberechnung. Standard: 4 Stunden.
FramaPeriod
Periode des FrAMA-Indikators.
SignalBar
Versatz des Balkens zur Signalerkennung.
BuyOpen / SellOpen
Eröffnung von Long-/Short-Positionen aktivieren.
BuyClose / SellClose
Schließen von Long-/Short-Positionen aktivieren.
Hinweise
Die Strategie basiert ausschließlich auf FrAMA-Kreuzungen und implementiert kein Stop-Loss- oder Take-Profit-Management.
Das Positionsvolumen wird durch die Basis-Volume-Eigenschaft der Strategie gesteuert.
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>
/// FrAMA candle trend-following strategy.
/// Uses FrAMA indicator for trend detection and trades on direction changes.
/// </summary>
public class FramaCandleTrendStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _framaPeriod;
private decimal _prevFramaValue;
private decimal _prevPrevFramaValue;
private bool _hasPrev;
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
public int FramaPeriod
{
get => _framaPeriod.Value;
set => _framaPeriod.Value = value;
}
public FramaCandleTrendStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
.SetDisplay("Candle Type", "Timeframe for indicator calculation", "General");
_framaPeriod = Param(nameof(FramaPeriod), 15)
.SetGreaterThanZero()
.SetDisplay("FrAMA Period", "Length of the Fractal Adaptive Moving Average", "Indicator");
}
/// <inheritdoc />
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
{
return [(Security, CandleType)];
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_prevFramaValue = 0;
_prevPrevFramaValue = 0;
_hasPrev = false;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_hasPrev = false;
_prevFramaValue = 0;
_prevPrevFramaValue = 0;
var frama = new FractalAdaptiveMovingAverage { Length = FramaPeriod };
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(frama, OnProcess)
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, frama);
DrawOwnTrades(area);
}
}
private void OnProcess(ICandleMessage candle, decimal framaValue)
{
if (candle.State != CandleStates.Finished)
return;
if (!_hasPrev)
{
_prevFramaValue = framaValue;
_hasPrev = true;
return;
}
// Trend direction from FrAMA slope
var rising = framaValue > _prevFramaValue;
var falling = framaValue < _prevFramaValue;
var wasRising = _prevFramaValue > _prevPrevFramaValue;
var wasFalling = _prevFramaValue < _prevPrevFramaValue;
// Buy on transition from falling to rising
if (rising && wasFalling && Position <= 0)
{
if (Position < 0) BuyMarket();
BuyMarket();
}
// Sell on transition from rising to falling
else if (falling && wasRising && Position >= 0)
{
if (Position > 0) SellMarket();
SellMarket();
}
_prevPrevFramaValue = _prevFramaValue;
_prevFramaValue = framaValue;
}
}
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 FractalAdaptiveMovingAverage
from StockSharp.Algo.Strategies import Strategy
class frama_candle_trend_strategy(Strategy):
def __init__(self):
super(frama_candle_trend_strategy, self).__init__()
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(4))) \
.SetDisplay("Candle Type", "Timeframe for indicator calculation", "General")
self._frama_period = self.Param("FramaPeriod", 15) \
.SetDisplay("FrAMA Period", "Length of the Fractal Adaptive Moving Average", "Indicator")
self._prev_frama_value = 0.0
self._prev_prev_frama_value = 0.0
self._has_prev = False
@property
def candle_type(self):
return self._candle_type.Value
@property
def frama_period(self):
return self._frama_period.Value
def OnReseted(self):
super(frama_candle_trend_strategy, self).OnReseted()
self._prev_frama_value = 0.0
self._prev_prev_frama_value = 0.0
self._has_prev = False
def OnStarted2(self, time):
super(frama_candle_trend_strategy, self).OnStarted2(time)
self._has_prev = False
frama = FractalAdaptiveMovingAverage()
frama.Length = self.frama_period
subscription = self.SubscribeCandles(self.candle_type)
subscription.Bind(frama, self.on_process).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawIndicator(area, frama)
self.DrawOwnTrades(area)
def on_process(self, candle, frama_value):
if candle.State != CandleStates.Finished:
return
frama_value = float(frama_value)
if not self._has_prev:
self._prev_frama_value = frama_value
self._has_prev = True
return
rising = frama_value > self._prev_frama_value
falling = frama_value < self._prev_frama_value
was_rising = self._prev_frama_value > self._prev_prev_frama_value
was_falling = self._prev_frama_value < self._prev_prev_frama_value
if rising and was_falling and self.Position <= 0:
if self.Position < 0:
self.BuyMarket()
self.BuyMarket()
elif falling and was_rising and self.Position >= 0:
if self.Position > 0:
self.SellMarket()
self.SellMarket()
self._prev_prev_frama_value = self._prev_frama_value
self._prev_frama_value = frama_value
def CreateClone(self):
return frama_candle_trend_strategy()