Estrategia de ruptura de líneas de tendencia definidas por el usuario. La estrategia calcula proyecciones lineales a partir de los parámetros de pendiente e intercepto tanto para las líneas alcistas como bajistas. Cuando el precio de cierre supera la línea de compra proyectada por un umbral, se abre una posición larga. Cuando el precio cae por debajo de la línea de venta menos el umbral, se entra en una posición corta.
Las posiciones están protegidas por valores de take profit y stop loss en ticks. Un stop trailing opcional actualiza el stop de protección conforme el precio se mueve a favor. Una opción adicional cierra la operación si la ruptura falla en la siguiente vela.
Detalles
Criterios de entrada:
Largo: Close > BuyLine + EntryThreshold
Corto: Close < SellLine - EntryThreshold
Largo/Corto: Ambos
Criterios de salida: Stop loss, take profit, stop trailing o señal opuesta
Stops:
Take profit en ticks
Stop loss en ticks
Stop trailing opcional en ticks
Cierre opcional por ruptura falsa en la siguiente vela
Valores predeterminados:
EntryThreshold = 15m
StopLossTicks = 50
TakeProfitTicks = 100
EnableTrailing = false
TrailingStepTicks = 5
FalseBreakClose = true
CandleType = TimeSpan.FromMinutes(5).TimeFrame()
BuyLineSlope = 0m
BuyLineIntercept = 0m
SellLineSlope = 0m
SellLineIntercept = 0m
Filtros:
Categoría: Ruptura de línea de tendencia
Dirección: Ambos
Indicadores: Ninguno
Stops: Sí
Complejidad: Medio
Marco temporal: Intradía
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>
/// Swing trader using EMA crossover.
/// </summary>
public class CoensioSwingTraderStrategy : Strategy
{
private readonly StrategyParam<int> _fastPeriod;
private readonly StrategyParam<int> _slowPeriod;
private readonly StrategyParam<DataType> _candleType;
private decimal _prevFast;
private decimal _prevSlow;
private bool _hasPrev;
public int FastPeriod { get => _fastPeriod.Value; set => _fastPeriod.Value = value; }
public int SlowPeriod { get => _slowPeriod.Value; set => _slowPeriod.Value = value; }
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public CoensioSwingTraderStrategy()
{
_fastPeriod = Param(nameof(FastPeriod), 12)
.SetGreaterThanZero()
.SetDisplay("Fast Period", "Fast EMA period", "Trading");
_slowPeriod = Param(nameof(SlowPeriod), 26)
.SetGreaterThanZero()
.SetDisplay("Slow Period", "Slow EMA period", "Trading");
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
.SetDisplay("Candle Type", "Candle type", "General");
}
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
=> [(Security, CandleType)];
protected override void OnReseted()
{
base.OnReseted();
_prevFast = 0;
_prevSlow = 0;
_hasPrev = false;
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var fast = new ExponentialMovingAverage { Length = FastPeriod };
var slow = new ExponentialMovingAverage { Length = SlowPeriod };
SubscribeCandles(CandleType)
.Bind(fast, slow, ProcessCandle)
.Start();
}
private void ProcessCandle(ICandleMessage candle, decimal fastVal, decimal slowVal)
{
if (candle.State != CandleStates.Finished) return;
if (!_hasPrev)
{
_prevFast = fastVal;
_prevSlow = slowVal;
_hasPrev = true;
return;
}
var crossUp = _prevFast <= _prevSlow && fastVal > slowVal;
var crossDown = _prevFast >= _prevSlow && fastVal < slowVal;
if (crossUp && Position <= 0)
{
if (Position < 0) BuyMarket();
BuyMarket();
}
else if (crossDown && Position >= 0)
{
if (Position > 0) SellMarket();
SellMarket();
}
_prevFast = fastVal;
_prevSlow = slowVal;
}
}