WL5 Help in Bite Sized Chunks
Author: Bandit292
Creation Date: 7/14/2008 8:45 PM
profile picture

Bandit292

#1
Hi gang. I have obtained WL5 from Fidelity and have given it a test drive or two for familiarity. I have skimmed the User Guide and the WealthLab Script Guide. I am somewhat overwhelmed with the capabilities, so will continue to trade using my current caveman tools while I learn to customize WL5 in my off-trading hours. I have a VB6 programming background building front-ends for Access & SQL Server database backends -- very much a one trick pony without any programming for the past two years. I can (and will) dig into C# on my own, but can understand the script examples posted here so far.

I would like to use this single thread to throw out questions in bite sized chunks, digest the inputs, and then come back with follow-up questions before moving to the next step. In this manner, I hope to crawl, walk, then run with this tool. If I ask a stupid question, refering me back to the User/Script guide is fine by me.

Issue #1 - Customize Candlesticks:
Can I customize candlestick charts so that up bars with an open to close price change less than some user defined percentage are displayed in a separate user defined color? Example, say the user wants all up bars greater than .2% change to display as the default green, all down bars greater than the same .2% to display as the default red, and all bars with less than a .2% change to disply yellow. Can I do this by customizing the existing Candlestick charts or will I need to develope a new Candlestick Chart Class?

Thanks ...
profile picture

Cone

#2
You can programmatically change the bar color using the SetBarColor method. See the QuickRef - Cosmetic Chart category for functions that work with the visual chart.
profile picture

Bandit292

#3
Got it -- working on the solution, but I run into a problem trying to get the absolute value of a number:
double perChange;
perChange = abs(Close[bar] - Close[bar-1])/Close[bar-1];
... this isn't working for me. Do I have the syntax wrong?

Thanks ...
profile picture

Bandit292

#4
Here is what I have so far:

CODE:
Please log in to see this code.
Next issue is -- the parameter perChange is hard coded. How do I make it a user selectable paramenter say from zero to .05 in .01 increments with default set to .01?

Thanks again ...
profile picture

Eugene

#5
CODE:
Please log in to see this code.


Unfortunately it seems like C# favors unambiguity so well that does not accept this figure. So we should be precise and use 0.01 here.

QUOTE:
Next issue is -- the parameter perChange is hard coded. How do I make it a user selectable paramenter say from zero to .05 in .01 increments with default set to .01?


For that, StrategyParameter and then CreateParameter are used. Please revisit one of the bundled strategies that demonstrate the parameter usage or see my code below. For an overview of the functionality, see "Strategy Window - Strategy Builder - Parameter Sliders for the Strategy Builder" in the User Guide.

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

Bandit292

#6
Eugene,

Thanks a million for the detailed help. While I review your User Guide reference and get comfortable with a few more applications of user selectable parameters, here is another quick question:

Can I modify the candlestick display so all bars are filled in, not just the default down bars. Shooting for a display of solid red, green, and yellow candlesticks.

Thanks again ...
profile picture

Bandit292

#7
Eugene,

I'm getting the hang of user defined parameters from your code snippet, however ...

Just a quick note to see if maybe I need to get an updated User Guide:

I can't locate topic "Parameter Sliders for the Strategy Builder" but I do see the main topics "Strategy Window - Strategy Builder" that you pointed me to.

profile picture

Eugene

#8
QUOTE:
I can't locate topic "Parameter Sliders for the Strategy Builder" but I do see the main topics "Strategy Window - Strategy Builder" that you pointed me to.


Sorry for inconvenience. Most likely there was a change in it for 5.1.

QUOTE:
Can I modify the candlestick display so all bars are filled in, not just the default down bars. Shooting for a display of solid red, green, and yellow candlesticks.


There was an option to fill candlestick body in 4.x but it's not present in 5.0-5.1.
profile picture

Cone

#9
The "fill in Candlesticks" option just isn't in the same place as 4x. Right click the chart, select "Chart Style Options (Ctrl+Y)", and check "Fill Candlesticks".

All Chart Styles are "non native" and therefore their options are in "Chart Style Options (Ctrl+Y)".
profile picture

Eugene

#10
Thanks now I know where it is :)
profile picture

Bandit292

#11
RE: Candlestick Fill
Works well. Thanks for that hint.

