Estrategia basada en la Media Móvil Simple Adaptativa Fractal (FRASMAv2).
Esta estrategia calcula una Media Móvil Simple Adaptativa Fractal usando el indicador Fractal Dimension. El color del indicador cambia según la pendiente: verde para subida, gris para lateral, magenta para bajada. La estrategia observa las transiciones de color en la última vela cerrada:
Si el indicador era verde en la barra anterior y se vuelve no verde (gris o magenta) en la última barra, la estrategia cierra las posiciones cortas y abre una nueva posición larga.
Si el indicador era magenta y se vuelve no magenta, la estrategia cierra las posiciones largas y abre una nueva posición corta.
La gestión del riesgo utiliza los parámetros de stop-loss y take-profit especificados en puntos.
Detalles
Criterios de entrada: Cambios de color de FRASMAv2.
Largo/Corto: Ambas direcciones.
Criterios de salida: Transición de color opuesta.
Stops: Take profit y stop loss mediante módulo de protección.
Valores predeterminados:
Period = 30
TakeProfit = 2000 puntos
StopLoss = 1000 puntos
CandleType = TimeSpan.FromHours(4)
Filtros:
Categoría: Reversión de tendencia
Dirección: Ambos
Indicadores: FractalDimension, FRASMAv2
Stops: Sí
Complejidad: Intermedio
Marco temporal: 4h
Estacionalidad: No
Redes neuronales: No
Divergencia: No
Nivel de riesgo: Medio
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>
/// Strategy based on Fractal Adaptive Simple Moving Average (FRASMAv2).
/// Computes FRAMA from fractal dimension, trades on color (slope direction) changes.
/// </summary>
public class FrasmaV2Strategy : Strategy
{
private readonly StrategyParam<int> _period;
private readonly StrategyParam<DataType> _candleType;
private bool _isFirst;
private decimal _prevFrama;
private int _prevColor;
public int Period { get => _period.Value; set => _period.Value = value; }
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public FrasmaV2Strategy()
{
_period = Param(nameof(Period), 30)
.SetGreaterThanZero()
.SetDisplay("Period", "FRAMA calculation period", "Indicator");
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
.SetDisplay("Candle Type", "Type of candles", "General");
}
/// <inheritdoc />
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
{
return [(Security, CandleType)];
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_isFirst = true;
_prevFrama = 0;
_prevColor = 1;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_isFirst = true;
_prevFrama = 0;
_prevColor = 1;
var fdi = new FractalDimension { Length = Period };
var subscription = SubscribeCandles(CandleType);
subscription
.BindEx(fdi, ProcessCandle)
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawOwnTrades(area);
}
}
private void ProcessCandle(ICandleMessage candle, IIndicatorValue fdiValue)
{
if (candle.State != CandleStates.Finished)
return;
if (!fdiValue.IsFinal)
return;
var fdi = fdiValue.GetValue<decimal>();
var alpha = (decimal)Math.Exp(-4.6 * ((double)fdi - 1.0));
alpha = Math.Max(0.01m, Math.Min(1m, alpha));
var price = candle.ClosePrice;
var frama = _isFirst ? price : alpha * price + (1 - alpha) * _prevFrama;
int color;
if (_isFirst)
{
color = 1;
_isFirst = false;
}
else if (frama > _prevFrama)
color = 0; // Uptrend
else if (frama < _prevFrama)
color = 2; // Downtrend
else
color = 1; // Flat
// Uptrend ended (color was 0, now > 0) -> sell signal
if (_prevColor == 0 && color > 0 && Position >= 0)
SellMarket();
// Downtrend ended (color was 2, now < 2) -> buy signal
else if (_prevColor == 2 && color < 2 && Position <= 0)
BuyMarket();
_prevFrama = frama;
_prevColor = color;
}
}
import clr
import math
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 FractalDimension
from StockSharp.Algo.Strategies import Strategy
class frasma_v2_strategy(Strategy):
def __init__(self):
super(frasma_v2_strategy, self).__init__()
self._period = self.Param("Period", 30) \
.SetDisplay("Period", "FRAMA calculation period", "Indicator")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(4))) \
.SetDisplay("Candle Type", "Type of candles", "General")
self._is_first = True
self._prev_frama = 0.0
self._prev_color = 1
@property
def period(self):
return self._period.Value
@property
def candle_type(self):
return self._candle_type.Value
def OnReseted(self):
super(frasma_v2_strategy, self).OnReseted()
self._is_first = True
self._prev_frama = 0.0
self._prev_color = 1
def OnStarted2(self, time):
super(frasma_v2_strategy, self).OnStarted2(time)
self._is_first = True
self._prev_frama = 0.0
self._prev_color = 1
fdi = FractalDimension()
fdi.Length = self.period
subscription = self.SubscribeCandles(self.candle_type)
subscription.BindEx(fdi, self.process_candle).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawOwnTrades(area)
def process_candle(self, candle, fdi_value):
if candle.State != CandleStates.Finished:
return
if not fdi_value.IsFinal:
return
fdi = float(fdi_value)
alpha = math.exp(-4.6 * (fdi - 1.0))
alpha = max(0.01, min(1.0, alpha))
price = float(candle.ClosePrice)
if self._is_first:
frama = price
else:
frama = alpha * price + (1.0 - alpha) * self._prev_frama
if self._is_first:
color = 1
self._is_first = False
elif frama > self._prev_frama:
color = 0
elif frama < self._prev_frama:
color = 2
else:
color = 1
if self._prev_color == 0 and color > 0 and self.Position >= 0:
self.SellMarket()
elif self._prev_color == 2 and color < 2 and self.Position <= 0:
self.BuyMarket()
self._prev_frama = frama
self._prev_color = color
def CreateClone(self):
return frasma_v2_strategy()