Custom Indicator Macro

I have a long and complex formula that I commonly use multiple times in my scans. Is there any way to write a "macro" for such an indicator that I can reuse multiple times in a single scan or across multiple scans (similar to the way StockCharts' allows "Daily Engulfing Bullish" to be reused without duplicating the syntax of that complex indicator)? If not, is there a way to store the value of a formula in a local variable in the scan to reuse in a "rank by" clause to reduce scanning time? Note that this is different from a UDI.

One of my particularly nasty scans (3336 characters long) keeps getting grounded for taking too long, but because it has to repeat the same nested indicator calculations every time I need to evaluate it or rank by it. If I could somehow store the results of several nested indicators in variables and reference them in various places, it would speed the scan up tremendously.

Basically, I am scanning for four of six nested indicators to meet my criteria. Because any four will do, there are 15 valid combinations to get at least four of six. However, this means I have to calculate 60 nested indicators (4 x15).

I did notice that the "Bullish Engulfing" candlestick scan checks to see whether the indicator "Daily Bullish Engulfing" equals "1". I tried comparing my formula to a value to see if the result equated to "1" if it tested true. Alas, even a simple example such as "rank by [(close > 50) = 1]" grounds the scan with the message "The Scan Engine is taking too long to return your results. Please try again later." If I could figure out a way to equate a comparison to 1 (true) or 0 (false), then I can just add up the results (I have been able to get simple arithmetic to work in a scan).

Well, I think you are getting grounded because your code passes syntax, but doesn't conform to the scan engine's expectations (so to speak).

The scan engine language is NOT a full fledged programming language, although it is still very flexible. It is intended to return ONLY symbols that meet the combination of conditions that you specify.

Usually, those conditions have to do with built-in indicator states and symbol properties, although you can include calculations, like say,

and [ [high + close + low]/3 > 20].

But most of the complex math you might need is done for you with built in functions. For instance, a 20 period moving average is "sma(20, close)". You don't need to write out the whole thing.

The scan engine language does not return values, pass values, or store values, or throw errors, or anything else that other languages do - it is purpose built to JUST returns symbols.

Usually, scan conditions are very simple - for instance, exchange is NYSE and close > 20 and close < 50 and volume > 100000 and MACD Line crossing above MACD Signal. As you noted with Bullish Engulfing, a lot of the work is done for you. You don't have to specify the calculations for MACD or a candle formation, that's done for you. You can make scans very complex, but you do it by usually by combining lots of simple statements.

So, if you come from a programming background in a complete language, like C or VB, where a lot of things are not built in, you have to re-think things a little.

For instance, in the scan engine, "1" does not equal true, or "0" false. That is not a feature of the scan language. So, my guess is, the scan engine could not resolve your rank by statement, so it gave up. If your statement is valid, it will pass syntax, and the scan will return all symbols, if any, for which that statement (together with your other statements, if any) is true. Note that a statement can pass syntax if it is syntactically correct but logically inconsistent (within the scan engine environment), as I assume your rank by statement did.

So, if your intent, among other things, was to capture only stocks greater than 50, and order them by close, your scan would have two statements:

// begin scan

... //other conditions, if any, like exchange or market cap or industry

and [close > 50]

... // other conditions, if any, like indicator states

rank by close

// end scan

As for writing your indicator conditions multiple times:

If only one needs to be true, and it doesn't matter how many others are true, you should be able to write each of them just once in a series of "or" conditions:

// begin scan

[exchange is NYSE]and [close > 50]

... other stuff, if any

and

// next line is opening "or" bracket

[

[ code for indicator 1]

or

[ code for indicator 2]

or

...

or

[ code for last indicator]

// next line closing "or" bracket

]

rank by close

// end scan

Note the opening and closing brackets that contain all your "or" conditions - these are absolutely necessary to separate the conditions that don't ALL have to be true (the indicators) from those that do have to be true (like close > 50 and exchange is NYSE).

Re-reading your post, I see that you need AT LEAST four of the indicator conditions to be true, but it doesn't matter which four, so you want to test for all possible combinations of the six conditions.

That's a bear.

I don't think the scan engine is the place to do it, unless, as you've suggested, you code for each possible combination. As you've implied, it can't keep track of the "or" conditions that are true. You would have to do that outside the scan engine by keeping the results in lists, or in spreadsheets and then devising a way to merge them.

Or else re-think the problem to determine which indicators are essential and which nice to have, or prioritize them and run sequential scans starting from the most important indicator(s).