- ago
Issue:
- Same-bar price-based StopLoss is not working if the trade entry is of type Stop but works OK with Market or Limit trade entries
- Affects all scales tested - Daily/Weekly/Monthly

-------------------------
P.S. I did *not* check if the issue also affects Short@Stop/Cover@AutoStop or percentage-based autostops.
------------

Test code (check it out using volatile stocks over different time scales):
CODE:
using WealthLab.Backtest; using System; using WealthLab.Core; using WealthLab.Data; 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) {          ind1 = new RSI(bars.Close,20);          PlotIndicator(ind1, WLColor.Blue, PlotStyle.Line, false, "pRSI");          DrawHorzLine(60, WLColor.Red, 1, LineStyle.Dashed, "pRSI"); } //execute the strategy rules here, this is executed once for each bar in the backtest history public override void Execute(BarHistory bars, int idx) { if (!HasOpenPosition(bars, PositionType.Long)) {             Transaction t = null;             if (ind1.CrossesUnder(60, idx))             {                SetBackgroundColor(bars, idx, WLColor.Red.SetAlpha(80));                //t = PlaceTrade(bars, TransactionType.Buy, OrderType.Market, 0, "Buy @Market");                //t = PlaceTrade(bars, TransactionType.Buy, OrderType.Limit, bars.Close[idx], "Buy @Limit");                t = PlaceTrade(bars, TransactionType.Buy, OrderType.Stop, bars.Close[idx], "Buy @Stop");             }             if (t != null)                t.AutoStopLossPrice = bars.Low[idx] - 0.01;      //does NOT work if Trade Entry is at Stop, works OK with Market or Limit          } else {             Position p = LastOpenPosition;             ClosePosition(p, OrderType.Limit, p.EntryPrice * 1.25, "Profit");             ClosePosition(p, OrderType.Stop, bars.Low[p.EntryBar - 1], "Stop");          } } //declare private variables below       private IndicatorBase ind1; } }


Pic 1:
Symbol: NAIL. Scale: Daily. Trade date: 1/20/23. Same-bar AutoStop executes correctly if Trade Entry is a Market or Limit order (Limit order shown).


Pics 2 & 3:
Symbol: NAIL. Scale: Daily. Trade date: 1/20/23. Same-bar AutoStop does NOT execute if Trade Entry is a Stop order. The price clearly violated the stop price (low of signal bar) *after* trade entry at the Open but the stop didn't execute.


0
488
11 Replies

Reply

Bookmark

Sort
Cone8
 ( 6.71% )
- ago
#1
Generally, for the stop entry/stop exit scenario, the order of trading within a bar cannot be determined - except if the Closing price would have triggered the order. Therefore, in a backtest, Close beyond the Stop trigger price is the only scenario WealthLab will fill a same-bar Stop exit after a Stop order entry fill.

However, the 1/20/23 NAIL case is a very specific scenario in which the entry stop order executed "on the Open", so it's essentially the Market order entry scenario. Let's see if we can make an exception for that scenario.

- Update -
Ready for Build 49
0
- ago
#2
Thanks for fixing that particular scenario.
--------------------

