- ago
This is the script I use in Tradestation

If close < close[3] then Sell Short 100 Shares this Bar on Close;
If close > close[3] then Buy 100 Shares this Bar on Close;

Is this possible with WL ?
0
627
Solved
18 Replies

Reply

Bookmark

Sort
- ago
#1
First, is this a stop-and-reverse system or the "Buy" actually means "Cover"?
0
- ago
#2
1. Switch to Weekly data scale on Strategy Settings tab.

2. Assuming Short/Cover. In Blocks it's not possible to enter/exit on the same bar's close. With the PowerPack extension you can use next bar's close as depicted:

0
- ago
#3
0
Cone8
 ( 23.69% )
- ago
#4
hakem, for those like me who have never used TradeStation, what are we looking at?

Is it:
A: Shorting 100 shares and then Covering 100 shares
or
B: Shorting 100 shares, and then Buying 200 shares (by Covering 100 shares and Buying 100 shares), and then Selling 200 shares (Selling 100 shares and Shorting 100 shares)?
0
- ago
#5
It is a stop-and-reverse system.
0
- ago
#6
Shorting 100 shares, and then Buying 200 shares (by Covering 100 shares and Buying 100 shares), and then Selling 200 shares (Selling 100 shares and Shorting 100 shares)
0
Cone8
 ( 23.69% )
- ago
#7
In that case, you just need to add the same block rules for BuyAtMarket and SellAtMarket signals.

WealthLab works with Positions. So each leg of the trade has 2 transactions - a Buy/Cover or a Sell/Short.

Here's what it looks like in a C# script -
CODE:
using WealthLab.Backtest; using System; using WealthLab.Core; using WealthLab.Data; using WealthLab.Indicators; namespace WealthScript5 { 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) {          StartIndex = 3; } //execute the strategy rules here, this is executed once for each bar in the backtest history public override void Execute(BarHistory bars, int idx) {          Position p = LastPosition;          if (p == null || HasOpenPosition(bars, PositionType.Short))             if (bars.Close[idx] > bars.Close[idx - 3])             {                ClosePosition(p, OrderType.Market);                PlaceTrade(bars, TransactionType.Buy, OrderType.Market);             }         if (p == null || HasOpenPosition(bars, PositionType.Long))        if (bars.Close[idx] < bars.Close[idx - 3])             {                ClosePosition(p, OrderType.Market);                PlaceTrade(bars, TransactionType.Short, OrderType.Market);                         } } //declare private variables below } }
0
Cone8
 ( 23.69% )
- ago
#8
I just noticed in your TS image that the trades are occurring on the Close. We purposely don't allow this type of unrealizable trading in the Building Blocks, but if you really want to do it, you have to purposely peek ahead in a C# script - which won't be able to give you Signals.

Peeking script for AtClose orders that duplicates your TS trades.

CODE:
using WealthLab.Backtest; using System; using WealthLab.Core; using WealthLab.Data; using WealthLab.Indicators; namespace WealthScript5 { 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) {          StartIndex = 3; } //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 (idx == bars.Count - 1) return;          Position p = LastPosition;          if (p == null || HasOpenPosition(bars, PositionType.Short))             if (bars.Close[idx + 1] > bars.Close[idx - 2])             {                ClosePosition(p, OrderType.MarketClose);                PlaceTrade(bars, TransactionType.Buy, OrderType.MarketClose);             }         if (p == null || HasOpenPosition(bars, PositionType.Long))        if (bars.Close[idx + 1] < bars.Close[idx - 2])             {                ClosePosition(p, OrderType.MarketClose);                PlaceTrade(bars, TransactionType.Short, OrderType.MarketClose);                         } } } }

Of course, this is a worthwhile exercise for backtesting, and on a Weekly scale you probably could estimate if an AtClose trade would be triggered and put in a MOC order 5 or 6 minutes before the close on Nasdaq.
1
Best Answer
- ago
#9
Thank You Cone !

It executes at the next open.

Is it possible to execute at the close of this bar ?
0
Cone8
 ( 23.69% )
- ago
#10
Beat you to it - see Post #8
0
- ago
#11
Thank You Cone !

Now it executes at the close !
0
- ago
#12
Now the next step would be to take the QQQ Long Short only as signal.

When QQQ ROC 3W gives a short signal the strategy should sell short
the stock from NDX100 with the lowest ROC 3W at that time.

Is this possible with WL ?
0
- ago
#13
Transaction Weight.
0
Cone8
 ( 23.69% )
- ago
#14
QUOTE:
Is this possible with WL ?
This is almost always the wrong question, and you've asked it twice already. The right question is, "how do you do this in WealthLab"?
.. and there are usually multiple answers to that question.

