Estrategia Fibonacci Auto Trend Scouter
Esta estrategia utiliza dos extremos móviles basados en números Fibonacci para rastrear tendencias emergentes. La ventana corta (8) sigue los máximos y mínimos recientes, mientras que la ventana larga (21) proporciona contexto. Se abre una posición larga cuando el máximo de corto plazo supera el máximo de largo plazo. Se abre una posición corta cuando el mínimo de corto plazo cae por debajo del mínimo de largo plazo.
Detalles
- Criterios de entrada:
- Largo: máximo de corto plazo > máximo de largo plazo.
- Corto: mínimo de corto plazo < mínimo de largo plazo.
- Largo/Corto: Ambos.
- Criterios de salida:
- La posición se invierte ante la señal opuesta.
- Stops: No.
- Valores predeterminados:
Short period= 8Long period= 21
- Filtros:
- Categoría: Seguimiento de tendencia
- Dirección: Ambos
- Indicadores: Múltiples
- Stops: No
- Complejidad: Simple
- Marco temporal: Medio plazo
using System;
using System.Linq;
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>
/// Trend detection using Fibonacci period moving averages.
/// </summary>
public class FibonacciAutoTrendScouterStrategy : Strategy
{
private readonly StrategyParam<int> _smallPeriod;
private readonly StrategyParam<int> _mediumPeriod;
private readonly StrategyParam<DataType> _candleType;
private decimal _prevSmall;
private decimal _prevMedium;
private bool _isReady;
public int SmallPeriod { get => _smallPeriod.Value; set => _smallPeriod.Value = value; }
public int MediumPeriod { get => _mediumPeriod.Value; set => _mediumPeriod.Value = value; }
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public FibonacciAutoTrendScouterStrategy()
{
_smallPeriod = Param(nameof(SmallPeriod), 8)
.SetGreaterThanZero()
.SetDisplay("Small Period", "Small EMA period", "General");
_mediumPeriod = Param(nameof(MediumPeriod), 21)
.SetGreaterThanZero()
.SetDisplay("Medium Period", "Medium EMA period", "General");
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
.SetDisplay("Candle Type", "Candle Type", "General");
}
/// <inheritdoc />
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
=> [(Security, CandleType)];
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_prevSmall = 0;
_prevMedium = 0;
_isReady = false;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var emaSmall = new ExponentialMovingAverage { Length = SmallPeriod };
var emaMedium = new ExponentialMovingAverage { Length = MediumPeriod };
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(emaSmall, emaMedium, ProcessCandle)
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, emaSmall);
DrawIndicator(area, emaMedium);
DrawOwnTrades(area);
}
}
private void ProcessCandle(ICandleMessage candle, decimal small, decimal medium)
{
if (candle.State != CandleStates.Finished)
return;
if (!_isReady)
{
_prevSmall = small;
_prevMedium = medium;
_isReady = true;
return;
}
// Crossover detection
var crossUp = _prevSmall <= _prevMedium && small > medium;
var crossDown = _prevSmall >= _prevMedium && small < medium;
if (crossUp && Position <= 0)
BuyMarket();
else if (crossDown && Position >= 0)
SellMarket();
_prevSmall = small;
_prevMedium = medium;
}
}
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 fibonacci_auto_trend_scouter_strategy(Strategy):
def __init__(self):
super(fibonacci_auto_trend_scouter_strategy, self).__init__()
self._small_period = self.Param("SmallPeriod", 8) \
.SetDisplay("Small Period", "Small EMA period", "General")
self._medium_period = self.Param("MediumPeriod", 21) \
.SetDisplay("Medium Period", "Medium EMA period", "General")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(4))) \
.SetDisplay("Candle Type", "Candle Type", "General")
self._prev_small = 0.0
self._prev_medium = 0.0
self._is_ready = False
@property
def small_period(self):
return self._small_period.Value
@property
def medium_period(self):
return self._medium_period.Value
@property
def candle_type(self):
return self._candle_type.Value
def OnReseted(self):
super(fibonacci_auto_trend_scouter_strategy, self).OnReseted()
self._prev_small = 0.0
self._prev_medium = 0.0
self._is_ready = False
def OnStarted2(self, time):
super(fibonacci_auto_trend_scouter_strategy, self).OnStarted2(time)
ema_small = ExponentialMovingAverage()
ema_small.Length = self.small_period
ema_medium = ExponentialMovingAverage()
ema_medium.Length = self.medium_period
subscription = self.SubscribeCandles(self.candle_type)
subscription.Bind(ema_small, ema_medium, self.on_process).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawIndicator(area, ema_small)
self.DrawIndicator(area, ema_medium)
self.DrawOwnTrades(area)
def on_process(self, candle, small, medium):
if candle.State != CandleStates.Finished:
return
if not self._is_ready:
self._prev_small = small
self._prev_medium = medium
self._is_ready = True
return
# Crossover detection
cross_up = self._prev_small <= self._prev_medium and small > medium
cross_down = self._prev_small >= self._prev_medium and small < medium
if cross_up and self.Position <= 0:
self.BuyMarket()
elif cross_down and self.Position >= 0:
self.SellMarket()
self._prev_small = small
self._prev_medium = medium
def CreateClone(self):
return fibonacci_auto_trend_scouter_strategy()