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
the result is not.
Holding quantity over 20
Complete Code
Strategy Settings
Thx
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
Rename
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.
Hi, Eugene
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.
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.
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; } }
Hi, Glitch
I folloing ur code, set op as a open position condition
in line 60
but it shows over 3 open positions on the chart.
Image see next post.
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.
I think this is because your backtest includes NSF positions. You can disable them on Strategy Setttings tab > Advanced Settings.
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.
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.
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:
Add using System.Linq; to your using clauses at the top.
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.
Hi, Glitch
If i want to limit the number of Open Long Position or Open Short Position, how to write?
I writing this doesn't work.
Thx
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
Maybe because you’re not checking IsEntry so you’re also counting any sell/cover orders?
Hi, Glitch
Got it.
I corrected it.
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();
Your Response
Post
Edit Post
Login is required