Discussions
»
Product and Service Development
»
Formula Assistance
»
ValueWhen() opposite function, such as ValueUntil()?
Rank: Newbie
Groups: Registered, Registered Users, Unverified Users Joined: 4/15/2014(UTC) Posts: 6
|
Hi Guys,
I have a formula which makes use of the ValueWhen() function to start a series of values when a condition is met.
Is there a way of ending the series when another condition is met?
For example I have a trailing stop which follows under rising prices, and as soon as it is greater than a bar/candle Low I would like the series to end, as I will have exited the trade.
Currently the plotted line of the series continues all the way across the chart ad infinitum. But I would like it to stop dead when it hits a bar/candle. Otherwise if I enter a trade on the same stock a number of times, I keep getting old remnant dead series plotting across the chart messing it up.
I have been able to send the series to value zero (0) so it at least plots the rest of the series along the bottom of the chart, but its still messy, and means my chart's vertical axis has to range from 0 to the current trading price, which can make my bars/candles unusably stunted.
Ideally I would love a ValueUntil() function which would work in an equivalent but opposite way to ValueWhen(), to turn off the series of values once a condition is met.
I don't think I can use Ref() as I don't want to turn it off for the last x periods, I want it turned off permanently from a certain point onwards forever.
Any other ways I can turn off a series of values?
Thanks for any help you can offer.
Regards
Drew
|
|
|
|
Rank: Advanced Member
Groups: Registered, Registered Users, Subscribers Joined: 7/25/2005(UTC) Posts: 1,042
Was thanked: 57 time(s) in 54 post(s)
|
Hi Drew
What you're asking for is very likely possible but I'd need more information before providing specific code.What I can do is to outline the concept that I have in mind.
ValueWhen() has three parameters, Nth, Expression and Data Array. Assuming that the Nth parameter is 1, then ANDing the trade status with the Expression parameter you should be able to effectively turn the VaulueWhen() function on or off.
What you might need to do is is generate a "trade latch" that goes TRUE with a Buy signal and FALSE with a Sell signal (Sell equating to CLOSE below the trailing stop). The state of that latch can be included in the ValueWhen() Expression so that when the latch is FALSE its result will be held constant until the next trade is opened.
I'm sure there will be problems to resolve before this scenario will work for you. However I'm confident that the concept is valid. It may be that the trailing stop has to be generated once so that the Sell signal is created, with the next step being the trade latch, and then the latch condition being used to modify the trailing stop to generate an output.
For the latch this is what I'd suggest.
Buy:= {your buy signal}
Buy:= Buy*Alert(Buy=0,2); {This line reduces the Buy signal to just one bar}
Sell:= CLOSE< {trailing stop} ;
Sell:= Sell*Alert(Sell=0,2); {This line reduces the Sell signal to just one bar}
Init:= Cum(IsDefined(Buy OR Sell))=1;
Trade:=BarsSince(Init OR Buy)<BarsSince(Init OR Sell);
Obviously you'll need to insert actual code for Buy and make any changes as appropriate. The reason for creating the "Init" variable is to eliminate a number of N/A bars in the Trade result which could (and usually does) miss capturing the first trade on the chart.
If you need further help then I would want to see your code. You can email me at rlarsen@quik.co.nz
Roy
|
|
|
|
Rank: Newbie
Groups: Registered, Registered Users, Unverified Users Joined: 4/15/2014(UTC) Posts: 6
|
Hi Roy,
Thanks so much for quick and detailed reply. It will take me a few days to process that and try a few things. But I will get back to you once I have tested your theory, and a couple of others I have had in the past 24hrs. I was thinking that if I could multiply the "post-stop" series values (ie the values of the series that I don't want plotted) by an "undefined" value, that maybe the post-stop series values would become undefined themselves, and hence not be plotted. Just a theory - I have no idea whether it even makes sense (except to me).
Thanks again for the great lead - looks hopeful - I appreciate it
Kind Regards
Drew
|
|
|
|
Rank: Advanced Member
Groups: Registered, Registered Users, Subscribers Joined: 7/25/2005(UTC) Posts: 1,042
Was thanked: 57 time(s) in 54 post(s)
|
Hi Drew
I don't know of any way to force a valid plot to an N/A state to break the plot into two or more sections. It's easy enough to generate N/A bars at the beginning and/or end of a plot, but breaking a plot into two or more sections still eludes me.
Creating an N/A result at the right side of the chart can be achieved simply by shifting the plot right then shifting it left by the same amount using the Ref() function. The idea behind my earlier suggestion is that unwanted sections of the plot would hold a constant value near the price bars rather than plotting zero.
Come to think of it, there is a way to disassociate a plot from left and right scales. This approach can tie a signal (such as a trailing stop) to the price plot, while still allowing its zero values to drop out of sight and not affect the positioning of price bars. This is done by adding an N/A result as a second output to the primary result that you do want.
The N/A result can be generated by using ValueWhen(1,0,0); as the last line of code. Try adding this to the end of any indicator that switches between price and zero and see what effect it has. Usually the style of the original indicator should be set as a dotted line so that the switches between zero and active value do not create near vertical lines.
Roy
|
|
|
|
Rank: Newbie
Groups: Registered, Registered Users, Unverified Users Joined: 4/15/2014(UTC) Posts: 6
|
Hi Roy,
Well thanks to your help I've been able to achieve my initial goal (and a little extra). The following code plots an EMA90 whenever its less then an EMA30. It successfully turns the plot on and off again (which is more than what I was originally after).
ema30 := Mov(C, 30, E);
ema90 := Mov(C, 90, E);
undefined := ValueWhen(1, 0, 0);
plottedEma90 := ema90 * if(ema90 < ema30, 1, undefined);
plottedEma90;
However its not perfect - I am still experiencing the issue where if I zoom into an area of the chart where the EMA90 has been switched off, the scale will range from the highest High of the visible bars down to zero (0) - I'm guessing because the plottedEma90 becomes N/A, and that is probably defaulted to 0 by the chart rendering rules.
When I scroll into the middle of a long uptrend and I have plenty of visible EMA90 on either side of the visible bars, then the display behaves itself and the vertical (price) scale will range from the highest High to the lowest Low of the visible bars.
Roy, you seemed to think you could disassociate the plot from the vertical scale. I don't what you mean by "This is done by adding an N/A result as a second output to the primary result that you want." How do you add a value as a second output to the primary?
Do you still think that's possible even when the plot values are undefined?
Anyway - getting closer - unfortunately it won't be much use if I can't get the vertical scales working correctly.
Have a play and see what you think - many thanks again Roy
Kind Regards
Drew
|
|
|
|
Rank: Advanced Member
Groups: Registered, Registered Users, Subscribers Joined: 7/25/2005(UTC) Posts: 1,042
Was thanked: 57 time(s) in 54 post(s)
|
Hi Drew
If you introduce an N/A variable into another variable, that variable will itself become an N/A variable. What follows is not exactly what you're looking for but it might give you some clues as to how to achieve your goal. I've created 2 indicators around the same theme, one that effectively (though not in reality) appears to create an N/A result at intervals built on the relationship between a 30 period EMA and a 90 period EMA.
{Test Indicator}
ema30 := Mov(C, 30, E);
ema90 := Mov(C, 90, E);
plot:=ValueWhen(1,ema30>ema90,ema30);
If(ema30>ema90,Plot,0);
ValueWhen(1,0,0);
The first "Test Indicator" is set to a heavy dotted line to demonstrate "simulated N/As" along the ema30 path. The zero plot sections are allowed to float out of sight below the bottom of the chart. If the zero values still plotted visibly along the bottom of the chart then zero could be changed to some negative number.
The ValueWhen() function causing the plot to float should be placed last on the chart. It's sole function is to allow any plot generated earlier in the indicator to float unwanted results out of sight (below or above the visible chart and and other indicators) . The"Test Indicator" should be linked to the scale that the chart uses. What the ValueWhen() function does is that it allows extremities to move above and/or below visible chart extremities.
The second indicator is a simple system that generates a buy when the first indicator is visible, and a Sell when it falls out of sight. The equity curve in the top segment of the chart shown at http://www.metastocktips.co.nz./agilent.png is created by a Trade Equity indicator (not relevant to your problem but possibly still of interest).
{Test Indicator 2}
ema30 := Mov(C, 30, E);
ema90 := Mov(C, 90, E);
plot:=ValueWhen(1,ema30>ema90,ema30);
Buy:=ema30>ema90;
Buy:=Buy*Alert(Buy=0,2);
Sell:=ema30<ema90;
Sell:=Sell*Alert(Sell=0,2);
Signal:=Buy-Sell;
Plot;
Hope this gets you pointed in the right direction.
Roy
|
|
|
|
Users browsing this topic |
Guest (Hidden)
|
Discussions
»
Product and Service Development
»
Formula Assistance
»
ValueWhen() opposite function, such as ValueUntil()?
Forum Jump
You cannot post new topics in this forum.
You cannot reply to topics in this forum.
You cannot delete your posts in this forum.
You cannot edit your posts in this forum.
You cannot create polls in this forum.
You cannot vote in polls in this forum.