Is Strategy being executed on a symbol or on a DataSet?
Author: Panache
Creation Date: 10/30/2018 9:22 PM
profile picture

Panache

#1
I'd like my code to be able to tell whether the Strategy is being run on the entire data set or just one of the symbols in a data set. Specifically, I don't want to run:
CODE:
Please log in to see this code.

if the entire data set is selected.
profile picture

Eugene

#2
GetMode2 from Community Components is here to help you out:

Returns the mode the Strategy is being executed. (...) and GetMode2 which returns a RunMode which can take four values: SSB, MSB, SM, Error - single symbol backtest, multi-symbol backtest, running in Strategy Monitor and state of error.

This is really a FAQ on the forum.

How to determine if a WealthScript runs for a single symbol
How to Differentiate Strategy Monitor from Multi-symbol Backtest
Get DataSet Name and Symbol
How to tell if the script is being run via MSB vs SSB?
profile picture

Panache

#3
Thank you. I actually checked the Community Components before asking the question, and apparently my Google search wasn't looking for the right key words either.

In any event, unless I'm missing something, if I run the code in the WIKI against the entire data set, it prints the message once for each symbol in the data set. I can use
CODE:
Please log in to see this code.

to only print the message once, but the strategy is still executed against each symbol in the data set, and for a data set like the Russell 2000 with a large data range, that takes awhile.

What I'm looking for is a way to stop the strategy from executing on the rest of the symbols if it is a Multi-Symbol back test and tell the user to set it for a single symbol back test. I can speed up the program execution by forcing an error on the first symbol in the data set, but that doesn't seem like a particularly elegant way to solve the problem:
CODE:
Please log in to see this code.


Ideally, what I would like to be able to do is to force Wealth-Lab to only run the strategy against the first symbol in the data set, regardless whether it was set for a multi or single symbol run. That would make it unnecessary to check for an error at all.
profile picture

Eugene

#4
QUOTE:
What I'm looking for is a way to stop the strategy from executing on the rest of the symbols if it is a Multi-Symbol back test

It's easier than you think. There's Abort statement in WealthScript:

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

Panache

#5
Many thanks.
profile picture

Eugene

#6
You're welcome.
profile picture

Panache

#7
Abort() is an elegant way to stop execution of the strategy. However, in the multi-symbol mode, Wealth-Lab continues to execute the strategy for each symbol in the data set, even though the strategy is aborted as soon as it is executed. If the data set contains many symbols and a large data range, this results in a significant delay before control is returned to the user.
CODE:
Please log in to see this code.

Is there any way to tell Wealth-Lab to stop executing the strategy against the rest of symbols in the data set? Or, to make that a positive statement, is there any way to programmatically instruct Wealth-Lab to only execute the strategy against the first symbol in the data set.
profile picture

Eugene

#8
How significant is the delay?
profile picture

Panache

#9
Running against the S&P 500 with one year of data takes about 30 seconds on my i5 with the data already in memory. Obviously, it would be less on my faster computers, but probably more if it has to read all the data from the files.

I think most of the delay is caused by the fact that Abort() prints an error message to the debug window each time.

This is what I was using for my benchmark:
CODE:
Please log in to see this code.
profile picture

Eugene

#10
Of course PrintDebug() comes with some overhead. But this is how WL's backtester is designed to operate.

The code snippet from #7 finishes in 1.2 sec on 200 symbols for me (on SSD, EOD data) which isn't even close to 30 seconds. Are you using intraday data?
profile picture

Panache

#11
QUOTE:
Are you using intraday data?

No, just EOD data. However, I know that my i7 runs strategies approximately 10 times faster than my i5, so that might be a lot of the difference.

QUOTE:
But this is how WL's backtester is designed to operate.


I understand that I'm trying to do things differently than the way Wealth-Lab was designed to do them. Without getting into a long explanation, using foreach symbol allows me to get more accurate backtesting and optimization results and to generate more user friendly email alerts than are possible running Wealth-Lab the way it was designed.

