MIH8
- ago
In short, how do you know that the stop trigger occurs before the limit trigger on a bar? (of course talking of backtesting)
0
312
17 Replies

Reply

Bookmark

Sort
Cone8
 ( 28.25% )
- ago
#2
StopLimit is a Stop order that Limits the execution price if the stop is triggered. You get the the limit price or better for a limit order.

Generally, the limit is (should be) beyond the stop price for a StopLimit order - and most brokers only accept orders this way. If you put the limit "inside" the stop, you'll still get the stop price in backtesting because it's a better price than the limit when the stop is triggered. In live trading, you'll get the limit or better - or maybe no execution at all if no one takes your order.
0
- ago
#3
A StopLimit order is only activated if the Stop is breached; in which case it then becomes a simple Limit order.

With just EOD data it’s possible to know if that StopLimit order was eligible to activate (if Low<=Stop for a SELL; or High>=Stop for a Cover). However, with just EOD data it’s almost impossible to know for certain if the Limit price was ever visited after the Stop; Still, with some conditions based on the candle body, you can probably “guess” it most of the times (for example: if the Open/Close is near the Low/High).
Many years ago, I had a complex set of such conditions to try to determine it; if was probably accurate more than 80-90% of the time; the problem was the other 10-20%…

The only way to know for sure would be to increase the granularity of the data. But, in trading, life (and drawdowns) taught me the power of KISS: keep it to EOD and avoid (or better yet suppress) any uncertainty in the backtests (including not simulating with those ambiguous orders).
0
MIH8
- ago
#4
Hello everyone and thanks for the feedback.

@DrKoch
I was able to read your post before it was deleted. Well, it was a rhetorical question. But as for the 1:1 chance you mentioned, that is not true. The odds have to be measured in the context of the selected candles. This would require a clean distinction between whether the stop and the limit will occur in the right order.

@alkimist
I agree with you. The interesting thing about your comment is that the confidence level is important in order to interpret the backtest results correctly.

@Cone

CODE:
               Transaction t = PlaceTrade(bars, TransactionType.Buy, OrderType.StopLimit, 11.0,-1, "Buy");                t.StopLimitLimitPrice = 10;


In the given example the stop will be triggered at 11.0. From this point on it can drop back to 10 and trigger the limit order or it can move upwards on the bar and never come back. The current implementation in the backtest "always" triggers a StopLimit order if both prices occur within the bar. This is not realistic.
0
- ago
#5
To make things worse: I had situations where a SELL StopLimit order was activated, the Limit was actually below the stop and still I was not out of the market! If you would just look at the EOD data, there is no way I should not have gotten out of the position. However, apparently there was not enough buyers at the Limit price to absorb the size of my order (and from whoever was already first in line); and I am not talking about a theoretical scenario only affecting big funds (I’m an independent small trader after all); in times of down pressure, with everyone rushing through the door to get out, limits can be very dangerous!
0
Cone8
 ( 28.25% )
- ago
#6
Like I said, in the Buy at Stop Limit Scenario, putting the limit below the stop isn't accepted at most brokers. It might work at IB. Have at it.

In backtesting anything you do to guess the order of the prices other than assuming the Open is first and the Close is last, is just a guess. WealthLab activates the limit order if the stop is hit, that's all there is to it...however...

... the possibility for an enhancement would be to make Granular Limit/Stop Processing work for StopLimit. You can call it an oversight since we didn't expect anyone to use StopLimit in this messed up way. The primary incentive for StopLimit was to place a traditional limit on a stop order for live trading; not to create a pseudo strategy based prices advancing and then retreating.
0
MIH8
- ago
#7
QUOTE:

... not to create a pseudo strategy based prices advancing and then retreating. ...


Please do not judge things you have not seen or used before. The "idea" is quite common to trade after a price drop. Just look for "Knife Juggler" or "OneNight" in your library. The only difference is that a different price is chosen, defined by a stop level. To which price the limit price is related has nothing to do with how it is technically implemented.

It is also not unusual for stops and limits to be used in two directions, that has always been the case.

I assure you that there are many more things in trading that you have not seen than things that you know. That is true for all of us here. There is nothing unusual here.

The crucial thing is that this implementation delivers values in the backtest that are clearly too optimistic. But I also think that the results should and can be validated at a granular level (taking into account deviations given by intraday specifics).
0
Cone8
 ( 28.25% )
- ago
#8
Create a strategy that does it. We're not going to use StopLimit orders like that in WealthLab. Most brokers don't accept it. That's the truth.

0
Cone8
 ( 28.25% )
- ago
#9
By the way, the order works exactly the way you want it to for any broker that will accept the order. The issue is upgrading Granular processing for backtesting what would usually be an order-entry mistake, which we have to assume is intentional.
0
MIH8
- ago
#10
All right, accepted. For information only, I can say that IB accepts the orders. I came across the topic in this regard.

Thanks for the feedback.
0
MIH8
- ago
#11
Hello, after taking a deep breath, I would like to talk about the type of order again without diverting the focus to the introductory question.
Finally it is a bug report.

Part 1 - standard usage Buy-Stop-Limit order

In the following I am talking about a buy-stop-limit order and how it is used in principle. There is a stop-price < limit-price setup.



