Logical OR does not produce a buy when I expect
Author: infoff
Creation Date: 4/13/2019 5:28 AM
profile picture

infoff

#1
Hi,

I am trying to learn to use wealth lab pro and am running into an issue (have been for months but assumed I just needed more time to experiment and understand). I am trying to buy if either one of two conditions is true:

// Something like this in C
if ((MACD > 0) || (stochastic crosses above oversold))
Buy at Close

In the strategy editor it seems to look like this:

CODE:
Please log in to see this code.


which looks fine. The problem is when back testing this code does not produce a buy when I expect. In the symbol I am back testing for a year the first buy takes place 5/16/2018 with the code above. However if I comment out the cond1 = true code or just remove the cond1, i.e.

CODE:
Please log in to see this code.


then all of a sudden the first buy takes place on 4/19/2018 and there is much more activity throughout the period. Assuming funds are available (and they are) the first buy should be the earliest of the macd (cond1) and crossover check (cond2), but it seems this is not the case. Is this not an OR operator? What am I not reading or understanding correctly?
profile picture

Eugene

#2
Welcome aboard.

The code is fine and it does work correctly. Unfortunately, your problem report lacks some key detail and allows for guesswork. A helpful test case would at least indicate:

1. the symbol(s) used,
2. the data range,
3. position sizing,
4. have the complete code and
5. when exactly you expect the buy to happen?

