I'm trying to get my head around things and build my first simple strategy with Strategy builder.
Strategies from tutorials work, mine doesn't.
I want to wait for a pullback with very simple rules before taking a trade.
The rules:
- If the previous candle opened and closed above it's own median and the current candle's low falls below that median, go long and set profit and stop loss.
- If the previous candle opened and closed below it's own median and the current candle's high rises above that median go short and set profit and stop loss.
It complies fine but when I try to use it, I get this error:
1/24/2025 9:59:57 AM,Default,Strategy 'SimplePullBack': Error on calling 'OnStateChange' method: Object reference not set to an instance of an object.
#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
//This namespace holds Strategies in this folder and is required. Do not change it.
namespace NinjaTrader.NinjaScript.Strategies
{
public class SimplePullBack : Strategy
{
protected override void OnStateChange()
{
if (State == State.SetDefaults)
{
Description = @"Wait for a pullback";
Name = "SimplePullBack";
Calculate = Calculate.OnPriceChange;
EntriesPerDirection = 1;
EntryHandling = EntryHandling.AllEntries;
IsExitOnSessionCloseStrategy = true;
ExitOnSessionCloseSeconds = 30;
IsFillLimitOnTouch = false;
MaximumBarsLookBack = MaximumBarsLookBack.TwoHundredFiftySix;
OrderFillResolution = OrderFillResolution.Standard;
Slippage = 0;
StartBehavior = StartBehavior.WaitUntilFlat;
TimeInForce = TimeInForce.Gtc;
TraceOrders = false;
RealtimeErrorHandling = RealtimeErrorHandling.StopCancelClose;
StopTargetHandling = StopTargetHandling.PerEntryExecution;
BarsRequiredToTrade = 20;
// Disable this property for performance gains in Strategy Analyzer optimizations
// See the Help Guide for additional information
IsInstantiatedOnEachOptimizationIteration = true;
}
else if (State == State.Configure)
{
SetProfitTarget(@"Long", CalculationMode.Price, (Median[1] + 4) );
SetStopLoss(@"Long", CalculationMode.Price, (Median[1] - 2) , false);
SetProfitTarget(@"Short", CalculationMode.Price, (Median[1] - 4) );
SetStopLoss(@"Short", CalculationMode.Price, (High[1] - 2) , false);
}
}
protected override void OnBarUpdate()
{
if (BarsInProgress != 0)
return;
if (CurrentBars[0] < 1)
return;
// Set 1
if ((Open[1] > Median[1])
&& (Close[1] > Median[1])
&& (Low[0] < Median[1]))
{
EnterLong(Convert.ToInt32(DefaultQuantity), @"Long");
}
// Set 2
if ((Open[1] < Median[1])
&& (Close[1] < Median[1])
&& (High[0] > Median[1]))
{
EnterLong(Convert.ToInt32(DefaultQuantity), @"Short");
}
}
}
}
Thank you!

Comment