Esta estrategia identifica bloques de órdenes "PowerZone" creados por una vela bajista seguida de velas alcistas consecutivas (y viceversa). Una ruptura por encima de la zona alcista activa una operación larga, mientras que una ruptura por debajo de la zona bajista abre una corta. Los objetivos y stops se basan en el rango de la zona.
Detalles
Criterios de entrada:
Largo: Vela bajista hace Periods+1 barras seguida de Periods velas alcistas y el precio rompe por encima del máximo de la zona.
Corto: Vela alcista hace Periods+1 barras seguida de Periods velas bajistas y el precio rompe por debajo del mínimo de la zona.
Largo/Corto: Ambos lados.
Criterios de salida: Take profit y stop loss como múltiplos del rango de la zona.
Indicadores: Ninguno.
Valores predeterminados:
Periods = 5
Threshold = 0
UseWicks = false
Take Profit Factor = 1.5
Stop Loss Factor = 1
Filtros:
Categoría: Ruptura
Dirección: Ambos
Indicadores: Ninguno
Stops: Sí
Complejidad: Moderado
Marco temporal: Cualquiera
Estacionalidad: No
Redes neuronales: No
Divergencia: No
Nivel de riesgo: Moderado
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>
/// PowerZone strategy using EMA crossover.
/// </summary>
public class PowerZoneStrategy : Strategy
{
private readonly StrategyParam<int> _slowLength;
private readonly StrategyParam<DataType> _candleType;
/// <summary>
/// Slow EMA period.
/// </summary>
public int SlowLength
{
get => _slowLength.Value;
set => _slowLength.Value = value;
}
/// <summary>
/// Candle type.
/// </summary>
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
/// <summary>
/// Initializes a new instance.
/// </summary>
public PowerZoneStrategy()
{
_slowLength = Param(nameof(SlowLength), 40)
.SetGreaterThanZero()
.SetDisplay("Slow Length", "Slow EMA period", "General");
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(5).TimeFrame())
.SetDisplay("Candle Type", "Candle type", "General");
}
/// <inheritdoc />
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
{
return [(Security, CandleType)];
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var fast = new ExponentialMovingAverage { Length = 14 };
var slow = new ExponentialMovingAverage { Length = SlowLength };
var prevF = 0m;
var prevS = 0m;
var init = false;
var lastSignal = DateTimeOffset.MinValue;
var cooldown = TimeSpan.FromMinutes(360);
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(fast, slow, (candle, f, s) =>
{
if (candle.State != CandleStates.Finished)
return;
if (!fast.IsFormed || !slow.IsFormed)
return;
if (!init)
{
prevF = f;
prevS = s;
init = true;
return;
}
if (candle.OpenTime - lastSignal >= cooldown)
{
if (prevF <= prevS && f > s && Position <= 0)
{
BuyMarket();
lastSignal = candle.OpenTime;
}
else if (prevF >= prevS && f < s && Position >= 0)
{
SellMarket();
lastSignal = candle.OpenTime;
}
}
prevF = f;
prevS = s;
})
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, fast);
DrawIndicator(area, slow);
DrawOwnTrades(area);
}
}
}