The one Eugene suggested somewhat cryptically is to add a Transaction Weight rule (or block) to prioritize trade candidates. If you're trading with 100% equity (make sure to use margin if you do that), then the stock(s) with the highest weight(s) will be the one selected.

Since you can't do the AtClose strategy in the blocks, here you go - run it on a DataSet, use 100% Equity sizing (to trade 1 symbol at a time, 50% for 2, etc.) and be sure to include margin so that you don't miss any trades.

CODE:
using WealthLab.Backtest; using System; using WealthLab.Core; using WealthLab.Data; using WealthLab.Indicators; namespace WealthScript123 {    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)       {          StartIndex = 3;       }       //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 (idx == bars.Count - 1) return;          Position p = LastPosition;          if (p == null || HasOpenPosition(bars, PositionType.Short))             if (bars.Close[idx + 1] > bars.Close[idx - 2])             {                ClosePosition(p, OrderType.MarketClose);                Transaction t = PlaceTrade(bars, TransactionType.Buy, OrderType.MarketClose);                t.Weight = ROC.Series(bars.Close, 3)[idx];      // pick the highest ROC             }          if (p == null || HasOpenPosition(bars, PositionType.Long))             if (bars.Close[idx + 1] < bars.Close[idx - 2])             {                ClosePosition(p, OrderType.MarketClose);                Transaction t = PlaceTrade(bars, TransactionType.Short, OrderType.MarketClose);                t.Weight = -1 * ROC.Series(bars.Close, 3)[idx];      // pick the lowest ROC             }       }    } }

But remember, since you're trading AtClose, you will not get Signals - you will only see the trades here after the fact. To trade it, you would have to use intraday data to calculate the 3-week ROC estimate for all symbols before the close, perform a sort, pick the ones with the highest/lower ROC, and enter your MOC orders at least 5 minutes before the close on Nasdaq.
0
- ago
#15
But how to set up that the QQQ is taken for the Long Short signals ?
0
- ago
#16
QUOTE:
But how to set up that the QQQ is taken for the Long Short signals ?

If my understanding is correct, you're looking at the external symbol's price dynamics? Check if this is what you're after then:
CODE:
using WealthLab.Backtest; using System; using WealthLab.Core; using WealthLab.Data; using WealthLab.Indicators; namespace WealthScript123 {    public class MyStrategy : UserStrategyBase    {       BarHistory qqq;              //create indicators and other objects here, this is executed prior to the main trading loop       public override void Initialize(BarHistory bars)       {          qqq = GetHistory(bars, "QQQ");          PlotBarHistory(qqq, "qqqPane", WLColor.Silver);                    StartIndex = 3;       }       //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 (idx == bars.Count - 1) return;          Position p = LastPosition;          if (p == null || HasOpenPosition(bars, PositionType.Short))             if (qqq.Close[idx + 1] > qqq.Close[idx - 2])             {                ClosePosition(p, OrderType.MarketClose);                Transaction t = PlaceTrade(bars, TransactionType.Buy, OrderType.MarketClose);                t.Weight = ROC.Series(bars.Close, 3)[idx]; // pick the highest ROC             }          if (p == null || HasOpenPosition(bars, PositionType.Long))             if (qqq.Close[idx + 1] < qqq.Close[idx - 2])             {                ClosePosition(p, OrderType.MarketClose);                Transaction t = PlaceTrade(bars, TransactionType.Short, OrderType.MarketClose);                t.Weight = -1 * ROC.Series(bars.Close, 3)[idx]; // pick the lowest ROC             }       }    } }
0
- ago
#17
Position Symbol Quantity Entry Date Entry Price Exit Date Exit Price
Short ROST 84 09.12.2022 114,89 13.01.2023 120,01
Short ALGN 30 24.02.2023 306,28 Open 0

There is still a problem.

Entry and Exit dates are exactly what the QQQ ROC 3W is pretending.
But the trade for ROST at 09.12.2022 should be Long and not Short !
0
Cone8
 ( 23.69% )
- ago
#18
There are some complex things at play here when running a backtest like this and relying on the Transaction Weight to get you into trades.

1. You're using 100% of equity without margin. That's a bad idea because you're going to miss A LOT of trades - especially with a Strategy sizing positions a week in advance. Look up "NSF Positions" in the User Guide.

2. To run this code properly, you need to do this in the Strategy Settings:
1. DISABLE Retain NSF Positions
2. If you're going to use 100% of Equity sizing, make sure to use at least 1.2 Margin - and you still might miss trades if a stock moves more than 20% in a week.

There's another way to write the code in order to produce only the number of trade candidates and largely avoid the NSF effect, but in the end, disabling "Retain NSF Positions" will achieve the same effect.
0

Reply

Bookmark

Sort