Hi,
1. How can pass a profit target variable from public override void Execute(BarHistory bars, int idx) loop into public override void AssignAutoStopTargetPrices(Transaction t, double basisPrice, double executionPrice), which is "1.03" in the example below?
2. On a red bar, it looks like covering a Short position does not work when the profit target falls below the Close price and above the Low price.
1. How can pass a profit target variable from public override void Execute(BarHistory bars, int idx) loop into public override void AssignAutoStopTargetPrices(Transaction t, double basisPrice, double executionPrice), which is "1.03" in the example below?
2. On a red bar, it looks like covering a Short position does not work when the profit target falls below the Close price and above the Low price.
CODE:
using WealthLab.Backtest; using System; using WealthLab.Core; using WealthLab.Indicators; using System.Drawing; using System.Collections.Generic; namespace WealthScript5 { public class SameBarAuto : UserStrategyBase { TimeSeries _band; public override void Initialize(BarHistory bars) { double pct = 0.95; _band = SMA.Series(bars.Close, 10) * pct; PlotTimeSeriesLine(_band, "band", "Price"); } public override void Execute(BarHistory bars, int idx) { if (HasOpenPosition(bars, PositionType.Long)) { //sell at open next bar PlaceTrade(bars, TransactionType.Sell, OrderType.Market); } else { //buy at market if the low goes below the band, but closes above it if (bars.Low.CrossesUnder(_band[idx], idx) && bars.Close[idx] > _band[idx]) PlaceTrade(bars, TransactionType.Buy, OrderType.Market); } } //same bar exits: 3% profit or loss from execution price public override void AssignAutoStopTargetPrices(Transaction t, double basisPrice, double executionPrice) { t.AutoProfitTargetPrice = executionPrice * 1.03; t.AutoStopLossPrice = executionPrice * 0.97; } } }
Rename
Example 1 -
Profit target depends on actual execution price
Example 2 -
Profit target does not depend on actual execution price
Re: 2
If the TransactionType is Short (not Buy), then you need to change the logic to handle that, e.g. -
Profit target depends on actual execution price
CODE:
using WealthLab.Backtest; using System; using WealthLab.Core; using WealthLab.Indicators; using System.Drawing; using System.Collections.Generic; namespace WealthScript5 { public class SameBarAuto : UserStrategyBase { TimeSeries _band; public override void Initialize(BarHistory bars) { double pct = 0.95; _band = SMA.Series(bars.Close, 10) * pct; PlotTimeSeriesLine(_band, "band", "Price"); } public override void Execute(BarHistory bars, int idx) { if (HasOpenPosition(bars, PositionType.Long)) { //sell at open next bar PlaceTrade(bars, TransactionType.Sell, OrderType.Market); } else { //buy at market if the low goes below the band, but closes above it if (bars.Low.CrossesUnder(_band[idx], idx) && bars.Close[idx] > _band[idx]) { Transaction t = PlaceTrade(bars, TransactionType.Buy, OrderType.Market); // assign a value or more values using a tuple to the Transaction Tag object to retrieve later. t.Tag = (1.05, 0.95); } } } public override void AssignAutoStopTargetPrices(Transaction t, double basisPrice, double executionPrice) { (double, double) tupleVals = ((double, double))t.Tag; t.AutoProfitTargetPrice = executionPrice * tupleVals.Item1; t.AutoStopLossPrice = executionPrice * tupleVals.Item2; } } }
Example 2 -
Profit target does not depend on actual execution price
CODE:
using WealthLab.Backtest; using System; using WealthLab.Core; using WealthLab.Indicators; using System.Drawing; using System.Collections.Generic; namespace WealthScript45 { public class SameBarAuto : UserStrategyBase { TimeSeries _band; public override void Initialize(BarHistory bars) { double pct = 0.95; _band = SMA.Series(bars.Close, 10) * pct; PlotTimeSeriesLine(_band, "band", "Price"); } public override void Execute(BarHistory bars, int idx) { if (HasOpenPosition(bars, PositionType.Long)) { //sell at open next bar PlaceTrade(bars, TransactionType.Sell, OrderType.Market); } else { //buy at market if the low goes below the band, but closes above it if (bars.Low.CrossesUnder(_band[idx], idx) && bars.Close[idx] > _band[idx]) { Transaction t = PlaceTrade(bars, TransactionType.Buy, OrderType.Market); // if execution price doesn't matter, just assign target now t.AutoProfitTargetPrice = bars.Close[idx] + 5; t.AutoStopLossPrice = bars.Close[idx] - 2.5; } } } } }
Re: 2
If the TransactionType is Short (not Buy), then you need to change the logic to handle that, e.g. -
CODE:
if (t.TransactionType == TransactionType.Short) - or if using the t.Tag, assign the correct values as appropriate
Re: 2
Wealth Lab 8 would not execute the trade if the profit target is below the Close on the picture attached, but it does execute
it if it is above the Close.
It looks like it is a bug. Please test it on your end.
Wealth Lab 8 would not execute the trade if the profit target is below the Close on the picture attached, but it does execute
It looks like it is a bug. Please test it on your end.
A profit target (a limit order) below the entry price on the same bar is not a valid order.
A broker wouldn't accept it, and if they did, it would result in an immediate exit.
A broker wouldn't accept it, and if they did, it would result in an immediate exit.
I am referring to a Short position.
It is illustrated on the picture attached. The profit target is below the Open and the entry price. The tester should execute the order regardless of the Close as long as it is below the Entry price. It does execute it only in the range between Open and the Close, but not below the Close.
It is wrong behavior. Looks like a bug.
It is illustrated on the picture attached. The profit target is below the Open and the entry price. The tester should execute the order regardless of the Close as long as it is below the Entry price. It does execute it only in the range between Open and the Close, but not below the Close.
It is wrong behavior. Looks like a bug.
I'm not able to confirm. Here's an example strategy that runs on SPY. It uses a limit order to exit at 558. The tester executes the order even though it is NOT in the range of open to close. All looks good in our backtester and I'm not seeing a bug.
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) { } //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(2025, 3, 5); if (bars.DateTimes[idx] == dt) { PlaceTrade(bars, TransactionType.Short, OrderType.Market); } if (HasOpenPosition(bars, PositionType.Short)) { PlaceTrade(bars, TransactionType.Cover, OrderType.Limit, 558); } } //declare private variables below } }
Please try on the same bar using public override void AssignAutoStopTargetPrices(Transaction t, double basisPrice, double executionPrice).
The illustration doesn't help. It only shows that "a trade" opened approximately at the opening price and "another trade" filled approximately at the close.
What placed the opening order?
Show the code, give me a symbol and a scale, and we'll discuss it. There's a lot of logic around same-bar orders and it depends how on the OrderType of the entry and exit orders and the market dynamics of that bar.
What placed the opening order?
Show the code, give me a symbol and a scale, and we'll discuss it. There's a lot of logic around same-bar orders and it depends how on the OrderType of the entry and exit orders and the market dynamics of that bar.
Here, it's working fine at my end.
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) { } //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(2025, 3, 5); if (bars.DateTimes[idx] == dt) { PlaceTrade(bars, TransactionType.Short, OrderType.Market); } if (HasOpenPosition(bars, PositionType.Short)) { PlaceTrade(bars, TransactionType.Cover, OrderType.Limit, 558); } } public override void AssignAutoStopTargetPrices(Transaction t, double basisPrice, double executionPrice) { t.AssignAutoProfitTargetPrice(570.13); } } }
There was a limit order to enter a short position. The next bar (the one on the picture) opened above the Limit. Short position entered at the opening price. Profit target is set to exit at a limit price that happens to be below the Close and above the Low of the bar, but wealth lab does not execute it. If I lift the target to be above the Close, wealth Lab does execute it. Wrong behavior.
On the picture that you attached, can you generate an exit at 571 on the same bar you entered your short?
On the picture that you attached, can you generate an exit at 571 on the same bar you entered your short?
I see that the difference between your code and mine is that you entered a short position with a Market order, but my code is using a Limit order. It is still supposed to behave the same way, but it does not.
That's not going to work because we can't be sure when both limit prices were achieved.
In that case, why is it working while the limit is in the range between Open and Close, but not below the Close?
Glitch, wl64bit described the Limit filled on the open condition. That's a special case that I can try to work in.
This order is essentially equivalent to a Market order for your test case.
This order is essentially equivalent to a Market order for your test case.
CODE:
PlaceTrade(bars, TransactionType.Short, OrderType.Limit, 575);
Any chances it will be fixed?
Sounds reasonable!
Any idea how long it might take to fix it?
Regarding question number 1, I would recommend adding another object that is designed to pass the Profit Target and Stop Loss to the AssignAutoStopTargetPrices, since the "Tag" might already be used for different purposes in the Execute loop.
Regarding question number 1, I would recommend adding another object that is designed to pass the Profit Target and Stop Loss to the AssignAutoStopTargetPrices, since the "Tag" might already be used for different purposes in the Execute loop.
There's really no need, just declare a private variable(s) to store any value(s) you want to access amongst methods.
Could you please provide an example of code on how to do that?
You declare a private variable in your class, we even have a comment
In your Execute method, or whereever else, you can assign a value to "stopValue." In AssignAutoStopTargetPrices you can use the value in the variable.
CODE:
//declare private variables below //example private double stopValue;
In your Execute method, or whereever else, you can assign a value to "stopValue." In AssignAutoStopTargetPrices you can use the value in the variable.
Your Response
Post
Edit Post
Login is required