RE: 5.1 Update
Any idea when Fidelity will have an update for us? What else might we anticipate from that upgrade?
profile picture

Bandit292

#12
Hi Gang,

Stealing from the RSIAgita strategy code included in the software I can create an RSI indicator via code:

CODE:
Please log in to see this code.


Rather than draw the horizontal line overbought & oversold indicators, how do I access the Indicator Properties via code to create and color the oscillator like you can when you right click the RSI indicator and select the "Change Indicator Properties" option. Note that right clicking on the code created RSI indicator will not give you the "Change Indicator Properties" option, but if you drag and drop an RSI indicator onto the chart pane, right clicking that RSI indicator will give you that option. Once selected, the right side of the property box gives you the option to draw and color the oscillator as desired. I need to know how to control these oscillator options via code.

Thanks in advance ...
profile picture

Eugene

#13
QUOTE:
Note that right clicking on the code created RSI indicator will not give you the "Change Indicator Properties" option, but if you drag and drop an RSI indicator onto the chart pane, right clicking that RSI indicator will give you that option.


Right, this is by design.

QUOTE:
how do I access the Indicator Properties via code to create and color the oscillator like you can when you right click the RSI indicator and select the "Change Indicator Properties" option.


To duplicate the feature-rich Indicator Properties functionality in code, see the QuickRef example for PlotSeriesOscillator.
profile picture

Bandit292

#14
Eugene,

Good reference. Works great. How can I set the overbought & oversold colors to a transparance like 75%. I can do this via the drag & drop indicator, but don't see the property as one of the options in PlotSeriesOscillator. Is it, perhaps, a function of the color properties?

Thanks again ...
profile picture

Bandit292

#15
Ref above listed transparancy request:
I am now using LightSalmon and LightBlue. This selection closely mimics Red and Blue at 75% transparancy. I would still like to know if transparancy can be set via code or if it is embedded in the different color selections.

Thanks again ...

profile picture

Eugene

#16
QUOTE:
How can I set the overbought & oversold colors to a transparance like 75%. I can do this via the drag & drop indicator, but don't see the property as one of the options in PlotSeriesOscillator. Is it, perhaps, a function of the color properties?


Bingo! You need to call any of the two overloads of Color.FromArgb that accept alpha value ranging from 0 to 255 as the transparency parameter. See Color.FromArgb Method page in MSDN for details.

CODE:
Please log in to see this code.

Here's an example which illustrates both of these overloads:
CODE:
Please log in to see this code.
profile picture

Bandit292

#17
Color.FromArgb(75, Color.Blue) & Color.FromArgb(75, Color.Red) work as advertised.

Thanks, again, for all the good help.

I'll be back with a few more questions about entering and exiting positions based on current RSI related to the RSI for the previous two bars. I'm going to try entering, exiting, or reversing a position once a certain RSI value is registered if the current value is a reversal in the RSI trend.

IOW, a long position would be established when the RSI is above a certain trigger value on bar #3 as long as bar #1 & #2 are the first two values above the trigger, bar #2 is greater than bar #1 (trending up) and bar #3 is less than bar #2 (a one bar reversal) but still above the trigger value. The system would stick with that long position as the RSI continues to increase until it hits an even higher (overbought) value or cover (sell) on a three bar retreat back below the trigger value. Once in the overbought region, the same two bars up with a bar #3 reversal would trigger an exit from the position or a reversal into a short position.

Do you know of any example code I can review that works with RSI entry & exits more complex than a single value above or below a trigger point?
profile picture

Eugene

#18
Perhaps something like that for the entry (coded on-the-fly):

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

Bandit292

#19
That is the core idea. I need to add more qualifiers, but you have given me a good jumping off point. Let me fiddle with this a few days and get back with more questions.

Thanks, again. You are a great help.
profile picture

Bandit292

#20
Maybe this isn't the right forum, but I have another installation related question.

I installed C# Express 2008, but am having no luck installing SQL Server 2005 Express. I did a complete uninstall and registry cleanup of MSSQL7 and even run the MS web page cleanup tool prior to installation, but keep getting booted out of the installation about 75% of the way through with no error message. Any ideas? Should I even bother, or just reinstall my older version?
profile picture

Bandit292

#21
Final question for today in relation to your code sample above.

