- ago
In my (renewed) quest to learn how to code strategies for WL i am looking at some strategy code posted by DrKoch (Danke!) to learn about properly handling exits in a coded strategy.

CODE:
Position p = LastOpenPosition; if(p != null) { ClosePosition(p, OrderType.Stop, _stopPrice, "Stop Loss"); if (p.IsOpen) { CloseAtTrailingStop(p, TrailingStopType.PercentC, 25, "Trailing Stop"); } }


Why are we checking for the position being open for the CloseAtTrailingStop call but not for the ClosePosition call?
0
512
Solved
13 Replies

Reply

Bookmark

Sort
Cone8
 ( 4.98% )
- ago
#1
It's not necessary. It's sufficient to test if p is null after being assigned to LastOpenPosition.
CODE:
Position p = LastOpenPosition; if(p != null) { ClosePosition(p, OrderType.Stop, _stopPrice, "Stop Loss"); CloseAtTrailingStop(p, TrailingStopType.PercentC, 25, "Trailing Stop"); }

If it's not null, the position is active. Both orders can be "placed".
The order with the closest stop will be used (and only that order will be signaled for live trading).
2
Best Answer
Glitch8
 ( 10.62% )
- ago
#2
Yes, if the Position instance is open in the first place, it will REMAIN open after the first call to ClosePosition. This is because WL8 mimics real trading by placing orders and does not know the RESULT of the orders until the whole Execute processing is completed for that iteration and the backtester goes to its post-close processing.

This is unlike WL6 where it was possible to cheat because exiting a position even using a stop/limit would in fact close the Position object if the target price was hit next bar. This led to potential subtle strategy coding errors.
2
- ago
#3
QUOTE:
... WL8 mimics real trading by placing orders and does not know the RESULT of the orders until ...

So you're saying both ClosePosition and CloseAtTrailingStop orders are required and must be coded (included) because there's no way to know which one is valid at the current "idx" bar-moment in time?

Honestly, I didn't know that. Is this documented somewhere? In the Help docs, if I click on C#CodeBased strategies, I get the message "Help topic not found".
0
Glitch8
 ( 10.62% )
- ago
#4
The basic structure of a WL strategy is outlined in the first blog article, Anatomy of a WL Strategy, in the web site Blog menu.
0
- ago
#5
QUOTE:
... first blog article, Anatomy of a WL Strategy,...

That's an excellent article, by the way. It illustrates how different variables have to be scoped (declared) in WL8. It also looks different from the first time I read it. (I'll have to read it again.)

But it doesn't talk about using the CloseAtTrailingStop call or PlaceTrade pruning. Perhaps that's saved for a future blog article? (I do appreciate you have a lot on your things-to-do list.)
0
Glitch8
 ( 10.62% )
- ago
#6
Yes there's so much going on in WL it can be hard to find every specific detail documented. To make up for this we provide on-demand answers here with an extremely quick turnaround time.
2
Cone8
 ( 4.98% )
- ago
#7
QUOTE:
So you're saying both ClosePosition and CloseAtTrailingStop orders are required and must be coded (included) because there's no way to know which one is valid at the current "idx" bar-moment in time?
I didn't say that at all. How can you imply that?

If you don't want the Stop order - remove it.
If you don't want the Trailing Stop order, remove it.
If you want both, then don't remove either one.

I simply rearranged the existing code for precisely the same functionality. Presumably, the Stop and Trailing Stop have different stop trigger prices. It should be clear that the "closest" stop price is the one that will be used, because it's the one that will be hit first.
1
- ago
#8
QUOTE:
If you want both, then don't remove either one.... the Stop and Trailing Stop have different stop trigger prices. It should be clear that the "closest" stop price is the one that will be used,...

And what about in a bracket order? In WL6, the order of the Stop and Limit order matters and if the first one is taken, then the following one is skipped in the nested IF statement. Is there a discussion thread that discusses WL8 bracket order protocol?
0
Glitch8
 ( 10.62% )
- ago
#9
You can see this is how WL6 is faulty. How can you know AT THE TIME OF PLACING THE ORDER whether the first order of the bracket will fill or not? In WL8 it simulates what you would do in reality, place both sides of the bracket order and wait UNTIL THE NEXT DAY to see what transpires.
0
- ago
#10
I guess we should have started a new topic for bracket order confusion....

In The WL6 code below, we "assume" the Stop order will fill (because it's the worst case scenario), but if the return code for the Stop order indicates it doesn't fill, then we execute the Limit order instead. (Notice the Limit order is nested inside the Stop order, which is standard practice for a WL6 bracket order.)
CODE:
{    double deltaStop = atr22[bar]*0.65; //for Close[bar]-deltaStop;    sigMsg.Desc = deltaStop.ToString("$0.00 ")+(deltaStop/Close[bar]).ToString("0.0%")+"=¾ATR";    if ( !SellAtStop(bar+1,pos,Close[bar]-deltaStop,sigMsg.Title("Bear trail stop TIF=GTC")) )       SellAtLimit(bar+1,pos,limitPrice.SellExtrapolated(Bars,bar,8,5,1.93),sigMsg.Title("Brkt limit sell")); }

So how do we code this in WL8? Are we just placing two PlaceTrades(...) for the Stop and Limit order, then WL8 waits until the following bar to figure out which one actually hits its execution price? No nested IF statement required?
0
Glitch8
 ( 10.62% )
- ago
#11
Right, you would not use an if statement. You'd just issue two PlaceTrades one after the other.
1
- ago
#12
So something like this (then) for a WL8 bracket order, and the order of the PlaceTrade statements doesn't matter?
CODE:
{    double deltaStop = atr22[idx] * 0.65; //for Close[idx]-deltaStop;    sigMsg.Desc = deltaStop.ToString("$0.00 ") + (deltaStop/Close[idx]).ToString("0.0%") + "=¾ATR";    PlaceTrade(bars, TransactionType.Sell,OrderType.Stop, Close[idx]-deltaStop, sigMsg.Title("Bear trail stop TIF=GTC"));    PlaceTrade(bars, TransactionType.Sell,OrderType.Limit, limitPrice.SellExtrapolated(bars,idx,8,5,1.93), sigMsg.Title("Brkt limit sell")); }
0
Glitch8
 ( 10.62% )
- ago
#13
That's right
1

Reply

Bookmark

Sort