region Using declarations
using System;
using System.Collections.Generic;
using NinjaTrader.Cbi;
using NinjaTrader.Gui.Tools;
using NinjaTrader.NinjaScript;
using NinjaTrader.Data;
using NinjaTrader.NinjaScript.Strategies;
using NinjaTrader.NinjaScript.Indicators;
#endregion
namespace NinjaTrader.NinjaScript.Strategies
{
public class MNQOptimizedScalpingV2 : Strategy
{
private EMA emaFast;
private EMA emaSlow;
private VWAP vwap;
private RSI rsi;
private Dictionary<string, DateTime> newsEvents;
// Optimizable Parameters
[NinjaScriptProperty]
[Range(5, 20), Optimize(8, 12, 1)]
public int FastEMAPeriod { get; set; }
[NinjaScriptProperty]
[Range(15, 50), Optimize(20, 30, 2)]
public int SlowEMAPeriod { get; set; }
[NinjaScriptProperty]
[Range(4, 15), Optimize(6, 10, 1)]
public int StopLossTicks { get; set; }
[NinjaScriptProperty]
[Range(6, 20), Optimize(8, 12, 1)]
public int ProfitTargetTicks { get; set; }
[NinjaScriptProperty]
[Range(4, 12), Optimize(6, 10, 1)]
public int TrailingStopTicks { get; set; }
protected override void OnStateChange()
{
if (State == State.SetDefaults)
{
Description = "Optimized MNQ Scalping with Trailing Stops & News Filters";
Name = "MNQOptimizedScalpingV2";
Calculate = Calculate.OnEachTick;
EntriesPerDirection = 1;
EntryHandling = EntryHandling.AllEntries;
StopTargetHandling = StopTargetHandling.PerEntryExecution;
IsExitOnSessionCloseStrategy = true;
ExitOnSessionCloseSeconds = 30;
IsFillLimitOnTouch = false;
Slippage = 1;
StartBehavior = StartBehavior.WaitUntilFlat;
AddDataSeries(Data.BarsPeriodType.Minute, 1);
// Define major news events (adjust as needed)
newsEvents = new Dictionary<string, DateTime>
{
{ "FOMC", new DateTime(2025, 2, 14, 14, 00, 0) }, // Example: FOMC statement at 2:00 PM
{ "NFP", new DateTime(2025, 2, 7, 8, 30, 0) }, // Example: Non-Farm Payrolls at 8:30 AM
{ "CPI", new DateTime(2025, 2, 13, 8, 30, 0) } // Example: CPI report at 8:30 AM
};
}
else if (State == State.Configure)
{
emaFast = EMA(FastEMAPeriod);
emaSlow = EMA(SlowEMAPeriod);
vwap = VWAP(VWAPResolution.Standard, 0, 0, 0);
rsi = RSI(14, 3);
AddChartIndicator(emaFast);
AddChartIndicator(emaSlow);
AddChartIndicator(vwap);
AddChartIndicator(rsi);
}
}
protected override void OnBarUpdate()
{
if (CurrentBar < SlowEMAPeriod) return; // Ensure enough bars exist
// Check if current time is near a high-impact news event
if (IsNewsEventUpcoming()) return;
bool longCondition = Close[0] > vwap.VWAPLine[0] && emaFast[0] > emaSlow[0] && rsi[0] > 50;
bool shortCondition = Close[0] < vwap.VWAPLine[0] && emaFast[0] < emaSlow[0] && rsi[0] < 50;
if (longCondition && Position.MarketPosition == MarketPosition.Flat)
{
EnterLong("LongEntry");
SetProfitTarget("LongEntry", CalculationMode.Ticks, ProfitTargetTicks);
SetStopLoss("LongEntry", CalculationMode.Ticks, StopLossTicks, false);
Draw.ArrowUp(this, "BuySignal_" + CurrentBar, true, 0, Low[0] - 5 * TickSize, Brushes.Green);
}
if (shortCondition && Position.MarketPosition == MarketPosition.Flat)
{
EnterShort("ShortEntry");
SetProfitTarget("ShortEntry", CalculationMode.Ticks, ProfitTargetTicks);
SetStopLoss("ShortEntry", CalculationMode.Ticks, StopLossTicks, false);
Draw.ArrowDown(this, "SellSignal_" + CurrentBar, true, 0, High[0] + 5 * TickSize, Brushes.Red);
}
// Apply Trailing Stop for active positions
ManageTrailingStop();
}
private void ManageTrailingStop()
{
if (Position.MarketPosition == MarketPosition.Long)
{
double newStop = Position.AveragePrice - (TrailingStopTicks * TickSize);
if (newStop > GetCurrentStopLoss()) SetStopLoss(CalculationMode.Price, newStop);
}
if (Position.MarketPosition == MarketPosition.Short)
{
double newStop = Position.AveragePrice + (TrailingStopTicks * TickSize);
if (newStop < GetCurrentStopLoss()) SetStopLoss(CalculationMode.Price, newStop);
}
}
private double GetCurrentStopLoss()
{
foreach (Order order in ActiveOrders)
{
if (order.OrderType == OrderType.StopMarket) return order.StopPrice;
}
return 0;
}
private bool IsNewsEventUpcoming()
{
foreach (var news in newsEvents)
{
DateTime eventTime = news.Value;
if (Time[0].Date == eventTime.Date && Math.Abs((Time[0].Hour * 60 + Time[0].Minute) - (eventTime.Hour * 60 + eventTime.Minute)) <= 10)
{
Print($"Skipping trade due to {news.Key} event at {eventTime}");
return true;
}
}
return false;
}
}
}

Comment