- ago
Using WL7.11.

Scenario:
- (Don't know if this is relevant but strategy uses Weekly bars)
- I like to add a Stop as soon as a new position is entered
- Relevant code:
CODE:
... Transaction t = null; t = PlaceTrade(bars, TransactionType.Buy, OrderType.Limit, lmt_prc); if (t != null) {    //LastPosition.RiskStopLevel = stp_prc;   //no WL7 eqvt yet, developers working on it    ClosePosition(LastPosition, OrderType.Stop, stp_prc); }


After upgrading to build 11, the ClosePosition line is generating an exception: Object reference not set to an instance of an object, presumably referencing the LastPosition object. The error was *not* present in build 10.

The following code, however, fixes the error probably b/c it's not referencing the LastPosition (note: I have not yet checked whether it impacts backtest results):
CODE:
if (t != null) {    //LastPosition.RiskStopLevel = stp_prc;   //no WL7 eqvt yet, developers working on it    //ClosePosition(LastPosition, OrderType.Stop, stp_prc); //giver error    PlaceTrade(bars, TransactionType.Sell, OrderType.Stop, stp_prc); }


I like to use ClosePosition. Perhaps the developers can take a look-see and see if this can be fixed. Not only is LastPosition an important object but since you are working on Same Bar Exits it may have a bearing on that as well.
(I wonder if this error is in any way related to PlotStopsAndLimits that, as of build 11, also works with ClosePosition, previously it only worked with PlaceTrade???..... just throwing it out there.)
0
354
16 Replies

Reply

Bookmark

Sort
- ago
#1
No need for that test for null because you'll always get a Transaction from PlaceTrade. But a simple check for LastPosition not being null fixes the code:

CODE:
PlaceTrade(bars, TransactionType.Buy, OrderType.Limit, lmt_prc); if (LastPosition != null) { //LastPosition.RiskStopLevel = stp_prc; //this feature is not being worked on ClosePosition(LastPosition, OrderType.Stop, stp_prc); }

But you're right, this seems to be related to PlotStopsAndLimits. Let's get this fixed in Build 12.
0
- ago
#2
Glad to hear it'll be fixed in the upcoming build!

QUOTE:
//LastPosition.RiskStopLevel = stp_prc; //this feature is not being worked on

Is that true? I had high hopes for this + AutoProfitLevel.
0
Cone8
 ( 24.57% )
- ago
#3
Re: AutoProfitLevel -
Vote for it!
https://www.wealth-lab.com/Discussion/Trading-Support-for-Same-Bar-exits-5951

There are other features with more votes now, but we'll get to it!
0
- ago
#4
Voted for it a long time ago.
I'm having a *real* issue with same-bar exits in some of my strategies, hope this will resolve them.
--------------------------------

Last Q:
QUOTE:
...you'll always get a Transaction from PlaceTrade...

What if it's a Limit order and the limit price is never reached on the next bar? Won't Transaction = null be true in that case?
0
Glitch8
 ( 10.41% )
- ago
#5
Transaction represents the order itself. What will happen is that a Position object will never get instantiated if the limit does not get filled.
0
- ago
#6
If I understand correctly, the mere act of Placing a trade satisfies the Transaction t != null argument so it will always be true regardless of the transaction actually completing. It's confusing.
0
Glitch8
 ( 10.41% )
- ago
#7
You just have to get used to the new backtesting model. It's superior to how WL6 does it, where WL6 returns a Position object which can either be null if the limit price was not met, or have a value if it did. At the bar on which the trade is placed, you'd have no way of knowing if it would get filled on the subsequent bar. So the fact that WL6 does it this way is a flaw. We improved it in WL7 by eliminating this possibility of the strategy acting on future information.
0
- ago
#8
QUOTE:
...WL6 returns a Position object which can either be null if the limit price was not met...


Which is exactly why in WL6 I used
CODE:
if (BuyAtLimit(bar + 1, lmt_prc, "") != null

before operating on the LastPosition object.
So Eugene's solution in Post #1
CODE:
if (LastPosition != null)

may be invalid because if the Transaction didn't get filled then the "LastPosition" could be from another (previously filled) transaction (or maybe even for another symbol), no?
1
Glitch8
 ( 10.41% )
- ago
#9
You're 100% correct. LastPosition will not get assigned until the following bar. You simply cannot obtain the position for the transaction on bar number N until bar number N+1, it does not exist yet.

LastPosition just returns the most recent Position object (open or closed) that happened to have been created.

LastOpenPosition returns the most recently created open Position, so it could be used to control whether the strategy code goes into a buy or a sell block.

But both of these properties return the Positions for the current symbol only. To get Positions from all symbols, you could use the GetPositionsAllSymbols method.
1
- ago
#10
I humbly submit that, for backtesting purposes *only* and when dealing with Limit orders, it's perfectly valid to peek at N+1 bar to see if the Position was created so one can operate on the LastPosition object on bar N (add Stop and/or Profit Target, pass some info as Position.Tag, etc.) b/c that's what one would do in real life.

I emphasize, *for backtesting purposes only*, this peeking is valid, even necessary.
0
- ago
#11
Consider this scenario: You want to buy a stock at 3% below today's Close; if it fills you want to set:
- 3% Profit Target
- 2% Stop Loss
- Sell at Close if above two not met

In real life: You will place a Day order for trade entry and attach 3 OCO (One Cancels Other) orders (as above) which only become active if the order fills.

In WL7: Can't be achieved on backtesting b/c it'll fill the position on N+1 bar (assuming limit price is met) then create the subsequent orders which will then get executed on the subsequent (N+2) bar. No wonder I can't get any trade-entry-bar exits!
0
Cone8
 ( 24.57% )
- ago
#12
It's a good argument that will most certainly have to be solved by introducing the AutoProfitTarget and RiskStopLevel. No worries.

I see the backtest working precisely how it would work if you were Auto-Trading:

1. You place the stop/limit order for the next bar and assign AutoProfitTarget and/or RiskStopLevel (to the next Position created).

2. If and when the initial order is filled, the target and/or stop orders go live for Auto-Trade. Likewise, the backtest would be able to fill these orders on the same bar.
0
- ago
#13
They will help, without a doubt.

However,
CODE:
LastPosition.Tag

will still remain unsolved. :(
0
- ago
#14
BTW, I was thinking of Daily/Weekly bars, not intraday.
0
Cone8
 ( 24.57% )
- ago
#15
You can use Transaction.Tag and pick it up later in the Position.Tag.

QUOTE:
I was thinking of Daily/Weekly bars, not intraday.
Sure. I didn't mention intraday, but I did say "Auto-Trade" - very observant! I think it can work the same way using non-intraday scales as long as the orders were placed with the Order Manager.
0
- ago
#16
Once I'm satisfied AutoProfitLevel & RiskStopLevel work reliable and as expected on backtesting I'll move on to Order Manager.

Cant' wait!!
0

Reply

Bookmark

Sort