- ago
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


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>(); } }
0
494
Solved
5 Replies

Reply

Bookmark

Sort
Cone8
 ( 5.88% )
- ago
#1
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>();    } }
0
Best Answer
- ago
#2
Thanks Cone!

But in which line the reduction of entry signals takes place?
0
Cone8
 ( 5.88% )
- ago
#3
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.
0
- ago
#4
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"?
0
Cone8
 ( 5.88% )
- ago
#5
I already gave you a nice freebie. If someone else doesn't have the time to do your programming, the Concierge Servce is available.
0

Reply

Bookmark

Sort