using System;
using NinjaTrader.CBI;
using NinjaTrader.Data;
using NinjaTrader.NinjaScript;
namespace NinjaTrader.NinjaScript.Strategies
{
public class NQSimpleGridStrategy : Strategy
{
private EMA emaFast, emaSlow;
private ADX adx;
private RSI rsi;
private ATR atr;
private VWAP vwap;
private Bollinger bollinger;
private double gridSize; // Adaptif grid aralığı
private int gridLevels; // Grid seviye sayısı
private double lastPrice;
private double trailingStopDistance;
private bool dailyProfitReached;
private int baseLotSize = 1; // Temel lot büyüklüğü
private double dailyProfit; // Günlük kâr/zarar takibi
region Parameters
[NinjaScriptProperty]
[DisplayAttribute(Name = "Initial Capital ($)", Order = 1, GroupName = "Parameters")]
public double InitialCapital { get; set; }
[NinjaScriptProperty]
[DisplayAttribute(Name = "Grid Size Multiplier", Order = 2, GroupName = "Parameters")]
public double GridMultiplier { get; set; }
[NinjaScriptProperty]
[DisplayAttribute(Name = "Grid Levels", Order = 3, GroupName = "Parameters")]
public int GridLevels { get => gridLevels; set => gridLevels = value; }
[NinjaScriptProperty]
[DisplayAttribute(Name = "Manual Override", Order = 4, GroupName = "Parameters")]
public bool ManualOverride { get; set; }
#endregion
protected override void OnStateChange()
{
if (State == State.SetDefaults)
{
Name = "NQSimpleGridStrategy";
Calculate = Calculate.OnBarClose;
EntriesPerDirection = 5;
EntryHandling = EntryHandling.AllEntries;
IsExitOnSessionCloseStrategy = true;
ExitOnSessionCloseSeconds = 30;
InitialCapital = 50000;
GridMultiplier = 1.5;
gridSize = 10;
gridLevels = 3;
ManualOverride = false;
dailyProfit = 0;
}
else if (State == State.DataLoaded)
{
emaFast = EMA(Close, 10);
emaSlow = EMA(Close, 20);
adx = ADX(14);
rsi = RSI(Close, 14, 3);
atr = ATR(14);
vwap = VWAP();
bollinger = Bollinger(Close, 1.5, 20);
macd = MACD(Close, 12, 26, 9);
}
else if (State == State.Realtime)
{
dailyProfitReached = false;
dailyProfit = 0;
}
else if (State == State.Configure)
{
if (InitialCapital < 100000) gridLevels = 3;
}
}
protected override void OnBarUpdate()
{
if (BarsInProgress != 0 || CurrentBar < 20) return;
lastPrice = Close[0];
// Manuel override kontrolü
if (ManualOverride) return;
// Zaman filtresi: ABD piyasa saatleri (09:30-16:00 EST)
TimeSpan currentTime = Time[0].TimeOfDay;
if (currentTime < new TimeSpan(9, 30, 0) || currentTime > new TimeSpan(16, 0, 0))
return;
// Haber filtresi: Fed ve NFP (örnek, manuel devre dışı bırakılabilir)
if ((Time[0].DayOfWeek == DayOfWeek.Wednesday && currentTime >= new TimeSpan(13, 30, 0) && currentTime <= new TimeSpan(14, 30, 0)) ||
(Time[0].DayOfWeek == DayOfWeek.Friday && Time[0].Day <= 7 && currentTime >= new TimeSpan(8, 0, 0) && currentTime <= new TimeSpan(9, 0, 0)))
return;
// Günlük kâr/zarar sıfırlama ve kontrol
if (Time[0].Date != Time[1].Date)
{
dailyProfit = 0;
dailyProfitReached = false;
}
// Açık pozisyon kâr/zararını güncelle
if (Position.MarketPosition != MarketPosition.Flat)
{
dailyProfit += Position.GetUnrealizedProfitLoss(PerformanceUnit.C urrency);
}
if (dailyProfit < -2000 || dailyProfit >= 2000)
{
dailyProfitReached = dailyProfit >= 2000;
if (Position.MarketPosition != MarketPosition.Flat)
{
if (Position.MarketPosition == MarketPosition.Long) ExitLong("DailyLimit");
else if (Position.MarketPosition == MarketPosition.Short) ExitShort("DailyLimit");
}
return;
}
if (dailyProfitReached) return;
// Volatilite filtresi
double atrAverage = SMA(atr, 20)[0];
if (atr[0] < atrAverage * 0.8) return;
// Adaptif grid aralığı
gridSize = atr[0] * GridMultiplier;
// Trend tespiti (Bullish)
bool isBullish = emaFast[0] > emaSlow[0] && adx[0] > 25 && rsi[0] < 70 && lastPrice > vwap[0];
// Trend tespiti (Bearish)
bool isBearish = emaFast[0] < emaSlow[0] && adx[0] > 25 && rsi[0] > 30 && lastPrice < vwap[0];
// Dinamik pozisyon büyüklüğü ve kâr yeniden yatırımı
int lotSize = baseLotSize;
double totalProfit = SystemPerformance.AllTrades.TradesPerformance.Curr ency.CumProfit;
if (totalProfit > 5000) lotSize += (int)(totalProfit / 5000);
if (atr[0] > atrAverage) lotSize += 1;
// Grid emirleri (yalnızca trend yönünde)
if (Position.MarketPosition == MarketPosition.Flat && (isBullish || isBearish))
{
if (isBullish)
{
for (int i = 1; i <= gridLevels; i++)
{
double buyPrice = lastPrice - (i * gridSize * TickSize);
EnterLongLimit(lotSize, buyPrice, "GridBuy" + i);
}
}
else if (isBearish)
{
for (int i = 1; i <= gridLevels; i++)
{
double sellPrice = lastPrice + (i * gridSize * TickSize);
EnterShortLimit(lotSize, sellPrice, "GridSell" + i);
}
}
}
// Dinamik çıkışlar
trailingStopDistance = atr[0] * 2;
if (Position.MarketPosition == MarketPosition.Long)
{
double profitTarget = Position.AveragePrice + (atr[0] * 3 * TickSize);
ExitLongLimit(profitTarget, "ProfitTarget");
ExitLongStopMarket(Math.Max(Position.AveragePrice, Close[0] - trailingStopDistance), "TrailingStop");
}
else if (Position.MarketPosition == MarketPosition.Short)
{
double profitTarget = Position.AveragePrice - (atr[0] * 3 * TickSize);
ExitShortLimit(profitTarget, "ProfitTarget");
ExitShortStopMarket(Math.Min(Position.AveragePrice , Close[0] + trailingStopDistance), "TrailingStop");
}
}
protected override void OnExecutionUpdate(Execution execution, string executionId, double price, int quantity, MarketPosition marketPosition, string orderId, DateTime time)
{
if (execution.Order != null && execution.Order.OrderState == OrderState.Filled)
{
double tradeProfit = execution.Order.Filled * execution.Order.AverageFillPrice *
(marketPosition == MarketPosition.Long ? 1 : -1) * TickSize * 20; // NQ için 1 tick = $20
dailyProfit += tradeProfit - (quantity * 2.25); // Komisyon düşülür ($2.25/trade)
}
}
}
}

Comment