Could someone provide a code snipped (or modify the version below) in which the entry signals count are reduced by the number of open positions?
Example (max 10 open positions are allowed)
Day 0 --> 3 open positions (7 free slots)
Day 1 --> 16 entry signals sorted by weight, limited by number of free slots --> 7 entry signals are processed
Example (max 10 open positions are allowed)
Day 0 --> 3 open positions (7 free slots)
Day 1 --> 16 entry signals sorted by weight, limited by number of free slots --> 7 entry signals are processed
CODE:
using WealthLab.Backtest; using System; using WealthLab.Core; using WealthLab.Data; using WealthLab.Indicators; using System.Collections.Generic; namespace WealthScript1 { 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) { rsi4 = RSI.Series(bars.Close, 4); bars.UserData = rsi4; StartIndex = 4; } //pre-execute, sort candidates by RSI, keep lowest 4 public override void PreExecute(DateTime dt, List<BarHistory> participants) { symbolsToTrade.Clear(); participants.Sort((a, b) => { RSI rsiA = (RSI)a.UserData; RSI rsiB = (RSI)b.UserData; int idxA = GetCurrentIndex(a); int idxB = GetCurrentIndex(b); return rsiA[idxA].CompareTo(rsiB[idxB]); }); string s = ""; int entries = 0; foreach (BarHistory bh in participants) { if (!HasOpenPosition(bh, PositionType.Long)) { symbolsToTrade.Add(bh); s += bh.Symbol + ", "; entries++; if (entries >= 10) // minus the open position count? break; } } WriteToDebugLog(dt.ToShortDateString() + ": " + s, false); } //execute the strategy rules here, this is executed once for each bar in the backtest history public override void Execute(BarHistory bars, int idx) { bool tradeIt = symbolsToTrade.Contains(bars); if (!HasOpenPosition(bars, PositionType.Long)) { //code your buy conditions here if (tradeIt) PlaceTrade(bars, TransactionType.Buy, OrderType.Limit, bars.Close[idx] * 0.98); } else { //code your sell conditions here PlaceTrade(bars, TransactionType.Sell, OrderType.Limit, bars.High[idx]); } } //declare private variables below private RSI rsi4; private static List<BarHistory> symbolsToTrade = new List<BarHistory>(); } }
Rename
There are lots of ways to do the same thing. Here's one of them -
CODE:
using WealthLab.Backtest; using System; using WealthLab.Core; using WealthLab.Data; using WealthLab.Indicators; using System.Collections.Generic; using System.Linq; namespace WealthScript1 { public class RotationStrategy : UserStrategyBase { public RotationStrategy() { AddParameter("N Positions", ParameterType.Int32, 10, 2, 20); } //create indicators and other objects here, this is executed prior to the main trading loop public override void Initialize(BarHistory bars) { rsi4 = RSI.Series(bars.Close, 4); bars.UserData = rsi4; StartIndex = 4; } //pre-execute, sort candidates by RSI, keep lowest 4 public override void PreExecute(DateTime dt, List<BarHistory> participants) { symbolsToTrade.Clear(); participants.Sort((a, b) => { RSI rsiA = (RSI)a.UserData; RSI rsiB = (RSI)b.UserData; int idxA = GetCurrentIndex(a); int idxB = GetCurrentIndex(b); return rsiA[idxA].CompareTo(rsiB[idxB]); }); _buys.Clear(); for (int n = 0; n < Parameters[0].AsInt; n++) { BarHistory bh = participants[n]; _buys.Add(bh); } foreach (Position p in OpenPositionsAllSymbols) { //sell positions that are not in the _buys list if (!_buys.Contains(p.Bars)) PlaceTrade(p.Bars, TransactionType.Sell, OrderType.Market); } string actives = string.Join(", ", _buys.Select(x => x.Symbol)); WriteToDebugLog(dt.ToShortDateString() + ": " + actives, false); } //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) && _buys.Contains(bars)) { PlaceTrade(bars, TransactionType.Buy, OrderType.Limit, bars.Close[idx] * 0.98); } } //declare private variables below private RSI rsi4; private static List<BarHistory> symbolsToTrade = new List<BarHistory>(); private static List<BarHistory> _buys = new List<BarHistory>(); } }
Thanks Cone!
But in which line the reduction of entry signals takes place?
But in which line the reduction of entry signals takes place?
No, that line just gives you the list of the top 10 for that bar - or however many you select with the "N Positions" parameter (you have to adjust sizing accordingly).
First, the list of _buys of the top ranked symbols is created. This creates a "Top 10" limit.
Next, it sells off anything that's not in _buys.
In Execute(), if the BarHistory doesn't have an active Long Position AND the symbol is in the list of _buys, it creates a signal to buy it. In other words, if the symbol is already active, it won't try to buy it again even if it's in _buys.
First, the list of _buys of the top ranked symbols is created. This creates a "Top 10" limit.
Next, it sells off anything that's not in _buys.
In Execute(), if the BarHistory doesn't have an active Long Position AND the symbol is in the list of _buys, it creates a signal to buy it. In other words, if the symbol is already active, it won't try to buy it again even if it's in _buys.
Alright, understood!
But how to implement this method in a non RotationStrategy where there also Exit rules (market and limit)? By subtracting the count of _positions (list of all open positions) from _buys? Or _buys could be sorted into another list like: "n = 0, n < OpenPositionCount"?
But how to implement this method in a non RotationStrategy where there also Exit rules (market and limit)? By subtracting the count of _positions (list of all open positions) from _buys? Or _buys could be sorted into another list like: "n = 0, n < OpenPositionCount"?
I already gave you a nice freebie. If someone else doesn't have the time to do your programming, the Concierge Servce is available.
Your Response
Post
Edit Post
Login is required