From a general, and broader, perspective I would like to share a few thoughts:
- I understand your desire to remove false positives from the backtest but if the solution also eliminates true positives then its not a good solution
- In the scenario I illustrated there was zero ambiguity but what if ambiguous situations arise especially when using higher-than-daily scales (see below)? My suggestion: Make the Trade dependent upon the Backtest > Exit Prioritization setting under Preferences so if the user uses Favor Stop let the pessimistic outcome prevail (i.e. both entry and exit were hit), if its Favor Limit let the optimistic outcome prevail (stop not hit) and if its Neutral then its a tossup... all the time assuming of course that the situation was truly ambiguous
- For higher-than-daily scales it would help immensely (I can't emphasize this enough) if Daily granularity could be made available under Strategy Settings > Backtest > Advanced > Use Granular Limit/Stop Processing
0
- ago
#3
@Cone,
I created a flowchart detailing Entry & Exit Price logic for Buy@Stop situations where the AutoStop could also have been hit on the same bar (reverse it for Short@Stop):



- if I missed a scenario let me know
- it does not cover "fat finger" situations where BuyStop < AutoStop
- this could also be used for Weekly and higher scales but the BEST solution for that, BY FAR, is to implement Daily granularity under Strategy Settings > Backtest Data
0
Cone8
 ( 6.71% )
- ago
#4
It's already complicated enough to get those the exits that we can determine with certainty - and we have you to thank for adding another missing scenario (Build 49).

Thanks for the extra effort, but I really don't think we're going to get into the minutia of guessing and randomizing intra-bar behavior that can't be predicted for same-bar exits in a backtest. Imho, this one clearly favors the KISS approach.

Probably Dion agrees (I haven't asked), but we're all on the same page to eventually extend granular processing for this purpose.
0
- ago
#5
QUOTE:
...exits that we can determine with certainty...

Instead of 'certainty' think of 'probability'.
The current logic is eliminating perfectly valid trades that actually executed in real-life but don't show up in the strategy. In my experience the eliminated true positives substantially exceed the false positives that you're aiming to remove. You can paper trade for a couple of months to verify for yourself.
I'm all for keeping things simple... but not to the point where they become (overly) simplistic.
Lastly, the Exit Priority settings are there for the user to steer the results the way they prefer... but what good are they if valid trades get eliminated?
0
- ago
#6
If I may simplify/condense things up to this point:

(A) In a general sense, for Stop entry and Stop/Profit same-bar exit the order of execution can be difficult to determine in the absence of granular data. However, on a deeper analysis all such trades can be grouped into one of two categories:
1. Unambiguous: e.g. the example I gave in the initial post. These can be handled by the trading logic easily.
2. Ambiguous: Most trades will likely fall in this category. Currently, they're being eliminated from further consideration. I suggest these be passed forward to the pool of trades subject to user-selected Exit Priority (under Preferences). Not only will this give the user what they chose but also ease the burden on the developers to try to create exit logic for every conceivable scenario.

(B) Make Daily granularity available for Weekly-and-higher scales so the price action can be further broken down and then handled as in (A) above; I suspect quite a few of the trades considered "Ambiguous" on the higher scale would get re-characterized as "Unambiguous" on the lower. In the absence of sub-scale granularity rules of (A) would still apply (even though they'll be less accurate).

I think with these changes the same-bar exits in backtests will be much closer to real-life trading.
0
- ago
#7
Using build 49.

In spite of the slightly expanded Entry logic, same-bar autostop Exits still not fully resolved. Here are 2 examples:

Slight change to autostop which will now be 1% below Low of signal bar (same change to open position's stop)
CODE:
t.AutoStopLossPrice = 0.99 * bars.Low[idx] - 0.01;


1) NAIL trade on WEEKLY bar dated 8/25/23:


The weekly chart (on left) shows that the exit would have occurred 3 bars later.
However, the daily chart (on right) of the 5 bars (enclosed in a rectangle) comprising the weekly bar shows that the BuyStop Entry occurred on the 1st bar and the autostop very probably also, but even if one is to argue that we're not 100% certain that the autostop was hit on the 1st bar then it was assuredly hit on the 5th bar - the daily granularity makes that clear.
Both Exit Priority and Daily granularity would have correctly executed the same-bar autostop.


2) JNUG trade on WEEKLY bar dated 8/23/19:


The weekly chart (on left) shows BuyStop entry on one bar and Profit Target-based exit on the next bar. Seems clear cut - the trade bar is a strong up candle with open near the bottom and close near the top - right? Hmm, let's examine in more detail .
The daily chart (on right) shows unambiguously that Entry and Exit occurred on the first daily bar of the week: Since the High is > prev week's Close the BuyStop was filled but since the Close of that bar was below the autostop price (meeting Cone's definition of "certainty") the autostop was executed on the same bar as well. The Daily granularity laid bare the true situation.
---------------------------


I request the developers to enable Exit Priority-based processing for all Stop entry orders (in any scale) and Daily granularity for weekly-and-higher scales.
0
Glitch8
 ( 11.74% )
- ago
#8
Sammy, the backtester does not consider daily data when processing a weekly bar. If you'd like to see this added you can submit a #FeatureRequest.
0
- ago
#9
Will write up a FeatureRequest. Was hoping to avoid that route since that list just keeps growing with very little activity (as I write this not a single item in the list is being worked upon).

In the meantime, please enable Backtest > Exit Prioritization rules to apply to same-bar exits for Stop-based entries.
0
Glitch8
 ( 11.74% )
- ago
#10
We needed to work on some bugs in the backlog before starting any new feature development. Also we had to work in migrating QData/Screener to a new server. Always something to do :)
0
- ago
#11
QUOTE:
We needed to work on some bugs...

In your bug sweep you may wish to consider not having Backtest > Exit Prioritization enabled for same-bar exits for Stop-based entries (its enabled for Market and Limit based entries) as an inadvertent omission/bug, too... the base code is already there, just needs to be enabled for Stop entries........... hint, hint... nudge, nudge... wink, wink. ;)
0

Reply

Bookmark

Sort