mjj38
- ago
What would be the best way to implement the following rule:

a) That the given symbol is in the top 25% of [indicator value such as relative strength] for the given [dataset such as Nasdaq 100]?
1
1,011
Solved
5 Replies

Reply

Bookmark

Sort
- ago
#1
1. Create a custom indicator for relative strength.
2. Rotation Strategy > choose that Indicator for Weight Factor.

Both creation and usage of custom indicators requires running WL7 with admin privileges.
0
Cone8
 ( 26.65% )
- ago
#2


Here's a pattern you can use for a generic strategy. As written here, it adds 25% of total bar histories with the lowest RSI into a list called _buys. You can test if the current bar history is in the list (or not) to do some action with it.

CODE:
using WealthLab.Backtest; using System; using WealthLab.Core; using WealthLab.Indicators; using System.Drawing; using System.Collections.Generic; namespace WealthScript1 {    public class IndicatorRank : UserStrategyBase    {       //this static list will be available in all instances of this class       private static List<BarHistory> _buys = new List<BarHistory>();       private int _percentOfCandidates = 25;       private int _period = 14;       public IndicatorRank()       {          AddParameter("% of Candidates", ParameterTypes.Int32, 25, 5, 50, 5);          AddParameter("Period", ParameterTypes.Int32, 14, 5, 20, 1);       }       public override void Initialize(BarHistory bars)       {          _percentOfCandidates = Parameters[0].AsInt;          _period = Parameters[1].AsInt;          StartIndex = _period;       }       public override void PreExecute(DateTime dt, List<BarHistory> participants)       {          if (participants.Count < 2)             return;          int candidates = (int)Math.Truncate(participants.Count * _percentOfCandidates / 100d);          //Loop through the BarHistories of the participants, find the index that corresponds to the DateTime dt,          //and save the indicator value to the bars.UserData for sorting          foreach (BarHistory bars in participants)          {             int idx = GetCurrentIndex(bars);             if (idx < _period)             {                bars.UserData = 1.0e10;      // change this to a negative value if you change the sort from higher to lower below                continue;             }             //create a formula and assign a value. We'll just use RSI for this example             double rs = RSI.Series(bars.Close, _period)[idx];             bars.UserData = rs;          }          //this Sorts from lower to higher. For higher to lower, just change to .Sort(b, a)          participants.Sort((a, b) => a.UserDataAsDouble.CompareTo(b.UserDataAsDouble));          //Add the participants with the highest formula score to the _buys list          _buys.Clear();          _buys.AddRange(participants.GetRange(0, candidates));       }       public override void Execute(BarHistory bars, int idx)       {          if (!HasOpenPosition(bars, PositionType.Long))          {             // only buy this one if it's in the _buys list             if (_buys.Contains(bars))             {                PlaceTrade(bars, TransactionType.Buy, OrderType.Market);             }          }          else          {             if (!_buys.Contains(bars))                PlaceTrade(bars, TransactionType.Sell, OrderType.Market);          }       }    } }
3
Best Answer
Cone8
 ( 26.65% )
- ago
#3
fyi,
Made a correction above to account for participants with short histories whose indicator is not yet valid. It's this section -

CODE:
            if (idx < _period)             {                bars.UserData = 1.0e10;      // change this to a negative value if you change the sort from higher to lower below                continue;             }
2
mjj38
- ago
#4
Thanks Cone ...
0
mjj38
- ago
#5
putting the indicator for ranking in the cache speeds things up ...

CODE:
using WealthLab.Backtest; using System; using WealthLab.Core; using WealthLab.Indicators; using System.Drawing; using System.Collections.Generic; namespace WealthScript1 {    public class IndicatorRank : UserStrategyBase    {       //this static list will be available in all instances of this class       private static List<BarHistory> _buys = new List<BarHistory>();       private RSI _rsi;       private int _percentOfCandidates = 25;       private int _period = 14;       public IndicatorRank()       {          AddParameter("% of Candidates", ParameterTypes.Int32, 25, 5, 50, 5);          AddParameter("Period", ParameterTypes.Int32, 14, 5, 20, 1);       }       public override void Initialize(BarHistory bars)       {          _period = Parameters[1].AsInt;          _percentOfCandidates = Parameters[0].AsInt;          _rsi = RSI.Series(bars.Close, _period);          bars.Cache[_rsi.Name] = _rsi;          StartIndex = _rsi.FirstValidIndex;       }       public override void PreExecute(DateTime dt, List<BarHistory> participants)       {          if (participants.Count < 2)             return;          int candidates = (int)Math.Truncate(participants.Count * _percentOfCandidates / 100d);          //Loop through the BarHistories of the participants, find the index that corresponds to the DateTime dt,          //and save the indicator value to the bars.UserData for sorting          foreach (BarHistory bars in participants)          {             int idx = GetCurrentIndex(bars);             if (idx < _period)             {                bars.UserData = 1.0e10; // change this to a negative value if you change the sort from higher to lower below                continue;             }             //create a formula and assign a value. We'll just use RSI for this example //            double rs = RSI.Series(bars.Close, _period)[idx];             bars.UserData = (bars.Cache[_rsi.Name] as TimeSeries)[idx];          }          //this Sorts from lower to higher. For higher to lower, just change to .Sort(b, a)          participants.Sort((a, b) => a.UserDataAsDouble.CompareTo(b.UserDataAsDouble));          //Add the participants with the highest formula score to the _buys list          _buys.Clear();          _buys.AddRange(participants.GetRange(0, candidates));       }       public override void Execute(BarHistory bars, int idx)       {          if (!HasOpenPosition(bars, PositionType.Long))          {             // only buy this one if it's in the _buys list             if (_buys.Contains(bars))             {                PlaceTrade(bars, TransactionType.Buy, OrderType.Market);             }          }          else          {             if (!_buys.Contains(bars))                PlaceTrade(bars, TransactionType.Sell, OrderType.Market);          }       }    } }
4

Reply

Bookmark

Sort