Above the bar is first the stop price and then the limit price. The buying price is shown below the bar. The error is that the buying price "15,52" is above the limit price "15.34". However, this should be avoided by the limit. This is why think it is a bug. (let's see what you think)

CODE:
            double sprice = price * 0.90;             double lprice = price * 0.96;                          Transaction t = PlaceTrade(bars, TransactionType.Buy, OrderType.Stop, sprice ,-1, "Buy");             t.StopLimitLimitPrice = lprice;


This time there is no confusion on my side about the order type specifics and the default usage of a buy stop-limit-order. ( i am sure you will help me to get confused again :-) ) It is a generally known order type as well as how it is basically applied.

Part 2 - unusual usage

To set the limit below the stop may be unexpected but is not forbidden. While the idea shown above is generally aimed at protecting yourself from an inflated price, you can also follow other ideas and use the same tool.

Before you comment that, I agree that it introduces unwanted complexity and should be avoided.

Part 3 - Common thing

You must compare the market price with the limit price no matter how this order type is applied.
0
Glitch8
 ( 12.08% )
- ago
#12
Hi MIH,

I tried to duplicate your bug report but so far could not. It looks like your limit price is below the low of the bar, yet the order is still getting filled at a higher price?

Do you have any slippage settings going?

Can you run the following on SPY and see if you can set the order prices in such a way to duplicate the issue? Thanks.

CODE:
using WealthLab.Backtest; using System; using WealthLab.Core; using WealthLab.Indicators; using System.Collections.Generic; namespace WealthScript1 { public class MyStrategy : UserStrategyBase { //create indicators and other objects here, this is executed prior to the main trading loop public override void Initialize(BarHistory bars) { } //execute the strategy rules here, this is executed once for each bar in the backtest history public override void Execute(BarHistory bars, int idx) {          DateTime dt = new DateTime(2022, 10, 12);          if (bars.DateTimes[idx] == dt)          {             Transaction t = PlaceTrade(bars, TransactionType.Buy, OrderType.StopLimit, 360);             t.StopLimitLimitPrice = 348;          } } } }
0
MIH8
- ago
#13
The reason why you did not get a signal for the SPY is, that at the date you check the signal, the High was below 360 (359.82). The next point is, that the limit-price should be above the stop-price in your code (as we check the buy limit price, not a sell).

CODE:
using WealthLab.Backtest; using System; using WealthLab.Core; using WealthLab.Indicators; using System.Collections.Generic; namespace WealthScript10 {    public class MyStrategy : UserStrategyBase    {       //create indicators and other objects here, this is executed prior to the main trading loop       public override void Initialize(BarHistory bars)       {       }       //execute the strategy rules here, this is executed once for each bar in the backtest history       public override void Execute(BarHistory bars, int idx)       {          DateTime dt = new DateTime(2022, 10, 03);          if (bars.DateTimes[idx] == dt)          {             double sprice = 365;             double lprice = 370; // 375                          Transaction t = PlaceTrade(bars, TransactionType.Buy, OrderType.StopLimit, sprice);             t.StopLimitLimitPrice = lprice;                          PlaceTrade(bars, TransactionType.Sell, OrderType.MarketClose, 0,"MC");             DrawBarAnnotation(string.Format("{0:N2} ", sprice)+" "+string.Format("{0:N2} ", lprice)+ "(" + idx+")",idx, true,WLColor.Red,10);          }       }    } }


What I need to check is if I accidentally looked at the wrong bar, as you can see in my screenshot there were a few more bars with a trade next to it. (I thought I had double checked, but you never know ...). My impression is that I need to look at the price information of the left bar and compare it with the buy-price of the middle bar instead of all the information on one bar. Anyway, the price would still be to high.

In the given example for the SPY i now get a signal but i can not see somthing wrong.
0
Glitch8
 ( 12.08% )
- ago
#14
OK, if you're able to nail down a concrete issue here that we can reproduce let me know!
0
MIH8
- ago
#15
ok, here a little code update and an example.

CODE:
            double sprice = price * 0.90;             double lprice = price * 0.96;             if(bars.Open[idx+1] <= lprice) return; // exclude from debugging for now             Transaction t = PlaceTrade(bars, TransactionType.Buy, OrderType.Stop, sprice ,-1, "Buy");             t.StopLimitLimitPrice = lprice;


The example is for VTRS on (signal 14.11) 15.11.2018. I used the WL S&P500 dataset. The slippage in my preferences is 0,1%



You will get a bunch of cases this way. You can do it for the SPY only too, butthe decimals displayed in the chart doesn't differ.
0
Glitch8
 ( 12.08% )
- ago
#16
Sorry, can you post the full code, I want to make sure I'm using your exact script and date. And, to see the issue I should run the code on VTRS?
0
MIH8
- ago
#17
I found the bug. It is sitting in front of the monitor.

I needed to recreate the code for you. This time i was not able to create the behaviour again. Playing with it i found, that i used a Stop Order instead of a StopLimit order. (I did it before when you look at the last code snippet i posted). Well, that is the most plausible reason i can find so far.

So, i mixed things up. Sorry for that and thanks for taking action, it helped in a different way.
0

Reply

Bookmark

Sort