You use:
for(int bar = 50; bar < Bars.Count; bar++)
I also have in my current code:
for(int bar = 1; bar < Bars.Count; bar++) ... for coloring some candlesticks yellow
and:
for (int bar = period + 1; bar < Bars.Count; bar++) ... for my trading system main loop

I understand the need for different evaluation and increment inputs, but I'm failing to conceptually grasp why we are initializing the "for" loop counter at different values (50, 1, and period +1). Is there some rule of thumb for why we would select a specific initialization setting. In the case of your code, why did you initialize at bar 50?

Thanks again ...
profile picture

Eugene

#22
QUOTE:
Maybe this isn't the right forum, but I have another installation related question.

I installed C# Express 2008, but am having no luck installing SQL Server 2005 Express.


Looks like you've already answered your question :)

QUOTE:
why we are initializing the "for" loop counter at different values (50, 1, and period +1).


I initialized this for loop at bar 50 (although I could have done at 40, for example, considering the indicator period) because of RSI being an "unstable" indicator. You'll find guidance in the WealthScript (Programming) Guide, Indicators > Stability of Indicators.

Initializing at bar 1 in snippet from 7/16/2008 2:58 AM happened because the code required only the closing price value offset by a single bar, and no other indicators with the need to stabilize.
profile picture

Bandit292

#23
Wow!!! I did a little testing with the code supplied in your Indicators.Stability of Indicators Programming Guide reference, with particular attention to RSI. Now I am looking for some good performance vs. accuracy rules of thumb.

From the testing I did changing the RSI period across various fixed bar data ranges, it looks to me like you need to use a data range at least three times the RSI period to get stable results. The results became more stable at data ranges equal to five times the RSI period. Above that, it looks like the increase in accuracy is not worth the performance drag.

Am I in the ballpark here? If I intend to use an RSI period of 20-40 bars, my data range should be 60-120 bars for minimal accuracy and 100-200 bars for higher levels of confidence. Beyond that, we are just chewing up CPU cycles.

Thanks again ...
profile picture

Bandit292

#24
One more quick question before I head for bed -- how can I get a 10-Day average volume line in the volume pane?
profile picture

Eugene

#25
QUOTE:
how can I get a 10-Day average volume line in the volume pane?


a) By passing VolumePane as a PlotSeries parameter in your code:
CODE:
Please log in to see this code.

b) By dragging the average from the Indicators list and dropping to the Volume pane.

QUOTE:
Am I in the ballpark here? If I intend to use an RSI period of 20-40 bars, my data range should be 60-120 bars for minimal accuracy and 100-200 bars for higher levels of confidence. Beyond that, we are just chewing up CPU cycles.


Yes.
profile picture

Bandit292

#26
OK, I was cruising along just fine and ran head-on into big problems. The code compliles fine, but gives me all these errors when I run it:

QUOTE:
Runtime error: Index was out of range. Must be non-negative and less than the size of the collection.
at WealthLab.Strategies.CandlestickTails.Execute()
at WealthLab.Indicators.SMA.Value(Int32 bar, DataSeries ds, Int32 period) in S:\vobs_wealthlab\src\dotnet\WealthLab.Indicators\SMA.cs:line 44
at WealthLab.DataSeries.get_Item(Int32 i) in S:\vobs_wealthlab\src\dotnet\WealthLab\WealthLab\DataSeries.cs:line 52
at System.Collection.Generic.List 1.get_Item(Int32 index)
at System.ThrowHelper.ThrowArgumentOutOfRangeException()
at System.ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument, ExceptionResource resource))


This is the first set of error messages I have not been able to work with as line 44 is just an open bracket and line 52 is a code comment. This happened just after trying to build in long and short entry resrictions based on 50/200 SMA data. Here is the code:

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

Cone

#27
The main problem is that you're using a 200-period SMA, but not confining the variable range (the one used for the first bar index) to be at least 200.

Also, you should not use the .Value method as you have done. This forces a re-calculation of the SMA for the specified bar. In general, if you don't need to use the Value method, you should not. Replace those lines:

CODE:
Please log in to see this code.


profile picture

Bandit292

#28
Cone,

Thanks a million for the quick reply. I solved issue #1:

CODE:
Please log in to see this code.


I also used your smaXX[bar] inputs. I didn't stumble on your syntax solution, but when reviewing the user guide concerning the .Value method, I actually assumed forcing a re-calculation was something I would want to accomplish. The simple nature of the SMA, however, makes your suggestion look like the way to go.

