public class CustomMinutesBreakout : Strategy
{
protected override void OnStateChange()
{
if (State == State.SetDefaults)
{
Description = @"Execute the breakout of the first N minutes";
Name = "CustomMinutesBreakout";
Calculate = Calculate.OnBarClose;
EntriesPerDirection = 1;
EntryHandling = EntryHandling.AllEntries;
IsExitOnSessionCloseStrategy = true;
ExitOnSessionCloseSeconds = 30;
IsFillLimitOnTouch = false;
MaximumBarsLookBack = MaximumBarsLookBack.TwoHundredFiftySix;
OrderFillResolution = OrderFillResolution.Standard;
Slippage = 0;
StartBehavior = StartBehavior.WaitUntilFlat;
TimeInForce = TimeInForce.Gtc;
TraceOrders = false;
RealtimeErrorHandling = RealtimeErrorHandling.StopCancelClose;
StopTargetHandling = StopTargetHandling.PerEntryExecution;
BarsRequiredToTrade = 20;
// Disable this property for performance gains in Strategy Analyzer optimizations
// See the Help Guide for additional information
IsInstantiatedOnEachOptimizationIteration = true;
StopTicks = 16;
ProfitTicks = 32;
}
else if (State == State.Configure)
{
SetStopLoss(CalculationMode.Ticks, StopTicks);
SetProfitTarget(CalculationMode.Ticks, ProfitTicks);
}
}
protected override void OnBarUpdate()
{
//Detecta que es el inicio de la sesion configurada en el Data Series
if(IsFirstTickOfBar && Bars.IsFirstBarOfSessionByIndex(CurrentBar))
{
//Reiniciar contador a 0
counter = 0;
//Reiniciar max y minimo de rango
rangeHigh = 0;
rangeLow = double.MaxValue;
//Establecer Inicio de rango
rangeStart = Time[0];
//Establecer booleado de "ejecutado" en falso
executed = false;
}
//Aumenta el contador en 1 unidad
counter++;
//Si el contador es igual a la propiedad Minutos
if(counter == Minutes)
{
Draw.VerticalLine(this, Time[0] + "sessionEnd", Time[0], Brushes.Yellow);
}
//Si el contador es mayor a la propiedad Minutos
if(counter > Minutes)
{
//Si estamos FLAT y NO hemos ejecutado
if(Position.MarketPosition == MarketPosition.Flat && !executed)
{
//Si se rompe el maximo del rango
if (High[0] > rangeHigh)
{
//Comprar
EnterLong();
//Booleano ejecutado verdadero
executed = true;
}
//Si se rompe el minimo del rango
else if (Low[0] < rangeLow)
{
//Vender
EnterShort();
//Booleano ejecutado en verdadero
executed = true;
}
}
}
else
{
//Actualizacion maximos y minimos rango
//Si el Maximo de la vela actual es mayor al Maximo del rango
if (High[0] > rangeHigh)
{//Actualizar el maximo del rango
rangeHigh = High[0];
}//Si el minimo de la vela actual es menor al minimo del rango
if (Low[0] < rangeLow)
{//Actualizar el minimo actual
rangeLow = Low[0];
}
Draw.Rectangle(this, "Range" + rangeStart, rangeStart, rangeHigh, Time[0], rangeLow, Brushes.Yellow);
}
}
public int Minutes { get; set; }
public int StopTicks { get; set; }
public int ProfitTicks { get; set; }
private int counter;
double rangeHigh;
double rangeLow;
DateTime rangeStart;
bool executed;
}
2 thoughts on “Creando estrategia automatica de ruptura de rango”
Excelente Jota, estrategias y programación posibilidades infinitas.
Saludos.
Oro molido! muchísimas gracias por compartir!!! 🙏