I want to code a simple state machine in a called function, and use that state machine in a signal. The state machine accepts a "context" input that tells what part of the state machine should be updated. My problem: since the function is called under various conditions, it sometimes gets called twice in the same bar, with different contexts. I don't know whether it is the "twice" or the "different contexts" that is causing my problem, but:
A variable that is set in the first call on a bar in context1 never shows that new value when called in context2, whether or not in the same bar.
***************
things I have tried
***************
I thought IntraBarPersist might help on the called function, so put that modifier on the function's variables. Does not help.
Sometimes (I don't quite understand this) when a function is called with different parameters, you actually get different instances of the same function and its variables, so I made the "context" parameter a variable in the calling signal, instead of a literal, since I want to have only one instance of the function and its variables. Does not help.
******************
simple demonstration
******************
I've coded a simplest-case signal and function (see attached). Note that after each "Resetting"/"Reset" pair, I want to get a "New Start" output, but that never occurs except on bar1 (where I didn't have to do a reset). In other words, I want the "Latest Start" numbers to increase by 10's as the signal progresses through the bars, but "Latest Start" always stays at 1.
Should be able to run this on any kind of chart. No signals are actually generated (no buy or sell statements) but the output in the PLEditor "output" tab shows what I'm talking about.
All suggestions gladly considered. Thanks.
New question on persistence of variables
-
- Posts: 43
- Joined: 01 Dec 2008
- Has thanked: 2 times
- Been thanked: 2 times
New question on persistence of variables
- Attachments
-
- RD_StateTest_outputResult.txt
- the output results
- (1.35 KiB) Downloaded 407 times
-
- RD_StateTestFunc.txt
- the state-machine function
- (484 Bytes) Downloaded 414 times
-
- RD_StateTestSignal.txt
- the calling signal
- (476 Bytes) Downloaded 418 times
Last edited by RWDickinson on 10 Dec 2008, edited 1 time in total.
OK, I didn't have time to thorougly study your problem, but try the following:
Place your function call inside an if state as follows:
IF BarStatu(1)=2 THEN Function Call;
This will call the function only on the last tick of the bar.
Next any variables which have been assigned values based on the function call will need to be defined with intrabarpersist.
I solved a problem somewhat similar to yours using the above.
Ron
Place your function call inside an if state as follows:
IF BarStatu(1)=2 THEN Function Call;
This will call the function only on the last tick of the bar.
Next any variables which have been assigned values based on the function call will need to be defined with intrabarpersist.
I solved a problem somewhat similar to yours using the above.
Ron
-
- Posts: 43
- Joined: 01 Dec 2008
- Has thanked: 2 times
- Been thanked: 2 times
Thanks. In this very simple demo, I don't store the result from the function call anywhere, so there are no variables in the caller dependent on the value returned from the function (at least I think that's what you meant). All of the code is now guarded by "if barstatus=2" so state machine function and counter update is only happening once per bar (I think this was true anyway) but this did not change my results at all.
When I say called multiple times in a bar I mean that in a single pass of my calling code (when, say, barstatus=2) I check multiple conditions and may call the function multiple times before reaching the end of the code. The variables in the called function do not have the same value on the second and subsequent calls.
But I'm now more inclined to think it has to do not with the fact of multiple calls but that somehow I'm getting multiple instance of the variables - in the same way the XAverage(high,10) gives me a different instance of the variables than XAverage(high,20): Each of them internally uses XAverage[1] but they're different series.
Basically I just don't understand what's happening here. Very frustrating. Oh, help.
When I say called multiple times in a bar I mean that in a single pass of my calling code (when, say, barstatus=2) I check multiple conditions and may call the function multiple times before reaching the end of the code. The variables in the called function do not have the same value on the second and subsequent calls.
But I'm now more inclined to think it has to do not with the fact of multiple calls but that somehow I'm getting multiple instance of the variables - in the same way the XAverage(high,10) gives me a different instance of the variables than XAverage(high,20): Each of them internally uses XAverage[1] but they're different series.
Basically I just don't understand what's happening here. Very frustrating. Oh, help.
Last edited by RWDickinson on 10 Dec 2008, edited 1 time in total.
-
- Posts: 43
- Joined: 01 Dec 2008
- Has thanked: 2 times
- Been thanked: 2 times
Drwar, are you saying that barstatus does not work in top-level code and has to be coded in the called function? Or are you just pointing out the typo 'barstatu' in rsi77's code? The latter is fine, I ignored the typo and assumed he meant 'barstatus'. The former would just astound me and cause me to abandon EL forever. Or maybe I'm missing your point altogether?
In any case, I can't code the 'barstatus' (if it's needed in the first place) in the called function: the logic just won't flow from there. What would I do with calls that came in on a non-last-tick? Just abandon them?
Still very confused.
In any case, I can't code the 'barstatus' (if it's needed in the first place) in the called function: the logic just won't flow from there. What would I do with calls that came in on a non-last-tick? Just abandon them?
Still very confused.
-
- Posts: 43
- Joined: 01 Dec 2008
- Has thanked: 2 times
- Been thanked: 2 times
RW
I you are running update every tick and you are trying to use the Barstatus command to exclude a function from executing on every tick. It will not work unless the barstatus command is in the function being called. If you can code the exclude outside the function, It can be coded inside the function. What difference does it matter if it is wrapped externally or internally by the logic.
J~
I you are running update every tick and you are trying to use the Barstatus command to exclude a function from executing on every tick. It will not work unless the barstatus command is in the function being called. If you can code the exclude outside the function, It can be coded inside the function. What difference does it matter if it is wrapped externally or internally by the logic.
J~
-
- Posts: 43
- Joined: 01 Dec 2008
- Has thanked: 2 times
- Been thanked: 2 times
drwar: First, you would have to give me some reason other than you word for it that the barstatus function can be called from some contexts and not others. That would make PL such a strange language that I would totally give up on ever using it. The documentation makes no such claim that I can find.
Second, it makes a difference because the called function doesn't have all the context that the outer code has, and because the outer code can't know (after the fact) whether the call had the intended effect:
----------------------------------------------
{outer}
variable x(0);
if x=... and barstatus=2 then begin
funccall(dosomething);
x += 1;
end;
{function}
inputs: command("dosomething");
if command="dosomething" then begin
<code goes here>
end;
----------------------------------------------
if you move the barstatus check to the called function, how would the outer code know whether the dosomething had been done? If it hasn't, then he shouldn't update his x variable.
And what shoud the function do with the call if barstatus <> 2? ignore it? and how would it let the outer code know that nothing had been accomplished? I don't understand how you can possibly be confused about this. Your belief that the check can be moved with no ramifications could only be true in a pure language with no side effects at all..... and there are no such languages. Certainly PL is not one.
Second, it makes a difference because the called function doesn't have all the context that the outer code has, and because the outer code can't know (after the fact) whether the call had the intended effect:
----------------------------------------------
{outer}
variable x(0);
if x=... and barstatus=2 then begin
funccall(dosomething);
x += 1;
end;
{function}
inputs: command("dosomething");
if command="dosomething" then begin
<code goes here>
end;
----------------------------------------------
if you move the barstatus check to the called function, how would the outer code know whether the dosomething had been done? If it hasn't, then he shouldn't update his x variable.
And what shoud the function do with the call if barstatus <> 2? ignore it? and how would it let the outer code know that nothing had been accomplished? I don't understand how you can possibly be confused about this. Your belief that the check can be moved with no ramifications could only be true in a pure language with no side effects at all..... and there are no such languages. Certainly PL is not one.
- Marina Pashkova
- Posts: 2758
- Joined: 27 Jul 2007
Hi everybody,
If somebody needs an answer to the above (we have helped Rob to code what he's talking about in the posts above):
Here's the code for the function:
And here's the one for the indicator:
Regards.
If somebody needs an answer to the above (we have helped Rob to code what he's talking about in the posts above):
Here's the code for the function:
Code: Select all
Inputs:
Context (StringSimple),
TrueStateBar(NumericSimple);
Variables:
StateBar (0);
StateBar = TrueStateBar ;
If Context = "Reset" then begin
print(Date," ",Time_s," ",currentBar," Reset ");
StateBar = 0;
end
else begin
if StateBar=0 then begin
print(Date," ",Time_s," ",currentBar," New Start ");
StateBar = CurrentBar;
end;
end;
RD_StateTestFunc_ = StateBar;
Code: Select all
Variables:
Count (0),
StateTestContext (""),
intrabarpersist _State(0);
if Count >= 10 then begin
print(Date," ",Time_s," ",currentBar," Resetting ");
StateTestContext = "Reset";
_State = RD_StateTestFunc_(StateTestContext, _State);
Count = 0;
end;
StateTestContext = "";
_State = RD_StateTestFunc_(StateTestContext, _State);
print(Date," ",Time_s," ",currentBar," Latest Start ", _State);
Count += 1;