#region Using declarations using System; using System.ComponentModel; using System.ComponentModel.DataAnnotations; using NinjaTrader.Cbi; using NinjaTrader.Data; using NinjaTrader.Gui.Tools; using NinjaTrader.NinjaScript; #endregion namespace NinjaTrader.NinjaScript.Strategies { public class BK_ES : Strategy { [NinjaScriptProperty] [Display(Name = "HorarioInicioRango (HHmm)", GroupName = "Rango", Order = 1)] public int HorarioInicioRango { get; set; } [NinjaScriptProperty] [Display(Name = "HorarioFinalRango (HHmm)", GroupName = "Rango", Order = 2)] public int HorarioFinalRango { get; set; } [NinjaScriptProperty] [Display(Name = "HorarioOperativoInicio (HHmm)", GroupName = "Operativa", Order = 3)] public int HorarioOperativoInicio { get; set; } [NinjaScriptProperty] [Display(Name = "TP proporcional SL", GroupName = "Riesgo", Order = 4)] public double TPproporcionalSL { get; set; } [NinjaScriptProperty] [Display(Name = "Riesgo (USD)", GroupName = "Riesgo", Order = 5)] public double Riesgo { get; set; } [NinjaScriptProperty] [Display(Name = "Max Trades por Día", GroupName = "Operativa", Order = 6)] public int MaxTrades { get; set; } private const int HorarioOperativoFinal = 1400; private const int CierrePorVelas = 16; private const int SLticks = 160; private const int ExtenderBarras = 40; private const bool Lunes = true; private const bool Martes = false; private const bool Miercoles = true; private const bool Jueves = true; private const bool Viernes = true; private double rangoHigh; private double rangoLow; private int tradesCount; private bool oportunidadDisponible; private bool rangoListo; private double valorTick; private double riesgoPorContrato; private int contratos; protected override void OnStateChange() { if (State == State.SetDefaults) { Name = "BK_ES"; Calculate = Calculate.OnBarClose; EntriesPerDirection = 1; EntryHandling = EntryHandling.AllEntries; IsInstantiatedOnEachOptimizationIteration = false; IsExitOnSessionCloseStrategy = true; ExitOnSessionCloseSeconds = 30; HorarioInicioRango = 815; HorarioFinalRango = 830; HorarioOperativoInicio = 831; TPproporcionalSL = 1.0; Riesgo = 650; MaxTrades = 4; ResetDia(); } else if (State == State.Configure) { SetStopLoss(CalculationMode.Ticks, SLticks); SetProfitTarget(CalculationMode.Ticks, (int)Math.Round(SLticks * TPproporcionalSL)); } } private void ResetDia() { rangoHigh = double.MinValue; rangoLow = double.MaxValue; tradesCount = 0; oportunidadDisponible = false; rangoListo = false; } private int GetHHmm(DateTime t) { return ToTime(t) / 100; } protected override void OnBarUpdate() { if (CurrentBar < 2) return; if (Time[0].Date != Time[1].Date) ResetDia(); int diaNum = (int)Time[0].DayOfWeek; bool operarHoy = false; if (diaNum == 1 && Lunes) operarHoy = true; if (diaNum == 2 && Martes) operarHoy = true; if (diaNum == 3 && Miercoles) operarHoy = true; if (diaNum == 4 && Jueves) operarHoy = true; if (diaNum == 5 && Viernes) operarHoy = true; int hhmm = GetHHmm(Time[0]); if (hhmm >= HorarioInicioRango && hhmm <= HorarioFinalRango) { if (High[0] > rangoHigh) rangoHigh = High[0]; if (Low[0] < rangoLow) rangoLow = Low[0]; } if (!rangoListo && hhmm == HorarioFinalRango && rangoHigh > double.MinValue + 1 && rangoLow < double.MaxValue - 1) { rangoListo = true; } valorTick = TickSize * Instrument.MasterInstrument.PointValue; riesgoPorContrato = SLticks * valorTick; if (riesgoPorContrato > 0) { contratos = (int)Math.Floor(Riesgo / riesgoPorContrato); if (contratos < 1) contratos = 1; } else { contratos = 1; } if (!rangoListo) return; if (Close[0] >= rangoLow && Close[0] <= rangoHigh) oportunidadDisponible = true; if (operarHoy && hhmm >= HorarioOperativoInicio && hhmm <= HorarioOperativoFinal && tradesCount < MaxTrades && Position.MarketPosition == MarketPosition.Flat) { if (oportunidadDisponible && Close[0] > rangoHigh) { SetStopLoss(CalculationMode.Ticks, SLticks); SetProfitTarget(CalculationMode.Ticks, (int)Math.Round(SLticks * TPproporcionalSL)); EnterLong(contratos, "BreakoutLong"); tradesCount++; oportunidadDisponible = false; } } if (Position.MarketPosition == MarketPosition.Long) { if (BarsSinceEntryExecution() >= CierrePorVelas) ExitLong("Exit_CierreVel_L", "BreakoutLong"); } } } }