This isn't that big of a deal. Instead of an error check, I was hoping to be able to use Abort() to run a strategy using foreach symbol against the entire data set. I'll just use continue to run it against the first symbol in the data set and use Abort() as part of my error checking to make sure the strategy settings were configured properly.
profile picture

Cone

#12
Instead of Abort(); just use return; to leave the Execute() method.
profile picture

Panache

#13
Thank you Cone.

QUOTE:
just use return; to leave the Execute() method.

I guess I'm not sure I completely understand. When I run this, it still runs the strategy against all the symbols in the data set.
CODE:
Please log in to see this code.

Using return does work better for my purpose than Abort(), since it doesn't open the Debug window and doesn't have the overhead of Abort() using PrintDebug() .

The WealthScript.Execute method appears to call a void Execute() to run the strategy, so I don't think I can return a value. Is there a way to end the WealthScript.Execute method after the first run?
profile picture

Eugene

#14
return; also avoids the overhead of raising an Exception. And no, apparently there isn't a way to end the WS processing after the first run. An Exception in one symbol does not stop the strategy processing of a multi-symbol backtest. This is how WL's backtester is designed to operate.
profile picture

Panache

#15
Sorry for all the trouble I put you through, but return is a pretty good solution for error checking.
profile picture

Eugene

#16
No worries. I'm fine with whatever works for you.
profile picture

superticker

#17
QUOTE:
... in the multi-symbol mode, Wealth-Lab continues to execute the strategy for each symbol in the data set, even though the strategy is aborted as soon as it is executed.
So you have two options:

1) Create a dataset with one stock in it, and run the strategy that way without the Abort call.

2) Don't create any dataset. Instead, create a one-stock entry in Strategy Monitor, and let SM run that "single stock" without the Abort call.

Both of these options should work without using an Abort or Return call, and without all that first symbol testing. I just don't understand where we are going with all this.
profile picture

Panache

#18
QUOTE:
I just don't understand where we are going with all this.

The most common way to run a Strategy is to run it against the DataSet name, and Wealth-Lab executes the Strategy once for each symbol in the DataSet.

Another alternative is to run it against one symbol in the DataSet, in which case Wealth-Lab only executes the Strategy once, but if the Strategy contains
CODE:
Please log in to see this code.

the code following that statement is run on each symbol in the data set. For someone like you, who has a lot of pre-trading code in their strategy, this runs faster, since the pre-trading code only needs to be run once.

Obviously, running a "foreach" Strategy against the entire DataSet is a very bad option. Let's say your data set is the S&P 500. That would mean your Strategy would operate on 500 symbols, and Wealth-Lab would run the Strategy 500 times!

What I was hoping to do was to prevent that possibility if I accidentally clicked on the data set name.
profile picture

superticker

#19
QUOTE:
a lot of pre-trading code in their strategy, this runs faster, since the pre-trading code only needs to be run once.
If the "pre-code" is DataSet independent, then you can put the pre-code in the constructor for your strategy along with the CreateParameter statements (which are also DataSet independent).

The problem is any data types created in the strategy constructor are going to hang around until you either close the Chart window (which ends that instance of your strategy) or call the destructor for your strategy. Since you want to be able to switch DataSets without closing the Chart window, that makes any DataSet dependent data types off limits to the constructor of the main strategy. You're stuck with that limitation unless you derive a ChildMyStrategy class from your MyStrategy class that would be locked permanently to a specific DataSet. Any DataSet specific data types created in the ChildMyStratety class (by its own constructor) would then be stuck in memory until you closed that ChildMyStrategy's Chart window, which may not be what you want. You might run out of memory if you fail to close too many ChildMyStrategy Chart windows (or at least the OS may start to page memory). I think this ChildMyStrategy approach may be a bad idea.

At any rate, employing constructors for the run-once code is the normal solution. But for WL, you have to be careful because you want the MyStrategy class to maintain its DataSet independence (in its constructor) so you can step through difference DataSets without terminating MyStrategy by closing its Chart window.
This website uses cookies to improve your experience. We'll assume you're ok with that, but you can opt-out if you wish (Read more).