#region Using declarations
using System;
using NinjaTrader.Cbi;
using NinjaTrader.Gui.Tools;
using NinjaTrader.NinjaScript;
using NinjaTrader.Data;
using NinjaTrader.NinjaScript.Strategies;
using NinjaTrader.NinjaScript.Indicators;
using System.ComponentModel.DataAnnotations; // Required for Display and
DisplayAttribute
#endregion
namespace NinjaTrader.NinjaScript.Strategies
{
public class HighWinRateIndicator : Strategy
{
// Declare moving averages, RSI, and ATR
private SMA fastSMA;
private SMA slowSMA;
private RSI rsi;
private ATR atr;
// Parameters for risk and reward
private double riskPercent = 1.0; // 1% risk per trade
private double rewardToRiskRatio = 2.0;
// User-adjustable inputs for optimization
[NinjaScriptProperty]
[Display(Name = "Fast SMA Period", Order = 1, GroupName = "Parameters")]
public int FastSMAPeriod { get; set; }
[NinjaScriptProperty]
[Display(Name = "Slow SMA Period", Order = 2, GroupName = "Parameters")]
public int SlowSMAPeriod { get; set; }
[NinjaScriptProperty]
[Display(Name = "RSI Period", Order = 3, GroupName = "Parameters")]
public int RSIPeriod { get; set; }
[NinjaScriptProperty]
[Display(Name = "RSI Overbought", Order = 4, GroupName = "Parameters")]
public double RSIOverbought { get; set; }
[NinjaScriptProperty]
[Display(Name = "RSI Oversold", Order = 5, GroupName = "Parameters")]
public double RSIOversold { get; set; }
[NinjaScriptProperty]
[Display(Name = "ATR Period", Order = 6, GroupName = "Parameters")]
public int ATRPeriod { get; set; }
[NinjaScriptProperty]
[Display(Name = "Risk Percent", Order = 7, GroupName = "Parameters")]
public double RiskPercent { get; set; }
[NinjaScriptProperty]
[Display(Name = "Reward to Risk Ratio", Order = 8, GroupName =
"Parameters")]
public double RewardToRiskRatio { get; set; }
[NinjaScriptProperty]
[Display(Name = "Stop Loss Multiplier", Order = 9, GroupName =
"Parameters")]
public double StopLossMultiplier { get; set; }
// Additional parameters to handle volatility filters, etc.
private double volatilityThreshold = 0.001;
protected override void OnStateChange()
{
if (State == State.SetDefaults)
{
// Set default settings
Description = "High Win Rate Strategy with Multi-Factor
Indicators";
Name = "HighWinRateIndicator";
Calculate = Calculate.OnEachTick;
IsOverlay = true;
FastSMAPeriod = 10;
SlowSMAPeriod = 50;
RSIPeriod = 14;
RSIOverbought = 70;
RSIOversold = 30;
ATRPeriod = 14;
RiskPercent = 1.0;
RewardToRiskRatio = 2.0;
StopLossMultiplier = 1.5;
}
else if (State == State.DataLoaded)
{
// Initialize the indicators
fastSMA = SMA(FastSMAPeriod);
slowSMA = SMA(SlowSMAPeriod);
rsi = RSI(RSIPeriod, 3);
atr = ATR(ATRPeriod);
}
}
protected override void OnBarUpdate()
{
// Check if enough bars are available for the indicators
if (CurrentBar < Math.Max(SlowSMAPeriod, ATRPeriod)) return;
// Volatility filter to skip quiet markets
if (Math.Abs(Close[0] - Close[1]) / Close[1] < volatilityThreshold)
return;
// Entry logic for a Long position: Fast SMA crosses above Slow SMA,
RSI not overbought
if (CrossAbove(fastSMA, slowSMA, 1) && rsi[0] < RSIOverbought)
{
// Position sizing based on risk
double atrValue = atr[0];
double stopLoss = atrValue * StopLossMultiplier;
double targetProfit = stopLoss * RewardToRiskRatio;
// Calculate the number of contracts to trade based on risk
double tradeRisk = stopLoss * TickSize;
double quantity = Math.Floor(AccountSize() * (RiskPercent / 100) /
tradeRisk);
// Enter long with calculated position size
EnterLong(Convert.ToInt32(quantity), "Long");
// Set stop-loss and take-profit dynamically
SetStopLoss("Long", CalculationMode.Price, Close[0] - stopLoss,
false);
SetProfitTarget("Long", CalculationMode.Price, Close[0] +
targetProfit);
}
// Entry logic for a Short position: Fast SMA crosses below Slow SMA,
RSI not oversold
if (CrossBelow(fastSMA, slowSMA, 1) && rsi[0] > RSIOversold)
{
// Position sizing based on risk
double atrValue = atr[0];
double stopLoss = atrValue * StopLossMultiplier;
double targetProfit = stopLoss * RewardToRiskRatio;
// Calculate the number of contracts to trade based on risk
double tradeRisk = stopLoss * TickSize;
double quantity = Math.Floor(AccountSize() * (RiskPercent / 100) /
tradeRisk);
// Enter short with calculated position size
EnterShort(Convert.ToInt32(quantity), "Short");
// Set stop-loss and take-profit dynamically
SetStopLoss("Short", CalculationMode.Price, Close[0] + stopLoss,
false);
SetProfitTarget("Short", CalculationMode.Price, Close[0] -
targetProfit);
}
// Exit logic for Long position: Fast SMA crosses below Slow SMA
if (CrossBelow(fastSMA, slowSMA, 1) && Position.MarketPosition ==
MarketPosition.Long)
{
ExitLong("ExitLong", "Long");
}
// Exit logic for Short position: Fast SMA crosses above Slow SMA
if (CrossAbove(fastSMA, slowSMA, 1) && Position.MarketPosition ==
MarketPosition.Short)
{
ExitShort("ExitShort", "Short");
}
}
// Function to get account size for position sizing
private double AccountSize()
{
return Account.Get(AccountItem.CashValue, Currency.UsDollar);
}
}
}