- ago
The strategy description

according to sort results to buy foremost X counts symbol.

and i used OpenPositionsAllSymbols add open position condition in Execute

maximum holding should be less than or equal to 20

CODE:
         if (inBuyList && !HasOpenPosition(bars, PositionType.Long))          {             if (OpenPositionsAllSymbols.Where(t => t.EntryTransactionType.ToString() == "Buy").Count() <= 19)                PlaceTrade(bars, TransactionType.Buy, OrderType.Market);          }


the result is not.

Holding quantity over 20



Complete Code

CODE:
using WealthLab.Backtest; using System; using WealthLab.Core; using System.Collections.Generic; using System.Linq; namespace WealthScript2 {    public class OPAS : UserStrategyBase    {       private static List<BarHistory> Buys = new List<BarHistory>();       int idx;       double _TestVal;       TimeSeries _Test, Test_;       public override void Initialize(BarHistory bars)       {          Test_ = new TimeSeries(bars.DateTimes, 0);          for (int n = 1; n < bars.Count - 1; n++)             Test_[n] = (bars.Close[n] - bars.Close[n-1]) / bars.Close[n-1];          bars.Cache["Test"] = Test_;       }       public override void PreExecute(DateTime dt, List<BarHistory> participants)       {          foreach (BarHistory bh in participants)          {             _Test = (TimeSeries)bh.Cache["Test"];             idx = GetCurrentIndex(bh);             _TestVal = _Test[idx];             bh.UserData = Math.Round(_TestVal, 3);          }          participants.Sort((a, b) => a.UserDataAsDouble.CompareTo(b.UserDataAsDouble));          Buys.Clear();          for (int n = 0; n <= 20; n++)          {             if(n == participants.Count-1)                break;             Buys.Add(participants[n]);          }       }       public override void Execute(BarHistory bars, int idx)       {          bool inBuyList = Buys.Contains(bars);                    if(HasOpenPosition(bars, PositionType.Long) && !inBuyList)          {             ClosePosition(LastPosition, OrderType.Market);          }          if (inBuyList && !HasOpenPosition(bars, PositionType.Long))          {             if (OpenPositionsAllSymbols.Where(t => t.EntryTransactionType.ToString() == "Buy").Count() <= 19)                PlaceTrade(bars, TransactionType.Buy, OrderType.Market);          }       }    } }


Strategy Settings



Thx
0
1,284
Solved
11 Replies

Reply

Bookmark

Sort
- ago
#1
Have you tried "Max Open Pos" to limit the number of open positions across portfolio? It's a numeric control in the Strategy Settings. Same constraints exist for long/short positions and per symbol - and they can be combined.
0
- ago
#2
Hi, Eugene

QUOTE:

It's a numeric control in the Strategy Settings.




I know the Strategy Settings you said.

but can you tell me why the OpenPositionsAllSymbols can't reach control open position.

I hope Open Position ( Long / Short Position) is dynamic. not fixed.

Thx.
0
Glitch8
 ( 10.62% )
- ago
#3
In WL7 there is no need to hope. We provide you the full platform to test your doubts yourself. You can create a TimeSeries, populate it with OpenPositionsAllSymbols, and chart it. Here's a modified RSI Agita that does just that.

