the code is here:
#region Using declarations
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;
using System.Windows.Media;
using System.Xml.Serialization;
using NinjaTrader.Cbi;
using NinjaTrader.Gui;
using NinjaTrader.Gui.Chart;
using NinjaTrader.Gui.SuperDom;
using NinjaTrader.Gui.Tools;
using NinjaTrader.Data;
using NinjaTrader.NinjaScript;
using NinjaTrader.Core.FloatingPoint;
using NinjaTrader.NinjaScript.Indicators;
using NinjaTrader.NinjaScript.DrawingTools;
#endregion
namespace NinjaTrader.NinjaScript.Strategies
{
public class rsiextreme : Strategy
{
private RSI rsi14;
private SMA sma16_67Hour;
private double stopLossPercentage = 0.01; // 1% stop loss
private double rsiEntryOverbought = 65;
private double rsiEntryOversold = 35;
private double rsiExitOverbought = 60;
private double rsiExitOversold = 40;
private int maPeriod; // Moving average period based on the bar interval
protected override void OnStateChange()
{
if (State == State.SetDefaults)
{
Description = "RSI with dynamic MA period for 16.67-hour duration, mean reversion, and stop loss.";
Name = "rsiextreme";
Calculate = Calculate.OnEachTick;
IsOverlay = false;
AddDataSeries(Data.BarsPeriodType.Minute, 5); // Default 5-minute bars, adjust as needed
}
else if (State == State.Configure)
{
CalculateMAPeriod();
rsi14 = RSI(Close, 14, 1);
sma16_67Hour = SMA(Close, maPeriod);
AddPlot(Brushes.Blue, "RSI");
AddPlot(Brushes.Red, "SMA");
}
}
protected override void OnBarUpdate()
{
if (CurrentBars[0] < maPeriod)
return;
// Recalculate the moving average period if the bar interval changes
if (BarsInProgress == 0)
{
CalculateMAPeriod();
sma16_67Hour = SMA(Close, maPeriod);
}
// Long Entry
if (rsi14[1] < rsiEntryOversold && Close[1] > sma16_67Hour[1])
{
EnterLong();
}
// Long Exit Condition #1
if (Position.MarketPosition == MarketPosition.Long && rsi14[1] > rsiExitOverbought)
{
ExitLong();
}
// Long Exit Condition #2
if (Position.MarketPosition == MarketPosition.Long)
{
double stopLossPrice = Position.AveragePrice - (stopLossPercentage * Position.AveragePrice);
if (Low[0] <= stopLossPrice)
{
ExitLong("StopLoss");
}
}
// Short Entry
if (rsi14[1] > rsiEntryOverbought && Close[1] < sma16_67Hour[1])
{
EnterShort();
}
// Short Exit Condition #1
if (Position.MarketPosition == MarketPosition.Short && rsi14[1] < rsiExitOversold)
{
ExitShort();
}
// Short Exit Condition #2
if (Position.MarketPosition == MarketPosition.Short)
{
double stopLossPrice = Position.AveragePrice + (stopLossPercentage * Position.AveragePrice);
if (High[0] >= stopLossPrice)
{
ExitShort("StopLoss");
}
}
}
// Method to calculate the moving average period based on the current bar interval
private void CalculateMAPeriod()
{
// Calculate the period in minutes for 16.67 hours
double minutes = 16.67 * 60;
// Calculate the period based on the current bar interval
double barInterval = BarsPeriod.Value; // Bar interval in minutes
maPeriod = (int)Math.Round(minutes / barInterval);
}
}
}

Comment