So we neither know when you expect the buy (that isn't produced) nor the facts to prove that your expectation was incorrect or not.

This may be your position sizing (if set to ~100% equity), bigger seed period than you expect (26 bars for MACD by default, less so for StochK) etc. In addition, there may be a pitfall due to the use of an unstable indicator (MACD). So to get us going please provide the complete strategy code and required information.
profile picture

infoff

#3
Hi Eugene,

Thanks.

1. the symbol(s) used,
TQQQ

2. the data range,
1 Year

3. position sizing,
$5000

4. have the complete code and
The complete code is

CODE:
Please log in to see this code.


5. when exactly you expect the buy to happen?
I expected the entry date of the first buy to be 4/19/2018 at 11:30 AM at 51.92. I expect that because when I remove the cond1 that is the earliest entry.

Thanks again!


profile picture

Eugene

#4
Thanks for the followup.

1. Since you mention a time stamp (11:30 AM), is this intraday or EOD data? If intraday then what bar scale is this?

2. MACD is an unstable indicator with 26 bars of data as its lookback. According to the WealthScript Programming Guide (Help menu) > Indicators > Stability of Indicators, calculations should start 3-4 times the indicator's period (being the largest period used). Like this:

CODE:
Please log in to see this code.


For example, for 60-minute data (7 bars a day) you can expect a stable, valid first value of an unstable 26-period indicator like MACD to be churned out 26 * 4 times / 7 bars per day ~= 15 days since April 13, 2018 (because you're using a 1 Year range). I would expect a valid trade no earlier than on May 3rd, 2018.

This is something to consider when using unstable indicators.
profile picture

infoff

#5
Hi Eugene,

Thanks for the follow-up. I am using a scale of 30-minute date. This is code that comes directly from the "New Strategy From Rules" option. This is the "view strategy code window". I still don't get it. The OR means if either is true. Even if MACD is unreliable at this interval, the crossover bar for stoch K is and the two conditions are checked independently as needed. The stoch K is what should trigger the trade on 4/19, not MACD, but it doesn't seem to work when cond1 is also included in the branch conditional. When I change the if condition to only care about cond2 .. i.e.

CODE:
Please log in to see this code.


all of a sudden the stoch K triggers a trade on 4/19. So this still is not explained in my mind. How can:
(Cond2 == true) while ((Cond1 OR Cond2) == false))

If cond1 is not-working (always false) for a time period, that should have no impact on the 4/19 trade. I am at a loss here.

Also, your pointing out that there is this concept of unstable indicators brings up a different question. If I am looking at the performance tab and trades tab and trying to compare against buy and hold .. is there a built in way to get the buy and hold to show only once the simulation is considered stable, or do should I just put the trades in excel and figure it out.

Thanks.
profile picture

Eugene

#6
Hi Johnnie,

You get this perplexed result when caring only about cond2 because you get a crossover too early. The StochK is zero up until bar #14, then it returns a valid, non-zero value and this gets you a bogus crossover condition. To avoid this, condition your code like this:

CODE:
Please log in to see this code.


This way, the code checks for a non-zero value on the preceding bar - the condition you can get with StochK when it's not yet ready.

As it turns out, the EMA/MACD are ready at bar #1 due to an EMA formula change in an interim 6.9.x build. Still, they're "unstable" indicators and therefore setting the GetTradingLoopStartBar at the correct bar (i.e. the largest unstable indicator's lookback period * 3 or 4) should help make your simulation "stable".

P.S. Your concern re: B&H performance comparison is valid but applies only to a "long" indicators like 200-period EMA. Such a longer period may offset B&H comparisons and performance metrics sensitive to changes in start/end dates. To clear it up we've devised a code-based workaround: GetAllDataForSymbol from Community Components library lets you preloading the symbol's data and enable a system to trade on bar #1. But for 26-bar MACD in an intraday backtest there's nothing to worry about.
profile picture

infoff

#7
Hi Eugene,

Your explanation helps but I am still perplexed. It sounds like you are saying the StochK result is also not valid during that first buy (i.e. it didn't really cross zero at that point, it just became into existence). I will look closer at the bars to see this. What bothers me though is the same question ... why is that not the case when cond1 is being checked as well? I am a C programmer, compiler writer .. are there some optimizations taking place when I remove the use of cond1 that in turn change the lookback period for the loop? This simple example truly has stopped me from moving forward. I just can't make sense of (Cond2 == true) while ((Cond1 OR Cond2) == false). If this can be true then my C background won't be as helpful as I thought it would be.

I'll look into GetAllDataForSymbol. I am completely new to programming in wealth-lab pro but if I can understand my example then I will look to understand how to preload symbol data.

BTW .. you've been extremely quick and helpful in your responses. I appreciate it.

Thanks
profile picture

KGo

#8
MACD is > 0 thru 4/19/18 12:30 pm so a buy will happen any bar tested before then when cond1 is used. Comment out cond1 and the stochK buy happens as expected at 4/19/18 11:30 AM.

I used bar 16 start as shown above. You can start the macd check later and print the condition of each Boolean with
CODE:
Please log in to see this code.
profile picture

infoff

#9
Hi KGo,

Thanks for the debug code. This helps a lot and did not know this was available.
Code #1
CODE:
Please log in to see this code.


Code #2
CODE:
Please log in to see this code.


The only difference here is that code 1 gives more opportunity to buy at close due to cond2 being checked as well. The debug print is identical for both runs.

Code 1

QUOTE:

04/17/2018 11:30 AM True False True
05/16/2018 11:00 AM False False False
05/16/2018 11:30 AM False False False
05/16/2018 12:00 PM False False False
05/16/2018 12:30 PM False False False
05/16/2018 1:00 PM False False False
05/16/2018 1:30 PM True False True
...



Code 2

QUOTE:

04/17/2018 11:30 AM True False True
05/16/2018 11:00 AM False False False
05/16/2018 11:30 AM False False False
05/16/2018 12:00 PM False False False
05/16/2018 12:30 PM False False False
05/16/2018 1:00 PM False False False
05/16/2018 1:30 PM True False True
...


However even though code one produces more opportunity to trade on 4/19 by checking another boolean, a trade does not take place. In fact, only 2 trades take place for the year.

Code 1 Trades
QUOTE:

Position Symbol Quantity Entry Date Entry Price Exit Date Exit Price Profit % Profit $ Bars Held Profit per Bar Entry Name Exit Name MAE % MFE %
Long TQQQ 90 5/16/2018 1:30 PM 55.02 5/21/2018 11:30 AM 54.45 -1.35 ($66.89) 36 ($1.86) Group1| Group1 -3.41 0.83

Long TQQQ 79 6/13/2018 2:30 PM 61.51 6/19/2018 10:00 AM 60.19 -2.47 ($120.18) 44 ($2.73) Group1| Group1 -2.31 3.33



Code 2 Trades
QUOTE:

Position Symbol Quantity Entry Date Entry Price Exit Date Exit Price Profit % Profit $ Bars Held Profit per Bar Entry Name Exit Name MAE % MFE %
Long TQQQ 96 4/19/2018 11:30 AM 51.92 5/16/2018 11:00 AM 54.63 4.91 $244.58 247 $0.99 Group1| Group1 -15.49 9.30
Long TQQQ 91 5/17/2018 1:30 PM 54.55 5/21/2018 11:30 AM 54.30 -0.77 ($38.37) 23 ($1.67) Group1| Group1 -2.58 1.42
Long TQQQ 92 5/23/2018 10:00 AM 53.45 6/8/2018 3:00 PM 60.15 12.20 $600.20 154 $3.90 Group1| Group1 -0.75 15.30
Long TQQQ 81 6/14/2018 10:00 AM 62.53 6/19/2018 10:00 AM 60.19 -4.06 ($205.44) 40 ($5.14) Group1| Group1 -3.90 1.65
Long TQQQ 83 6/19/2018 11:00 AM 60.56 7/9/2018 11:30 AM 61.90 1.90 $95.52 160 $0.60 Group1| Group1 -9.55 5.74
Long TQQQ 77 7/16/2018 11:30 AM 65.02 8/3/2018 2:30 PM 65.18 -0.06 ($3.19) 189 ($0.02) Group1| Group1 -8.92 5.68
...



Can you help me understand this, where is the trade on 4/19 for code 1? Without adding code to change the guard on cond1, do you have an explanation for the difference in the code that I show where I simply commented out one additional check of a Boolean?

Looking at the debug output and all the print statements skipped between 4/18-5/15 this suggested to me the Code 1 did indeed make a purchase on 4/19, but I don't see it in the actual trades being shown (only 2 are shown) or the performance. The debug code helps and now gives me new questions.

Thanks.
profile picture

KGo

#10
Code1 and Code2 debug should not be the same. Therefore you did not recompile the code after editing. FIX: Do not press "Go" in the data panel after editing . It does not recompile. Press "Run the Strategy" on the code editing tab. That will compile and run.

Since trades are missing there is a position sizing problem. Make the Margin Factor 4:1 when you set the sizing for portfolio analysis. That should fix it. Or select "Raw Profit Mode" Fixed Dollar which will not skip any trades if the amount is greater than the share price.
profile picture

Eugene

#11
Johnnie,

QUOTE:
It sounds like you are saying the StochK result is also not valid during that first buy (i.e. it didn't really cross zero at that point, it just became into existence).

Yes, your understanding is correct.

With regard to what I've said in post #4 I'm not sure if you've corrected the trading loop's start bar? (Can't verify the test code right now, don't have access to intraday data).

QUOTE:
Thanks for the debug code. This helps a lot and did not know this was available.

There's another, advanced debugging technique intended for power users:

How can I debug my trading strategies in Wealth-Lab?

It's not required for this simple case but may be useful later on. Since you're a compiler writer (that's cool), hope this is not going to scare you off :)
profile picture

infoff

#12
Hi Eugene and KGo

I never said, but I am using wealth-lab pro v6.9.

@KGo
QUOTE:
"Code1 and Code2 debug should not be the same. Therefore you did not recompile the code after editing. FIX: Do not press "Go" in the data panel after editing . It does not recompile. Press "Run the Strategy" on the code editing tab. That will compile and run."


I have been only using the "Run the strategy" button. The debug output is the same, but the trades are different. Only two occur with Code1. I have not been pressing "Go" in the data panel.

I am using starting capital mode of 5000 with 5000 fixed dollar purchases. Margin is 1:1. Without making the adjustments (just to understand why what I currently have doesn't work) I thought the first trade using 5K would still take place regardless since I am starting with 5K?

@Eugene .. I did not modify the loop. I do get the lesson you are teaching about being careful about the lookback period and not using results that do not have an adequate look back period, but I see my question as much more basic. I am maybe being dense and I've repeated, but even with your comments about the lookback period I still just don't understand the differences in that initial buy results from this one change.

CODE:
Please log in to see this code.

vs
CODE:
Please log in to see this code.


Especially after looking at the debug results .. which @KGo is telling me is not valid and that I didn't compile. I don't get that, as I have only been using the run strategy button and the trade results table I show shows a difference. But KGo is right in that it doesn't match. I am looking at each line of code independently as I would with any C code but maybe that is throwing me off in this case. Is the whole iteration invalid if any data in that iteration is invalid?

There is no indicator warning about possible unreliable results so I have to be able to recognize that on my own. Being new, I am bound to overlook something or be unaware of some code that I am using that I unknowingly shouldn't be trusting but will. Keep in mind this is especially the case considering I did not write Code1. This code came directly from the "New Strategy From Rules" option wealth-lab pro provides which I thought would be a safe way to learn some basic in programming before moving to something more complex.

I'll just keep at it. Close the windows, take a few days off from this and then try again.
If not me, maybe this post can help another novice but in any case you guy's responses and attempts at helping me have been awesome.

Thanks
profile picture

Eugene

#13
I hear you stressing the test case which looks alarming to you based on your C experience. As a compiler writer you should be familiar with GIGO principle. For me your test case would make sense if you clean up for the Rule Wizard's (as we call it) imprecise output by 1) fixing the trading loop's start bar to account for EMA/MACD "instability" at the beginning of backtest and 2) conditioning the CrossOver (StochK) rule. The Wizard is quite powerful but in some borderline cases one has to be careful. Yes, there's no indicator warning about "unreliable" results - it wasn't part of the design. Backtesting is a double edged sword so it's a good practice to not blindly trust indicators etc.

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

KGo

#14
QUOTE:
I am using starting capital mode of 5000 with 5000 fixed dollar purchases. Margin is 1:1. Without making the adjustments (just to understand why what I currently have doesn't work) I thought the first trade using 5K would still take place regardless since I am starting with 5K?

Never use that setup if you want to ensure the trade takes place. WL calculates shares bought from the close price of the bar before the buy.For the 4/17/2018 11:30 AM TQQQ buy that's 5000/51.94= 96.2 truncates to 96 shares used. If the price rises before the buy, the shares * close price may exceed the $5,000 and the trade will be skipped. Buy is at 52.3666 *96 = $5,027.19 but there is only 5000 in the portfolio so the trade is rejected. Also know that if end of trade equity ever goes below $5000 no more trades will be taken. So generally that is not a good setup.

Using the Margin Factor as suggested in my post #10 above to allow the trade to be taken using $27.19 of margin. Please try it or add more portfolio capital. Also in post 10 was the suggestion to use Raw Profit mode Fixed Dollar which will also work.

For single positions systems I like 100% equity sizing with a large margin factor to avoid rejected trades.

You can put in the date and time to test buys with this:
CODE:
Please log in to see this code.
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).