I found a sample program for RSI Rotation on WL7 Discord.
I would like to change ① to the expression in ②, but I get an error.
What is wrong with it?
I don't know much about programming, so please tell me.
①
rsi = new RSI(bars.Close, 14);
②
rsi = (ATRP.Series(bars, 11) * WilliamsPctR.Series(bars, 2)) / RSI.Series(bars.Close, 21);
I would like to change ① to the expression in ②, but I get an error.
What is wrong with it?
I don't know much about programming, so please tell me.
①
rsi = new RSI(bars.Close, 14);
②
rsi = (ATRP.Series(bars, 11) * WilliamsPctR.Series(bars, 2)) / RSI.Series(bars.Close, 21);
CODE:
using WealthLab.Backtest; using System; using WealthLab.Core; using WealthLab.Indicators; using System.Drawing; using System.Collections.Generic; namespace WealthScript1 { public class Roto : UserStrategyBase { // be sure to set the Position Sizing in Settings appropriately // e.g., with rotating 3 symbols, set equity percent to 33.33 if you want ~100% exposure //the list of symbols that we should buy each bar private static List<BarHistory> buys = new List<BarHistory>(); //create the weight indicator and stash it into the BarHistory object for reference in PreExecute public override void Initialize(BarHistory bars) { rsi = new RSI(bars.Close, 14); bars.Cache["RSI"] = rsi; } //this is called prior to the Execute loop, determine which symbols have the lowest RSI public override void PreExecute(DateTime dt, List<BarHistory> participants) { //store the symbols' RSI value in their BarHistory instances foreach (BarHistory bh in participants) { RSI symbolRsi = (RSI)bh.Cache["RSI"]; int idx = GetCurrentIndex(bh); //this returns the index of the BarHistory for the bar currently being processed double rsiVal = symbolRsi[idx]; bh.UserData = rsiVal; //save the current RSI value along with the BarHistory instance } //sort the participants by RSI value (lowest to highest) participants.Sort((a, b) => a.UserDataAsDouble.CompareTo(b.UserDataAsDouble)); //keep the top 3 symbols buys.Clear(); for (int n = 0; n < 3; n++) { if (n >= participants.Count) break; buys.Add(participants[n]); } } //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 inBuyList = buys.Contains(bars); if (!HasOpenPosition(bars, PositionType.Long)) { //buy logic - buy if it's in the buys list if (inBuyList) PlaceTrade(bars, TransactionType.Buy, OrderType.Market); } else { //sell logic, sell if it's not in the buys list if (!inBuyList) PlaceTrade(bars, TransactionType.Sell, OrderType.Market); } } //declare private variables below private RSI rsi; } }
Rename
To fix it, make the following change in the declaration section in the footer of the script:
With your change it's no longer an RSI, it's a "custom" series so the object has to be adjusted accordingly.
Another code-based rotation strategy ("Tactical Asset Allocation") is to be found under the "Sample Strategies" folder.
Also check out this rotation template in Springroll's Post #20 here:
https://www.wealth-lab.com/Discussion/Converting-a-WL6-rotation-script-to-WL7-5613
CODE:
//private RSI rsi; private TimeSeries rsi;
With your change it's no longer an RSI, it's a "custom" series so the object has to be adjusted accordingly.
Another code-based rotation strategy ("Tactical Asset Allocation") is to be found under the "Sample Strategies" folder.
Also check out this rotation template in Springroll's Post #20 here:
https://www.wealth-lab.com/Discussion/Converting-a-WL6-rotation-script-to-WL7-5613
Thank you for your help
What is wrong with the following error message?
CODE:
foreach (BarHistory bh in participants)
What is wrong with the following error message?
A cast is missing since this is no longer an RSI, but a TimeSeries. Here's what's required to fix it:
CODE:
//RSI symbolRSI = (RSI)bh.Cache["RSI"]; TimeSeries symbolRSI = (TimeSeries)bh.Cache["RSI"];
It worked fine. Thank you very much.
Glad to help you.
I want to add a limit to the Hold Periods, Could you tell me how do I describe it?
What is the "limit to the Hold Periods", and why would you want to add it?
Thank you for your reply.
Bars Held. I'm thinking of a short-term strategy,
for example.I don't want to hold it for 19 days.
Bars Held. I'm thinking of a short-term strategy,
for example.I don't want to hold it for 19 days.
A rotation strategy holds whatever stock sorts to the top of the list. If a particular stock sits at the top of the ranking for 19 days why would you want to sell it early?
I understand that. More so, because I want to set the maximum bars held to a short term, like 2 days, and apply machine learning to the results of that.
This is how I had coded it in WL4.
I want to convert this for WL7.
I want to convert this for WL7.
CODE:
{ Close Positions that aren't on the bottom NUMBER list } Processed := 0; APCount := ActivePositionCount; for p := PositionCount - 1 downto 0 do begin if not PositionActive( p ) then Continue; sym := PositionSymbol( p ); bKeep := false; XitSignal := 'Rotation'; if PositionLong( p ) then begin if Bar + 1 - PositionEntryBar( p ) >= MAX_BARS then XitSignal := 'TimeBased' else for n := 0 to NUMBER do if sym = RSIVal.Data( lst.Count-1-n ) then bKeep := true; if not bKeep then SellAtMarket( Bar + 1, p, XitSignal ); Inc( Processed ); if Processed = APCount then break; end; end;
QUOTE:
This is how I had coded it in WL4.
To start with, we had stopped selling WL4 licenses several years before you registered on our website ;)
I am just asking because I would like to know the code for the above content in WL7 which has just been released.
I think it will be meaningful for other new users as well.
I think it will be meaningful for other new users as well.
Here is a minimal change to make if you wish to exit a position after 2 days:
CODE:
else { var pos = FindOpenPosition(PositionType.Long); bool shortTerm = idx >= pos.EntryBar + 2; //sell logic, sell if it's not in the buys list or is held for more than 2 days if (!inBuyList || shortTerm) PlaceTrade(bars, TransactionType.Sell, OrderType.Market); }
It worked fine. Thank you so much.
@Eugene, How would one modify the code in this post (#OP and #14) to not only exit a position after X days but to also exclude that symbol from the rotational strategy the following day so it cannot be picked up again?
Eric, for example you could tag an exit signal with some signal name string and then use BarsSinceLastExit (see QuickRef entry).
Your Response
Post
Edit Post
Login is required