What clues in the error message should I have used to key in on the range error (obvious in hindsight now). Still, looking at the error message and reference to lines 44 and 52 would not help me debug this without your inputs.

Thanks again ...
profile picture

Cone

#29
This runtime error is .NET that specifies that the index to a collection was out of range. You only have to review the collections that your using (all Data Series, Bars, and ActivePositions) and the bounds of the indices that you're passing to them.

For something a little harder, you might try commenting out blocks of code until you zero in on the error. And then if it's "really difficult" you'd might have to resort to using a real debugger. See this KB article.
profile picture

Bandit292

#30
Back again with more questions. I'm still mucking around trying to learn enough C# to be dangerous by modifying existing code. I'm currently working with the 3x2 code and have modified it:
CODE:
Please log in to see this code.


Questions:
1.) The first trading system line
CODE:
Please log in to see this code.

what value would you use to initialize the range and why?
2.) How can you set a parameter's min value based on another parameters selection. In my example, say I wanted the dnBarsOut min selectable value to be equal to the dnBarsIn selection -1. How would I code that?
3.) How would I use a DataSeries reference to be more efficient rather than the Value method I have used to reference CumUp.Value & CumDown.Value?
4.) My maximum holding period code does not work. It kicks me out of all trades well before the max bars holding period. Why?

Thanks in advance ...
profile picture

Eugene

#31
QUOTE:
what value would you use to initialize the range and why?

I would initialize the range here as the greater of upBarsIn and dnBarsIn. No need to sum maxBarsLong/maxBarsShort because they come in later in the game, after a position has been created.
QUOTE:
3.) How would I use a DataSeries reference to be more efficient rather than the Value method I have used to reference CumUp.Value & CumDown.Value?

Use the .Series instead.
QUOTE:
4.) My maximum holding period code does not work. It kicks me out of all trades well before the max bars holding period. Why?

Because, as indicated in the QuickRef entry, the BarsHeld property is primarily suitable for Performance Visualizers and not Strategies.
Use a variation of this pattern for time-based exits:
CODE:
Please log in to see this code.


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

Bandit292

#32
Thanks for the quick inputs. Let me work with this some and get back for more questions.

One question right off the bat. I do not understand the use of IsLastPositionActive as the key criteria for most exit rules. I can understand if you are building a system with no more than a single position at any one time, but it seems to fail the test for multiple position strategies. What if the LastPosition is no longer active? Why would you want to skip past prior positions with the exit rules? Why don't most strategies iterate through all positions and drill down to the active positions to implement the exit rules. I must be missing a key part of the big picture here.

Thanks ...
profile picture

Bandit292

#33
I have had a chance to review the code suggestions. In addition to the question on using IsLastPositionActive posted above, I am equally baffled by another simple concept that I can't seem to grasp. In the Data Series code you select an intPeriod value of one for both data series:
CODE:
Please log in to see this code.

Why the selection of one for the data series period? I would assume the intPeriod values should cover the number of bars we may be evaluating:
CODE:
Please log in to see this code.

What simple concept am I failing to grasp here?

Thanks ...
profile picture

Bandit292

#34
One last question as I head for bed -- how can I increase the height of the Strategy Parameters box for easy access to multiple parameter sliders so I don't have to scroll when backtesting to swap parameters?

Thanks ...
profile picture

Eugene

#35
QUOTE:
One last question as I head for bed -- how can I increase the height of the Strategy Parameters box for easy access to multiple parameter sliders so I don't have to scroll when backtesting to swap parameters?
No, only scrolling works there.
QUOTE:
What simple concept am I failing to grasp here?
I suggest bringing up the Indicators list and clicking the CumUp/CumDown entries for their online documentation.
QUOTE:
I do not understand the use of IsLastPositionActive as the key criteria for most exit rules. I can understand if you are building a system with no more than a single position at any one time, but it seems to fail the test for multiple position strategies.
Your understanding is to the point. The pattern above is useful in a single position trading system.
profile picture

Bandit292

#36
Again, thanks for the quick replies and suffering through my ignorance.

QUOTE:
I suggest bringing up the Indicators list and clicking the CumUp/CumDown entries for their online documentation.

