- ago
Hello,

The simple codes below are trying to exit on the same day of buying first on a limit, and if not successful, on the close:

In the first code, line 29 generates an error as if the position is not created.

In the second code (a modified version), the exit orders are separated from the buy. This version runs without error, but exits are not on the same day as buy.

Thanks


CODE:
using WealthLab.Backtest; using System; using WealthLab.Core; using WealthLab.Indicators; using WealthLab.ChartWPF; using System.Drawing; using System.Collections.Generic; namespace WealthScript29 {    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)       {          rsi = new RSI(bars.Close, 14);          PlotIndicator(rsi);       }       //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 (!HasOpenPosition(bars, PositionType.Long))             {             if (rsi[idx] < 30)             {                PlaceTrade(bars, TransactionType.Buy, OrderType.Market);                Position p = LastPosition;                if(PlaceTrade(bars, TransactionType.Sell, OrderType.Limit, p.EntryPrice *1.01) == null)                   PlaceTrade(bars, TransactionType.Sell, OrderType.MarketClose);             }             }       }       //declare private variables below       private RSI rsi;    } }


Second code:
CODE:
using WealthLab.Backtest; using System; using WealthLab.Core; using WealthLab.Indicators; using WealthLab.ChartWPF; using System.Drawing; using System.Collections.Generic; namespace WealthScript29 {    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)       {          rsi = new RSI(bars.Close, 14);          PlotIndicator(rsi);       }       //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 (!HasOpenPosition(bars, PositionType.Long))             {             if (rsi[idx] < 30)                PlaceTrade(bars, TransactionType.Buy, OrderType.Market);                             }          if (HasOpenPosition(bars, PositionType.Long))          {             Position p = LastPosition;             if(PlaceTrade(bars, TransactionType.Sell, OrderType.Limit, p.EntryPrice * 1.01) == null)                PlaceTrade(bars, TransactionType.Sell, OrderType.MarketClose);          }                       }       //declare private variables below       private RSI rsi;    } }

0
1,171
Solved
6 Replies

Reply

Bookmark

Sort
- ago
#1
Please check this out:

https://www.wealth-lab.com/Discussion/How-to-buy-at-open-and-sell-at-close-the-same-day-6836
https://www.wealth-lab.com/Discussion/Could-not-Close-position-on-Same-bar-at-Market-Close-7014
https://www.wealth-lab.com/Discussion/How-do-I-enter-at-the-close-of-the-day-5504 (from the FAQ)

Hope this helps.
0
- ago
#2
Hi Eugene,

I had already checked those posts, and although they seem to be on the same topic but are not exactly similar to this situation.

To be more specific, in this case the exit limit order is based on the position EntryPrice (say 1% profit), and not a percentage of the Close or Open (as discussed in those posts). So my solution was to use LastPosition.EntryPrice which seems to cause the problem. What am I missing here and do you know of a different workaround?

Thanks
0
- ago
#3
Hi Mohsen,

Please review the topic chosen for the FAQ. I think Dion explained it clearly there. You have to peek carefully (exception: last bar) and since your entry price is the market open price it can be saved in Position.Tag (for example) and used for the exit at limit.
0
Cone8
 ( 6.32% )
- ago
#4
Unlike WL6, a signal - PlaceTrade in WL7 - will never be null and always return a Transaction object.

There are 2 ways to do same bar exits, but the override AssignAutoStopTargetPrices method allows you to use the actual execution price. It's documented in the QuickRef > UserSrategyBase > Strategy Execution section.

Let me know if this works for you -

CODE:
using WealthLab.Backtest; using System; using WealthLab.Core; using WealthLab.Indicators; using WealthLab.ChartWPF; using System.Drawing; using System.Collections.Generic; namespace WealthScript2 {    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)       {          rsi = new RSI(bars.Close, 14);          PlotIndicator(rsi);       }       //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 (!HasOpenPosition(bars, PositionType.Long))          {             if (rsi[idx] < 30)             {                Transaction t = PlaceTrade(bars, TransactionType.Buy, OrderType.Market);                PlaceTrade(bars, TransactionType.Sell, OrderType.MarketClose);             }          }       }       //same bar exits: 1% profit execution price       public override void AssignAutoStopTargetPrices(Transaction t, double basisPrice, double executionPrice)       {          t.AutoProfitTargetPrice = executionPrice * 1.01;                }              //declare private variables below       private RSI rsi;    } }
0
Best Answer
- ago
#5
Happy New Year,

Thanks Cone for further explanation. Your suggested solution does work, however, is it possible to use a parameter instead of percentage for the profit (say ATR[idx] instead of 1.01)? Apparently idx is not passed to the function and is not recognized. can transaction tag be used for this purpose?

Coming from years of using WL6, I am still trying to figure out the fundamental differences and what cannot be simply transferred to WL7. For example, I still don't understand why creating a position right after a PlaceTrade and exiting based on the EntryPrice does not work:

CODE:
... if (!HasOpenPosition(bars, PositionType.Long))             {             if (rsi[idx] < 30)             {                PlaceTrade(bars, TransactionType.Buy, OrderType.Market);                Position p = LastPosition;                PlaceTrade(bars, TransactionType.Sell, OrderType.Limit, p.EntryPrice + ATR[idx] );             }             } ...



0
Glitch8
 ( 12.10% )
- ago
#6
It’s because in WL7 the simulation model is more accurate to what happens in the real world. When you place an order, you don’t immediately get a position, you just get an order. The position does not get created until the following trading day when/if the order is filled.

This prevents certain flaws that WL6 has, like the ability to take action on bar N based on whether the position generated at bar N+1 was filled or not.
0

Reply

Bookmark

Sort