CODE:
using WealthLab.Backtest; using System; using WealthLab.Core; using WealthLab.Indicators; using System.Drawing; using System.Collections.Generic; namespace WealthScript1 { public class RSIAgita : UserStrategyBase {       //constructor       public RSIAgita()       {          AddParameter("RSI Period", ParameterTypes.Int32, 14, 7, 42, 7);          AddParameter("Oversold", ParameterTypes.Int32, 25, 10, 60, 5);          AddParameter("Overbought", ParameterTypes.Int32, 60, 10, 80, 5);          }        //create indicators and other objects here, this is executed prior to the main trading loop public override void Initialize(BarHistory bars) {          period = Parameters[0].AsInt;          oversold = Parameters[1].AsInt;          overbought = Parameters[2].AsInt;          //Create and plot RSI          rsi = RSI.Series(bars.Close, period);          PlotTimeSeries(rsi, "rsi", "RSI", Color.Navy);          DrawHorzLine(oversold, Color.Red, 2, LineStyles.Dotted, "RSI");          DrawHorzLine(overbought, Color.Green, 2, LineStyles.Dotted, "RSI");          StartIndex = period + 1;          //create a time series to show the number of open positions across all symbols          op = new TimeSeries(bars.DateTimes);          PlotTimeSeries(op, "OpenPositions", "OP", Color.DarkGreen, PlotStyles.Histogram);       } //execute the strategy rules here, this is executed once for each bar in the backtest history public override void Execute(BarHistory bars, int idx) {          op[idx] = OpenPositionsAllSymbols.Count;                    //Entries are allowed only if price is below last entry price          double lastEntryPrice = Double.MaxValue;          if (LastPosition != null)             if (LastPosition.IsOpen)                lastEntryPrice = LastPosition.EntryPrice;          //Check penetration of RSI below levels 35 down to 5          level = oversold;          while (level > 0)          {             if (rsi.CrossesUnder(level, idx))                if (bars.Close[idx] < lastEntryPrice)                   PlaceTrade(bars,TransactionType.Buy,OrderType.Market);             level -= 5;          }          //Exit all long positions if RSI crosses above 45     if (rsi.CrossesOver(overbought, idx))             foreach (Position pos in GetPositions())                if (pos.IsOpen)                   ClosePosition(pos,OrderType.Market); }       public override void BacktestComplete()       {          List<Position> positions = GetPositionsAllSymbols(true);          foreach(Position pos in positions)             if (pos.NSF)                WriteToDebugLog(pos.ToString());       }       //declare private variables below       private int oversold, overbought, level, period;       private RSI rsi;       private TimeSeries op;    } }


1
- ago
#4
Hi, Glitch

I folloing ur code, set op as a open position condition

in line 60

CODE:
if (rsi.CrossesUnder(level, idx) && !HasOpenPosition(bars, PositionType.Long) && op[idx] <= 2)


but it shows over 3 open positions on the chart.

Image see next post.
0
- ago
#5


0
- ago
#6
I think this is because your backtest includes NSF positions. You can disable them on Strategy Setttings tab > Advanced Settings.
0
Glitch8
 ( 10.62% )
- ago
#7
yes, your test is saying to buy if op is <= 2, so then when it buys it causes the third one. Furthermore, there might be more than one order placed on that same bar in a portfolio backtest, thus causing more than three potential positions.

The positions for any new signals are not created until the following bar, so OpenPositions does not know about them yet.

Eugene, it’s nothing to do with nsf, it’s all working as designed here.
0
Glitch8
 ( 10.62% )
- ago
#8
If you want to limit the number of open positions the easiest way would be to use the fields in the position sizing settings. But if you want to do so in code too you should be able to account for the entry signals already placed:

CODE:
op[idx] = OpenPositionsAllSymbols.Count; op[idx] += Backtester.Orders.Where(o => o.IsEntry).Count();


Add using System.Linq; to your using clauses at the top.
1
- ago
#9
Hi, Glitch

QUOTE:

op[idx] = OpenPositionsAllSymbols.Count;
op[idx] += Backtester.Orders.Where(o => o.IsEntry).Count();


If i want to limit the number of Open Long Position or Open Short Position, how to write?

I writing this doesn't work.

CODE:
op[idx] = OpenPositionsAllSymbols.Count; op[idx] += Backtester.Orders.Where(o => o.PositionType == PositionType.Long).Count();


CODE:
op[idx] = OpenPositionsAllSymbols.Count; op[idx] += Backtester.Orders.Where(o => o.PositionType == PositionType.Short).Count();


Thx
0
Glitch8
 ( 10.62% )
- ago
#10
Maybe because you’re not checking IsEntry so you’re also counting any sell/cover orders?
1
Best Answer
- ago
#11
Hi, Glitch

QUOTE:

Maybe because you’re not checking IsEntry so you’re also counting any sell/cover orders?


Got it.

I corrected it.

CODE:
         opL[idx] += Backtester.Orders.Where(o => o.PositionType == PositionType.Long && o.IsEntry).Count();          opS[idx] += Backtester.Orders.Where(o => o.PositionType == PositionType.Short && o.IsEntry).Count();
0

Reply

Bookmark

Sort