Welcome to NexusFi: the best trading community on the planet, with over 150,000 members Sign Up Now for Free
Genuine reviews from real traders, not fake reviews from stealth vendors
Quality education from leading professional traders
We are a friendly, helpful, and positive community
We do not tolerate rude behavior, trolling, or vendors advertising in posts
We are here to help, just let us know what you need
You'll need to register in order to view the content of the threads and start contributing to our community. It's free for basic access, or support us by becoming an Elite Member -- see if you qualify for a discount below.
-- Big Mike, Site Administrator
(If you already have an account, login at the top of the page)
Absolute beginner here, strategy not working, any help greatly appreciated!
So I recently started messing around with automated strategy development using the strategy builder, which I tested out with this super simple bollinger cross strategy.. It's supposed to enter when the ask or bid is above or below the band, and exit if there's an open position when that happens.. But when I backtested it on high resolution (1 tick), there were all these parts where it just totally ignored exits, and that resulted in a lot of losses. I'm confused, not really experienced with any of this.. If anyone can explain what's wrong with this so I can prevent it from happening, or if I'll have to debug it could you please walk me through that as if you were explaining it to a child? Thank you so much, and sorry I'm such a noob.. Here's the code:
namespace NinjaTrader.NinjaScript.Strategies
{
public class MyCustomStrategy : Strategy
{
private Bollinger Bollinger1;
protected override void OnStateChange()
{
if (State == State.SetDefaults)
{
Description = @"Enter the description for your new custom Strategy here.";
Name = "MyCustomStrategy";
Calculate = Calculate.OnEachTick;
EntriesPerDirection = 1;
EntryHandling = EntryHandling.AllEntries;
IsExitOnSessionCloseStrategy = false;
ExitOnSessionCloseSeconds = 30;
IsFillLimitOnTouch = false;
MaximumBarsLookBack = MaximumBarsLookBack.Infinite;
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)
{
Bollinger1 = Bollinger(2, 14);
Bollinger1.Plots[0].Brush = Brushes.SaddleBrown;
Bollinger1.Plots[1].Brush = Brushes.SaddleBrown;
Bollinger1.Plots[2].Brush = Brushes.SaddleBrown;
AddChartIndicator(Bollinger1);
}
}
protected override void OnBarUpdate()
{
if (CurrentBars[0] < 1)
return;
// Set 1
if ((GetCurrentAsk() > Bollinger1.Upper[0])
&& (Time[0].TimeOfDay >= new TimeSpan(7, 0, 0))
&& (Time[0].TimeOfDay < new TimeSpan(14, 30, 0)))
{
EnterShort(Convert.ToInt32(DefaultQuantity), "");
}
// Set 2
if ((GetCurrentBid() < Bollinger1.Lower[0])
&& (Time[0].TimeOfDay >= new TimeSpan(7, 0, 0))
&& (Time[0].TimeOfDay < new TimeSpan(14, 30, 0)))
{
EnterLong(Convert.ToInt32(DefaultQuantity), "");
}
// Set 3
if ((Position.MarketPosition == MarketPosition.Short)
&& (GetCurrentBid() < Bollinger1.Lower[0])
&& (Time[0].TimeOfDay >= new TimeSpan(7, 0, 0))
&& (Time[0].TimeOfDay < new TimeSpan(14, 30, 0)))
{
ExitShort(Convert.ToInt32(DefaultQuantity), "", "");
}
// Set 4
if ((Position.MarketPosition == MarketPosition.Long)
&& (GetCurrentAsk() > Bollinger1.Upper[0])
&& (Time[0].TimeOfDay >= new TimeSpan(7, 0, 0))
&& (Time[0].TimeOfDay < new TimeSpan(14, 30, 0)))
{
ExitLong(Convert.ToInt32(DefaultQuantity), "", "");
}
}
}
}
Can you help answer these questions from other members on NexusFi?
Not sure why I never tried that, but I'm running a backtest right now to see if that was it. I also tried it with an SMA set to 1, and had the same results... wouldn't that have the same effect as using the closing price?
Edit: backtest came back with the exact same results.
Stop using GetCurrentBid() or GetCurrentAsk(), they won't work in a backtest, just use Close[0]. Also you don't need to check the time in every if, make it its own if statement
Thanks, I will from now on.. But I still have the same problem; the backtest with Close[0] was identical to the GetCurrentBid() / GetCurrentAsk() backtest. Still missing exits. Any other ideas why it's not working?
Wow, thanks haha.. I'm an idiot for copying it to 4 sets.
protected override void OnBarUpdate()
{
if (CurrentBars[0] < 14) // this needs to more than 1, the bollinger alone needs 14 bars
return;
if ((Position.MarketPosition == MarketPosition.Flat) &&
((Time[0].TimeOfDay < new TimeSpan(7, 0, 0)) || (Time[0].TimeOfDay >= new TimeSpan(14, 30, 0))))
return;
if (Position.MarketPosition == MarketPosition.Flat)
{
if (Close[0] > Bollinger1.Upper[0])
EnterShort();
else if (Close[0] < Bollinger1.Lower[0])
EnterLong();
}
else if ((Position.MarketPosition == MarketPosition.Short) && (Close[0] < Bollinger1.Lower[0]))
ExitShort();
else if ((Position.MarketPosition == MarketPosition.Long) && (Close[0] > Bollinger1.Upper[0]))
ExitLong();
}
Huh.. Okay, wait, so it mostly fixed it, but (and this isn't that much of an issue) it does veery occasionally miss 1 exit.
It was always like 4 or 5 before, and quite often, so this is a massive improvement and I'd be very happy with it even if I can't make it perfect, but..
ah, whatever. I'm so happy I can move on to the rest of the strategy now!