SetScaleMonthly with Rotation strategy
Author: MikeyRules
Creation Date: 8/30/2012 10:39 AM
profile picture

MikeyRules

#1
Hello,

I am trying to build out a system test that looks at a universe of ETFs, calculates the 3 month and 1 month % gain/loss based on the Close. It then ranks the ETFs each month based on that 3 Month % gain loss and takes the top 4. Using that top 4, I then want to buy only the ones within the top 4 that have a positive % gain in both the 3 and 1 month timeframes. I only buy and sell on the last day of the month.

I seem to have it working on a daily time frame but when I try to SetScaleMonthly on my "PainCalc" dataseries, I get incorrect results and the debug shows it seems to be creating the same PainCalc for each of the symbols in the list and returning the same set each month. I expect I am using it incorrectly, and am not understanding the proper interaction between the Scale and Rotation approaches. Can someone provide me with some further insight on what to do to try to accomplish what I am looking to do?

CODE:
Please log in to see this code.
profile picture

Eugene

#2
A couple of notes:

1. This has an incorrect order:
CODE:
Please log in to see this code.

Should be:
CODE:
Please log in to see this code.

My note is based on your original code before you edited it.

2. This should not be used in a multi-position strategy - like every Rotational script is:
CODE:
Please log in to see this code.

See the WealthScript Programming Guide > Programming Trading Strategies > Multi-Position Strategies > MP Strategy Template.
profile picture

MikeyRules

#3
Thanks Eugene. You are fast!

I changed the scale order,

CODE:
Please log in to see this code.


and changed Last position active to 'if(ActivePositions.Count > 0', thank you.
CODE:
Please log in to see this code.



After doing that, I am now getting the "Run time error: Index was out of range. Must be non-negative and less than the size of the collection..."

When I look at the trades, it makes the first month trades and closes them out appropriately and then opens the second month's trades and leaves them open.

When I comment out the SetScaleMonthly and RestoreScale, it works the way it should on a daily timeframe (opening and closing at End of Month). Is there another place in the code that I need to indicate the Monthly context? Or is there something else I am missing?
profile picture

Eugene

#4
I may be fast but you are faster - in returning a DataSeries ;)
QUOTE:
I changed the scale order,
...
return dsClose;
dsClose = Synchronize(dsClose);

You're almost there, but give the series a chance to Synchronize:
CODE:
Please log in to see this code.
profile picture

MikeyRules

#5
Ha!! Good one :-) Thanks! The error has been resolved.

The issue I am having now is that it is returning the same value for ThreeMonthPerc as OneMonthPerc. They are both coming up with the same value and that value is the OneMonthPerc. I should be able to treat the montly data series as a regular data series and be able to refer back to a value a certain number of bars back, is that right? Is there something else I am doing that is causing this to not resolve as I would expect it to?

CODE:
Please log in to see this code.
profile picture

Eugene

#6
It's related to synchronization. How about this drop-in replacement of your foreach loop?
CODE:
Please log in to see this code.
profile picture

wmrgrove

#7
Mikey, I am a new (one month) user of WL and trying to learn all the great features of the product. Also very interested in Rotational Strategy and ETF trading / Adaptive Asset Allocation Strategy. I used AIQ software for many years and find the coding here a challenge.

After a lot of backtesting and scanning runs it appears to me that 12mth ROC is much more powerful than 120/90/30 day ROC. Just an observation and clearly more relavent to investing than trading.

Would you mind sharing a copy of your daily strategy here that I could "cut and paste" modify?

Thanks and good luck on your trading! Bill
profile picture

MikeyRules

#8
Thanks Eugene!! That did the trick, I really appreciate your help!

Bill - as you probably know, you need to determine what your goals are for your system first before you design and build it. My goals were to build a system that beat the S&P500 with less volatility, and requires a minimal amount of work to trade it. This system is monthly and I use it against a universe of diversified ETFs and I am pleased with the results. Looking at a year for ROC is too far back for a monthly trading system.

Here is the final code from my system. As an aside, I have found the rotational stuff to be more challenging than the straight up systems. If you are going to run it, make sure to run it on one of the symbols of a dataset, not the whole dataset.

CODE:
Please log in to see this code.
profile picture

MikeyRules

#9
Now I am having an error issue when I try to add a crash stop 10% below the entry price.

When I use a close all positions exit on the last day of the month, the script compiles and executes fine. However, when I try to add in a crash stop at 10% below the entry price in addition to the end of the month exit, I am getting an Index out of range error. I am using the code from the MP Strategy Template.

I think that may mean I am trying to access the position before it is created. If that is the case, how do I structure my code to include the second "crash" stop?

This works fine:
CODE:
Please log in to see this code.


But this throws the error:
CODE:
Please log in to see this code.

Thanks
profile picture

Eugene

#10
1. AtClose(bar) orders should precede anything else. Reference: WealthScript Programming Guide > Programming Trading Strategies > Peeking > Order of Trading Signals.

2. The AtStop order should use bar+1, otherwise it's peeking.

3. Finally, on to the runtime error. When closing out all positions with the Position.AllPositions shortcut, you're modifying the Positions collection but the loop continues executing up to the point when it stumbles onto a Position that has been exited and removed from the ActivePositions collection:

Position p = ActivePositions[pos];

If your Strategy exits all positions, it has to abort processing the exits for the current bar. For example, with a break directive:

CODE:
Please log in to see this code.
profile picture

MikeyRules

#11
Ha, not one issue, but 3!! :-) Thanks so much Eugene, works great.