Tools, Techniques, and Training for Nirvana Platforms |
OmniTrader, VisualTrader, OmniFunds & OmniVest |
| ||
| ||
|
|
2 Cor 9:8 (NET) ... And God is able to make all grace overflow to you so that because you have enough of everything in every way at all times, you will overflow in every good work. |
OScript Rule-Voting via Boolean Math | |||
|
JimDean |
| ||
Owner/Admin Posts: 3925 Location: USA: GA, Lawrenceville | Recently someone requested help with a scan on the N forum (click here for the thread):
This particular combination of conditions is very stringent and rarely will get any hits, even if you search all US stocks. BUT, the IDEA is a good one, and it's a nifty example to use to illustrate how "Boolean Math" works in OmniScript formulae. You can read through the original thread to see the discussion there ... but I'm summarizing the solution here, so that it's stored in TT and to encourage y'all to think it over and ask questions you may have. Also, I'm providing some further explanations ... The solution to the request is the OScan formula: EMA(20) - C >= 2*ATR(10) and OBV() > HHV( OBV(), 130 )[1] and Sum( ( H > HHV(260)[1] ), 20 ) < 0 ... but the problem is that it's so picky that it doesn't get any hits. One way to make it work is to "loosen up" the rules somehow, making the HHV periods smaller or reducing the ATR mult, etc ... but another way is to leave each of the three rules as-is, and modify the scan so that symbols can pass if they satisfy ANY TWO of those three rules, rather than all three at once. This is accomplished by slightly changing the formula to: ( EMA(20) - C >= 2*ATR(10) ) + ( OBV() > HHV(OBV(),130)[1] ) + ( Sum((H > HHV(260)[1]),20) < 0 ) <= -2 ... NOTE the steps that I took: 1. I enclosed each relational-boolean rule in parentheses 2. I replaced the "and's" with "+" signs 3. I added a final boolean test "<= -2" at the end By enclosing each rule in parentheses, it forces the parser to evaluate that rule and substitute a numeric value for it, before moving on. So, each rule gets resolved to -1 if it's true, or 0 if it's false. When the three rule-results are added together, the answer will be either 0, -1, -2 or -3 depending on how many are true for that symbol on that bar. You can do this with ANY NUMBER of rules, and you can set the vote-threshold (here, 2 out of 3) to be whatever you want. This is VERY POWERFUL for use in OScan, CC's, EZ-Setups, TP Conditions, and now also in OmniVest conditions. BUT THERE'S MORE, if you look more carefully at the formula ... Boolean math is being used INSIDE of the third rule: Sum((H > HHV(260)[1]),20) < 0 That rule is saying: "for a given bar, report a true (-1) condition if it's high exceeds the highest-high of the 260 bars that precede that bar ... do that twenty times, from the current bar backwards, and ADD UP the results ... if ANY of those bars passed its test (ie reported -1=true), then return a true condition" ... that's saying a LOT! This ability to use the Sum function to check a SERIES of bars to find out whether a condition is true for any of those bars is VERY handy. You could write a substitution for the Sum-function, as a list of twenty individual tests: ( H > HHV(260)[1] or H[1] > HHV(260)[2] or ... H[19] > HHV(260)[20] ) ... but that's a pain. And think of this ... let's say the original request had been a little different ... let's say the person wanted the scan to find cases where stocks "made a 52 week high FOUR TIMES in the last 4 weeks" (any four times). This could theoretically be done with a LOT of individual clauses with or's and and's, but it would take 20*19*18*17 = 116,280 lines to do so ... I think my keyboard would break. INSTEAD, you can modify the Sum() formula with three keystrokes to test the "four times" rule: Sum((H > HHV(260)[1]),20) <= -4 This is cool stuff. I hope you find it useful! | ||
JimDean |
| ||
Owner/Admin Posts: 3925 Location: USA: GA, Lawrenceville | Here's a little OmniLanguage routine that illustrates the same concept: #indicator #param "Thresh", 2, 0, 5 dim Test as integer ' use boolean-math to calculate how many "rules" are satisfied, ' then compare to the input threshold required number of rules ' the value of Test will be -1(True) if an adequate number of ' rules are satisfied ... otherwise the value will be zero. Test = ((C>C[1]) + (C>C[2]) + (C>C[3]) + (C>C[4]) + (C>C[5])) >= -Thresh setscales(-1.5,1) ' to make output clearer plot("Test",Test) return Test | ||
JeremyLane |
| ||
Spectator Posts: 8 Location: : , | Thanks for posting this Jim, I never knew OScript was capable of this. I particularly like the SUM case because I had been wondering how to do setups like "the stock has made 2 highest highs over the last X period" and I think that this is a solution. | ||
JimDean |
| ||
Owner/Admin Posts: 3925 Location: USA: GA, Lawrenceville | Boolean math, and IIF(condition, truetarget, falsetarget) clauses are the two most powerful features of OmniScript ... allowing it to do things that most folks would think require a true multiline routine. True, btw, for formula engines like Excel as well, if you don't like having to write macros (Excel's OLang). | ||
JohnB |
| ||
Friend Posts: 29 Location: : , | Jim thanks for showing this. I was wondering if there is a boolean way to question a system in O/L to see if it is firing long or short signals without re writing the system as an indicator. For instance is there a way to take the output of the plugin ACCI - C and combine that into a system or indicator perhaps code something like "If ACCI-C(6,50) = Long then"? I think the answer is no but just incase ther is a way should love to know. Thanks JohnB | ||
JimDean |
| ||
Owner/Admin Posts: 3925 Location: USA: GA, Lawrenceville | Nope. Systems and Stops and Strategies don't return values that are accessible to OLang or OScript, in any form, though it's been requested many times. Only Indicators can be used that way. If your System IS in OLang, then it can be modified easily to be an Indicator, which then can be called from OScript or OLang. In fact, it's possible to convert an entire Strategy (if you have access to all the internal logic) to an Indicator. But that's the limit of it. | ||
JimDean |
| ||
Owner/Admin Posts: 3925 Location: USA: GA, Lawrenceville | Another thread that provides some info about Boolean-Math in OmniScript (for OmniVest equity-curve checks): http://tradetight.org/forums/thread-view.asp?tid=1072 | ||
JimDean |
| ||
Owner/Admin Posts: 3925 Location: USA: GA, Lawrenceville | Another example of this is given in answer to a posted request for finding stocks with price above an MA for X days, here: http://tradetight.org/forums/thread-view.asp?tid=298#M6250 | ||
VinayJain |
| ||
Regular Posts: 59 Location: India: , Bangalore | This Boolean math trick (SUM) is brilliant. However for some reason it doesn't work with Setups. I used the following code in one Setup box to paint it green if the stock made 52 weeks high on any day during last 5 days otherwise yellow: Sum( ( H > HHV(250)[1] ),5 ) < 0 However it displays green only if the stock in question has made 52 week high on previous day. If it made 52 weeks high on any other day during previous 5 days it doesn't show green but shows yellow. I think it's a bug. | ||
JimDean |
| ||
Owner/Admin Posts: 3925 Location: USA: GA, Lawrenceville | Try changing formula to: Sum( ( H > HHV(H[1],250) ),5 ) < 0 If that doesn't work try: Sum( ( H > HHV(H[1],244) ),5 ) < 0 … I'll explain later if it turns out second idea works but first doesn't. | ||
VinayJain |
| ||
Regular Posts: 59 Location: India: , Bangalore | Jim... I tried both but unfortunately these formulas are also not working. I am getting same results from the formula I posted as well as your alternate formulas. Anyways thanks for your help. | ||
JimDean |
| ||
Owner/Admin Posts: 3925 Location: USA: GA, Lawrenceville | You can try making an OScan, or convert it to OLang and test it as a sorted FL column. Or attach snapshots of your Setup definition. Or, just do it manually: H > HHV(H[1],250) or H[1] > HHV(H[2],250) or H[2] > HHV(H[3],250) or H[3] > HHV(H[4],250) or H[4] > HHV(H[5],250) I'd be surprised if there was an OT "bug", since this is just straightforward logic of the sort that's worked in many situations before. Let us know what the other tests reveal. If all of them yield the same result then maybe publish some charts to illustrate what is going wrong so that others can try to duplicate the problem. | ||
VinayJain |
| ||
Regular Posts: 59 Location: India: , Bangalore | When I create OmniScan with these formulas: 1. Sum( ( H > HHV(250)[1] ),5 ) < 0 as created by me (based on your tip) and 2. Sum( ( H > HHV(H[1],250) ),5 ) < 0 the alternate formula suggested by you both of them give correct and identical result however both are not working as expected with Setups. So it appears that there is some problem with Setups when such formulas are used. I have yet not tried the manual method: (H > HHV(H[1],250) or H[1] > HHV(H[2],250) or H[2] > HHV(H[3],250) or H[3] > HHV(H[4],250) or H[4] > HHV(H[5],250) But even if that worked it is not as neat and elegant as the former formulas. | ||
JimDean |
| ||
Owner/Admin Posts: 3925 Location: USA: GA, Lawrenceville | Ok that means the parser is working properly. If you'd like to post snapshots of your Setup config, that might help. | ||
VinayJain |
| ||
Regular Posts: 59 Location: India: , Bangalore | Jim... I have attached here the Setup I used for testing. The first square contains my original formula, the second square have the alternate formula as suggested by you and the third square has the manual (long) formula. 1. If the previous bar meets the condition of having made 250 days high then all the three squares show green which is as expected. 2. However in other cases (250 days high made on day before yesterday or earlier) the three squares show unpredictable and different combination of colors which means these three formulas produces different results. Attachments A1.ez.txt (1KB - 5 downloads) | ||
JimDean |
| ||
Owner/Admin Posts: 3925 Location: USA: GA, Lawrenceville | Hmm - I agree that seems odd. As you mentioned, Setups work sequentially- i.e. If the first rule fires then the other squares are not tested. That would partially account for the seemingly "random" results. I'd suggest that you send Barry this text file, plus a link to this thread, plus *screenshots* that illustrate a faulty result for a particular symbol. The only other possibility that I can think of is a corrupted profile - you might try starting with a brand-new one before you send this in. Since your test using OScan had no problems, then it's safe to conclude (I think) that the bug if any does not relate to the subject of this thread (Boolean math), but rather to the mechanisms of the Setup engine. | ||
JimDean |
| ||
Owner/Admin Posts: 3925 Location: USA: GA, Lawrenceville | Yet another OT forum question about this ... here's a reprint of my reply. The original posting is here: Click here You asked for a way to plot or utilize this rule: If the low of the bar is greater than a moving average, assign it a value of 1 and if the MACD is greater than 0 also assign it a value of 1 so when the two conditions are met, I should get a value of 2 Let's say the MA is EMA(14), and the MACD is MACD(12,26). The first query asks "is the Low greater than the MA" ... the formula for this: L > EMA(14) ... will return true (a value of -1) or false (a value of 0) The second query asks "is the MACD greater than zero" ... formula is: MACD(12,26) > 0 ... again, will return true (a value of -1) or false (a value of 0) You can combine these in two ways ... one uses Boolean logic, and the other uses Boolean math: Boolean logic: #indicator dim rules as integer if L > EMA(14) and MACD(12,26) > 0 then rules = 2 elseif L > EMA(14) or MACD(12,26) > 0 then rules = 1 else rules = 0 end if return rules Of course you need OLang to implement this. It could be done in OScript (ie a quick indicator or color chart, etc) using the "iif(condition,true,false)" rule, but that's sort of messy so I won't go into it further. The most "elegant" way to solve this is using Boolean math. That's a term I invented (afaik) to describe boolean-logic mixed with algebraic operations. Note above that true= -1 and false= 0. This means we can "add" (or subtract or multiply or many other things) two boolean expressions. The key to doing this is simple: wrap each boolean expression in parentheses, then plug those expressions into a math formula, thus: ( L > EMA(14) ) + ( MACD(12,26) > 0 ) ... this returns a value of 0, -1 or -2 (since True = -1) If you want positive values, simply insert minus signs in the formula: -( L > EMA(14) ) - ( MACD(12,26) > 0 ) You can PLOT that formula as a Quick Indicator and you will see a stairstep-wave with values of 0, 1, 2 HOMEWORK: Play with this using other functions, other boolean rules, and other algebra. It's amazing what you can do if you just experiment! | ||
|
Owner of site: Jim Dean -- Forum content is confidential, and may not be distributed without written permission. | |