Buy Price above Limit Order limit in backtests

Hello guys,

I have read the KB on running limit orders and searched the forum.

I'm using daily bars from Norgate.

After first getting really weird results (Buyprice lower than the low!!), I solved that problem by using 0 as the entryTradeDelay, unfortunately the KB didn't say what tradedelays were used.

Now my only problem is that I, sometimes, get a fill in the backtester with a Buy price above my limit...

I don't see how this can happen since the KB and my code set the BuyPrice to the Min between the open and the calculated limit.

Here is the Buy rules and Buy Price settings logic:

// 				Buy Rules

BuySignal = (ClosingRangePercent < ClosingRangeBottomingPercent) AND
			(PullbackPercentFromYesterday < (PullbackPercentFromYesterdayLimit*(-1))) AND
			(CRSI < CRSILimit) AND
			(C > MA(C,200)) AND
// buy on the next bar, cf Limit Order KB
Buy = Ref( BuySignal, -1) AND LiquidityFilter AND VolatilityFilter AND inRange;

BuyLimitPrice = Ref( Close, -1) * (100-BelowPreviousClosePercent)/100;

// now we check if limit was hit
Buy = Buy AND L < BuyLimitPrice;

// 				Buy Price

// if Open price is below the limit, then we use Open for entry
BuyPrice = Min( Open, BuyLimitPrice );

An example of a wrong Buy Price happen for example for this trade :

MLM 3/22/2021 Buy = 324.6219 in the backtester whereas the Limit order Price value is previous close 321.82*(100-2.24)/100 = 314.611232

Does any of you see where the problem is hidden ?

The full code that can be run wtih Norgate SP500 watchlist is available here:

Thanks a lot,


The MLM close on 3/19 was 332.06, and therefore the BuyPrice is exactly correct. The closing price that you quoted - 321.82 - is the closing price on the day of entry (3/22) and therefore not relevant.

Also, this is not a good way to implement limit orders because you're assuming you have sufficient capital to place orders for every setup that occurs. That's often not the case. If you reread the post that you referred to, you'll see that @Tomasz provided one potential solution to that problem. Another potential solution is to use a mid or low level CBT to limit the number of "orders" that are considered each day.

1 Like

Thanks a lot, you spotted my mistake...

Actually I screwed up with my google sheet verification... every "monday" entry were marked as wrong because I was checking with the day before (-1 in google sheets) instead of the friday closing price...

Yes I looked at the method of using "rank" displayed in the KB, however, unless I misunderstood something, it will only "try" to get a fill for the MaxPosition.

So let's say the MaxPosition is 7, it'll try and initiate a limit order on the top 7 tickers by rank.

The problem is that maybe you'll only get 1 or 2 fill out of these 7 tickers if the limit / pullback setting is quite high, e.g. 2% more pullback.

I need to investigate this further. I guess it really depends if the scan generates really too many limit orders or not, so maybe with high pullback / limit order settings you don't get that many orders (?)

With your current solution, you are not placing any restriction on the number of orders to consider. So, for example, if you have 20 setups on Monday then on Tuesday you might enter trades for Setups number 5, 10, 15 and 18 if those were the ones that breached the limit price.

With the solution in the article you referenced, you will restrict yourself to the top 7 (MaxPosition) setups, so on Tuesday you will only generate a trade entry for Setup #5.

However, what if on Monday you already have 4 positions open, implying that you only have capital to place 3 more orders? In this case, in live trading you would not get any fills, but the backtest would still enter a new trade for Setup #5. To resolve this issue requires the use of a CBT.

Thanks again, it's getting clearer and clearer : limit orders are not for the faint of heart !

I'll have to dig deeper into this, lots of good info in this topic

1 Like

This topic was automatically closed 100 days after the last reply. New replies are no longer allowed.