In portfolio simulations that’s easy: two separate rules one for buy one for sell, but you don’t really need SetVar for this.
You buy rule should be something like
Close(0,#Bench) >SMA(200,0,#Bench) *1.05
Your sell rule shuold be
Close(0,#Bench) < SMA(200,0,#Bench) *0.95
Not possible in the screener since you can’t separate buy/sell. In the screener a buy is everything that passes the screen, a sell if everything that was held before the rebalance that does not pass the screen.
You bring up an interesting case Steve. I too would like to know the answer to this question. If the variable is maintained that is great. If it isn’t, it serves to highlight the need for a BarsSince function.
Marco - the proposed solution works in the simple case. But if one wants to have another condition for entering/exiting the market on a shorter (or longer) term basis then the idea falls apart.
Perhaps the answer is to have a function called PrevSetVar(). This would allow the following states for the variable:
If SMA( …, 200) > 1.05 then set @variable = 1
If (SMA( …,200) < 0.95 then set @variable = 0
If neither of the above conditions are met then set @variable to Previous @variable (from last rebalance period).
I assume the logic could be handled via the IF statements already present with P123. So you would only need to have access to the value of the variable from the previous rebalance.
the SetVar is meant to set a variable for each stock, so what you are proposing is a bit of a hack.
Maybe SetGlobalVar is more like it… but the rule is still run for every stock, so it’s still a bit of a hack…
What you are asking is an independent rule run only once, before the buy/sells are executed. It belongs in a separate area than the rules… In other words, quite a bit of work…
The solution proposed by Steve using a global variable is one way to handle the problem. A conceptually different way that might also work would be using a BarsSince function.
If I was using a charting program with a BarsSince function, the generic way I would handle this problem is as follows:
A = Close(0,#Bench) >SMA(200,0,#Bench) *1.05
B = Close(0,#Bench) < SMA(200,0,#Bench) *0.95
Since this is the route most charting applications I am familiar with provide I’m guessing it may be the easier one to implement. I present it as another option to consider in case that is so.
Steve, I’m still wondering why my proposed solution would not work. It’s much easier to think of enhancements when exact examples of strategies people are trying to do. It can guide us to the right answer as to what solution is the best, most generic and most useful. Once a few examples are examined the answer becomes more obvious.
Everybody has very specific requirements, but once all are looked together the generalities and the true ‘function’ comes to the surface. For example I still think what everybody is talking about here is a separate market timing module. However since that is quite a project to design and implement, a simple solution might do for now. But we want to stay away from hacks…
Marco - I agree with everything you are saying. We are just on the wrong side of the page of what constitutes a hack.
You own the website and are a lot more aware of how complex various solutions are. My gut feel is that what you are proposing is a hack that will work in the simple case but not in general.
From how I understand the problem, which I’m not necessarily sure is the same as how Steve meant it, the proposed NoPos solution wouldn’t work.
Take for example the case where Close(0,#Bench) >SMA(200,0,#Bench)*1.05 occurred recently but is currently only Close(0,#Bench) = SMA(200,0,#Bench) *1.0. Is the stock bought or not? Using the NoPos solution it is not bought. However, some systems would still consider this in buy mode would buy the stock. I’m not sure how one would code it without going into contortions using multiple offsets and only arriving at an imprecise approximation.
I have no idea how difficult the technical aspects behind implementing the GlobalVar solution are, but from what I can tell the BarsSince solution seems very close to the already implemented HighestBar and LowestBar functions.
HighestBar(#High,10,0) is basically BarsSince(High=Highest(#High,10,0))
With the implementation of the HighestBar function I presume the code necessary for counting the bars is already coded. The modification that would make it more powerful is if the built-in statically defined true/false condition of “High=Highest(x,y,z)” could be turned into a user definable true/false condition like in the Eval function.
Anyway I’m just exploring ideas. Thank you for all the other improvements you’ve made to the site!