First, I completely missed the "more info" link at the botom of the drag & drop indicators list. After reviewing the info, however, I am still at a loss for why the intPeriod value of "one" works when we are looking back over a period of bars. I know it works, because I used your "one" value rather than my "dnBarsIn/upBarsIn" recommendation, but from the documentation:
QUOTE:
source - Price series
period - Indicator calculation period
...
Description: CumUp lets you test whether a specific number of consecutive bars have elapsed where the prices are greater than their value a certain number of bars ago.
...
Calculation: CumUp is a running count of the number of bars whose Series value is above its delayed Series; in other words, Series offset forward by the Period.

My feeble brain interprets this to mean that if we are looking for, lets say, 3 consecutive UP bars then the calculation period "intPeriod" would have to be at least 3 and not 1. What am I missing here???

QUOTE:
Your understanding is to the point. The pattern above is useful in a single position trading system.

OK, so for a potential multi-position system, is my original loop code correct or would you code it in a different manner?
CODE:
Please log in to see this code.


Final question before I head for bed. To help fine tune a strategy, it would be nice to add custom columns to the "trades" tab behind the MAE/MFE% columns. Say, for example, I wanted to print the 20-bar SMA at the time a position was entered and again when exited to custom columns in the "trades" tab. Where would I find info for accomplishing that in the users guide?

Thanks again ...
profile picture

Eugene

#37
QUOTE:
My feeble brain interprets this to mean that if we are looking for, lets say, 3 consecutive UP bars then the calculation period "intPeriod" would have to be at least 3 and not 1. What am I missing here???

Nope. For 3 consecutive up bars, you'd need to supply exactly "1" as the indicator parameter. This "1" would then mean that Wealth-Lab checks for a consecutive condition on each bar. As long as the resulting number exceeds 3, we have had 3 consecutive up bars.

Specifying "3" as the parameter would result in a somewhat different scenario: you would scan for 3 consecutive bars where the closing price remains over than the closing price 3 bars ago.


QUOTE:
Final question before I head for bed. To help fine tune a strategy, it would be nice to add custom columns to the "trades" tab behind the MAE/MFE% columns. Say, for example, I wanted to print the 20-bar SMA at the time a position was entered and again when exited to custom columns in the "trades" tab. Where would I find info for accomplishing that in the users guide?

Creating user columns in the Trades view is unreachable from Strategy code. For that, one have to build a custom Performance Visualizer like this example demonstrates:
Trades-v2 with Priority and multi-column sorting
Binary file and source code

However, it's simply possible to pass the 20-bar SMA value as entry/exit signal name parameter.

QUOTE:
OK, so for a potential multi-position system, is my original loop code correct or would you code it in a different manner?

The code seems right, but there's a new pattern in WL5 built for speed:
CODE:
Please log in to see this code.

The ActivePositions list allows to loop in active positions only.
profile picture

Bandit292

#38
Eugene,

I don't know how to thank you enough for all the good inputs.

RE: CumUp & intPeriod
Got it. Just to make sure -- a CumUp(Close, 5) = 16 would tell me that on this bar, bar-5(close) was lower than bar(close) for sixteen consecutive bars, ignoring bar(close) values in between. To specify consecutive up bar patterns, bar by bar, will always require intPeriod = 1.

RE: Custome Trade Columns
I have not had time to review your custom Performance Visualizer link, but passing value sets as entry & exit signal names will work fine for my purposes right now. Thanks.

RE: Multi-Position Code Sample
Thanks -- that will work.

Final question for the night. Will CumUp/CumDown also work with Volume? If so, how? I can't get CumUp.Series(Volume, 1) to work.

Thanks again ...
profile picture

Eugene

#39
QUOTE:
I can't get CumUp.Series(Volume, 1) to work.

CumUp should work with any series passed as the parameter, including Volume. Do you have a specific example where it's not working for you?
QUOTE:
Just to make sure -- a CumUp(Close, 5) = 16 would tell me that on this bar, bar-5(close) was lower than bar(close) for sixteen consecutive bars, ignoring bar(close) values in between. To specify consecutive up bar patterns, bar by bar, will always require intPeriod = 1.

That's right.
profile picture

Bandit292

#40
Sorry for the delay -- I got caught up with a different project.

I got CumUp/CumDown to work fine with volume. Fat finger fault at my end on the first attempt.

Back with more questions soon ...