- ago
I have the program below that both goes long and short. The long positions will be exited on the next bar at market open while the short positions will be exited on the same bar (same as entry bar) under the following condition. If a stop loss is triggered, the position will be covered at the stop loss price level, otherwise the position will be cover at market close of the same bar.

The problem is that short positions does not exits when stop loss is triggered nor does it exits at Market Close of the same bar. Rather it always exit at Market Open of the same bar. Long positions seems to work correctly. Thanks for any help and suggestions.

CODE:
using WealthLab.Backtest; using System; using WealthLab.Core; using WealthLab.Indicators; using System.Drawing; using System.Collections.Generic; 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) { }       //execute the strategy rules here, this is executed once for each bar in the backtest history       public override void Execute(BarHistory bars, int bar)       {          if (OpenPositions.Count > 0)          {             foreach (Position pos in OpenPositions)                ClosePosition(pos, OrderType.Market);          }          else          {             PlaceTrade(bars, TransactionType.Buy, OrderType.Limit, 0.9 * bars.Close[bar]);                          PlaceTrade(bars, TransactionType.Short, OrderType.Limit, 1.5 * bars.Close[bar]);             if (bars.High[bar + 1] > 1.75 * bars.Close[bar])                                   // peeking                PlaceTrade(bars, TransactionType.Cover, OrderType.Stop, 1.75 * bars.Close[bar]);             else                PlaceTrade(bars, TransactionType.Cover, OrderType.MarketClose);          }       } //declare private variables belows } }
0
1,401
Solved
10 Replies

Reply

Bookmark

Sort
- ago
#1
Both Stop and AtClose orders trigger for me just fine (with percentages more realistic to be hit than those in your code, of course) and 10% equity per position. What position size do you have?

You can name exit signals to make sure they're being hit:
CODE:
      public override void Execute(BarHistory bars, int idx)       {          //to prevent errors in the log          if (idx == bars.Count - 1)             return;          if (OpenPositions.Count > 0)          {             foreach (Position pos in OpenPositions)                ClosePosition(pos, OrderType.Market);          }          else          {             PlaceTrade(bars, TransactionType.Buy, OrderType.Limit, 0.95 * bars.Close[idx]);             PlaceTrade(bars, TransactionType.Short, OrderType.Limit, 1.03 * bars.Close[idx]);             if (bars.High[idx + 1] > 1.05 * bars.Close[idx]) // peeking                PlaceTrade(bars, TransactionType.Cover, OrderType.Stop, 1.05 * bars.Close[idx], "stop");             else                PlaceTrade(bars, TransactionType.Cover, OrderType.MarketClose, 0, "same");          }       }
0
Cone8
 ( 6.24% )
- ago
#2
The peeking isn't required. Just stack those exit signals. If the Cover hits there will be no Position to Cover at MarketClose, so that signal will be a "no op".
CODE:
PlaceTrade(bars, TransactionType.Buy, OrderType.Limit, 0.95 * bars.Close[idx]); PlaceTrade(bars, TransactionType.Short, OrderType.Limit, 1.03 * bars.Close[idx]); PlaceTrade(bars, TransactionType.Cover, OrderType.Stop, 1.05 * bars.Close[idx], "stop"); PlaceTrade(bars, TransactionType.Cover, OrderType.MarketClose, 0, "same");
1
- ago
#3
Thank you Eugene and Cone. Taking a closer look, as Eugene mentioned the code functions correctly. In the examples I was looking at, the trigger values for Limit entry and stop loss exit are higher than those of Open prices, so both entry and exit occur at Open price. When the stop loss is not triggered, the exit occurs at Market Close correctly.

It's good to know that no peeking needed in this case. This problem is solved. Thanks.
0
Best Answer
- ago
#4
QUOTE:
Just stack those exit signals. If the Cover hits there will be no Position to Cover at MarketClose, so that signal will be a "no op".
CODE:

Does this apply only to backtest, not live trading? I'm asking because I found that with TWS if you place a Sell Limit order and a Sell MOC order at the same time, same day, and the limit is hit the MOC will still execute, creating (an unwanted)short position.

I couldn't find documentation on Web for how IBKR says they handle this scenario. They do have a OCA (One Cancels All) trade entry option that should theoretically cancel one of these if the other is executed. Does WL8 automatically transmit OCA trades to IBKR for these "stacked' trades.?
0
Cone8
 ( 6.24% )
- ago
#5
Assign the same CancelationCode before both orders. Once filled, Wealth-Lab will cancel the opposite order.

CODE:
CancelationCode = 42; ClosePosition(... OrderType.Limit,..); CancelationCode = 42; ClosePosition(... OrderType.MarketClose,..);

Careful though! If the MOC is submitted with the broker, you won't be able to cancel it inside the period defined by the exchange.
0
- ago
#6
I am getting an error when I try to do this.
QUOTE:
The name "CancelationCode" does not exist in the current context.


Does this have to be used with ClosePosition or can it be used with PlaceTrade as well?

The method description references looking at C# code for a Block strategy. Not clear how to set this up. Here's what I tried:

CODE:
         Backtester.CancelationCode = 42;                CancelationCode = 42; //error PlaceTrade(bars, TransactionType.Sell, OrderType.MarketClose, 0, "Market Close Exit");          CancelationCode = 42;          PlaceTrade(bars, TransactionType.Sell, OrderType.Limit, target, "Limit Sell Target");

What am I missing?

0
- ago
#7
It's C# 101. You're trying to assign a value to the undeclared variable CancelationCode:
CODE:
//WRONG: CancelationCode = 42; //error

But you should not declare it on your own in this case because as you can see in the line above, there's the correct way of assigning it:
CODE:
//RIGHT: Backtester.CancelationCode = 42; //or whatever
0
- ago
#8
Hi Eugene,

If you look above at Post #5 and the code Cone supplied me, I was using that. I also found Backtester.CancelationCode = [number] in C# code from a Block strategy (referenced in QuickRef). Couldn't figure out how these two constructs worked together. Was there an error or omission in Post #5?

Not sure why it's C# 101. There's not much documentation on this feature and how to use it.

Then, the only way to use this is to precede by "Backtester." and then you add any integer number to define the Sell Cancel "group?"
0
- ago
#9
Hi Robert,

I admit that there's lack of C# example in B12 and Post #5 just outlines the feature. To sweeten the pill, CancelationCode is documented in the QuickRef under the Backtester namespace. Please use it as a guideline. The idea is to tag an exit order with an integer cancelation code which precedes it.

P.S. By 'C# 101' I meant to say that the compiler error message would suggest that a CancelationCode without the preceding 'Backtester' could not be found.
0
- ago
#10
Thanks, Eugene.
1

Reply

Bookmark

Sort